Security Overview

Last updated: October 22, 2026

This page describes how Adminlog, a Shopify embedded audit trail app developed by Bedrock Digital Apps, is hosted and secured today. It is written for security teams evaluating Adminlog. Where something is not in place yet, we say so.

Infrastructure & Data Residency

HostingA cloud server (virtual machine) at Hetzner Online in Ashburn, Virginia, USA. We run and maintain the server ourselves. Delete protection is turned on for the production server.
DatabasePostgreSQL, which we run in Docker on the same server. Adminlog has its own database; the database server also holds databases for other Bedrock Digital apps. The app connects to it over the server's internal Docker network, and the database is not exposed to the internet.
DevelopmentA separate development copy of the app, with its own database, runs on the same server. It is installed only on our own test stores.
Backup storageCloudflare R2 object storage, separate from the server.
Web trafficAll traffic goes through a Caddy reverse proxy on the server, which provides HTTPS with automatically renewed Let's Encrypt certificates.
Sub-processorsThe companies that process data for us are listed in our Privacy Policy.

Encryption

In transitHTTPS (TLS 1.2 or later) for all web and API traffic; plain HTTP is redirected to HTTPS. Email is sent over TLS. Inside the server, traffic between the app and the database stays on the internal Docker network and is not encrypted.
At restBackups are stored in Cloudflare R2, which encrypts stored data. We don't add our own encryption to the backup files, and we don't claim full-disk encryption on the server. Data in the database, including the Shopify access tokens the app uses, is not encrypted field by field.
API keysEnterprise API keys are shown once when created and stored only as SHA-256 hashes.
Webhook signaturesEvents we forward to your own HTTPS endpoint are signed with HMAC-SHA256, using a secret generated for each endpoint.

Audit Trail Integrity (Enterprise)

What is sealedChanges to orders, customers, inventory, fulfillments, collections, draft orders, locations and returns are written to a unified audit log. On Enterprise, each of those records is sealed after about 90 minutes and carries a SHA-256 hash chained to the previous record: who made a change is often confirmed by Shopify only minutes after it is recorded, so Adminlog waits for that before sealing. Product changes have their own chain, sealed the same way once a product record is 90 minutes old.
What is not sealed yetThe most recent records aren't sealed yet: audit-log and product records under about 90 minutes old wait for the next sealing run, and the chain check lists how many. Older records that were never sealed (for example, from before the store was on Enterprise) are not part of the chain. Refund, discount and theme changes are recorded with a per-record checksum but are not part of any chain.
Per-record checksumsRecords written since checksum version 2 (the checksum starts with "v2:") have a checksum that covers the before and after values of the change. Older records keep their original checksum, which covers the shop, record, event, time and actor but not the before and after values. Checksums are unkeyed SHA-256, not signatures: they show a change made by someone who did not also recompute them.
How it's protectedThe app refuses to edit or delete a sealed record. This protection lives in the application; it is not write-once storage, and the chain hash is not keyed, so someone with direct database access could rebuild it. It makes changes detectable (tamper-evident); it does not make records impossible to change.
VerificationYou can re-check the chain at any time from the Compliance page; it recomputes the links and reports where any break is. Evidence packs include a check of the whole chain (or say plainly that it couldn't run) and a SHA-256 hash of every file (a checksum, not a digital signature).
RetentionSealed records are still removed when they pass your retention period, and GDPR erasure anonymises sealed records in place without breaking the chain.

Authentication & Access Control

User authenticationUsers sign in through Shopify. Adminlog has no separate login and stores no passwords. Your Shopify staff settings (including two-step authentication and, on Shopify Plus, SSO) decide who can open the app.
Session managementSessions are stored server-side in PostgreSQL. Shopify issues the access tokens the app uses for background work (such as processing webhooks).
Tenant isolationEvery database query is scoped by the merchant's shop domain (shopId), taken from the Shopify session or the API key, never from the request. This is enforced in the application layer.
Roles inside AdminlogNot available yet. Anyone you allow to open Adminlog in Shopify can see all of your store's Adminlog data. Roles (Owner, Admin, Auditor, Viewer) are planned.
API authenticationThe Enterprise REST API uses a Bearer API key, rate-limited to 1,000 requests per hour per key. Every call re-checks that the store's plan still includes API access.
Our own accessOne developer operates the service. Server access is over SSH with keys only. Changes to Adminlog's own settings (tracking, retention, filters, API keys, integrations) are recorded in your audit log with the staff member's name; exports and alert actions are not recorded yet.

Data Handling & PII

PII storedCustomer names, email addresses and phone numbers appear in audit records when customer and order events are tracked. Staff names appear when Shopify tells us who made a change.
Purpose limitationWe use this data only to provide the audit trail and the features you turn on. We do not use it for marketing, advertising or profiling.
What we collectWhat Shopify sends us in webhooks, plus what we read from Shopify's API to import recent history, identify who made a change, and take snapshots of markets, metaobjects and themes.
RetentionBy plan: Starter 30 days, Professional 90 days, Enterprise 365 days by default (configurable up to 5 years). A daily cleanup enforces this. If your plan's period gets shorter, the old period is kept for 30 more days first.
Deletion on uninstallSessions are deleted at once. About 48 hours after an uninstall, Shopify asks us to erase the store's data and we delete it. A daily cleanup also deletes it 7 days after the uninstall if that request hasn't arrived.
BackupsDaily backups are kept for 14 days. The backup from the 1st of each month is kept for 12 months. Occasional one-off backups taken before database changes are kept until we delete them. Deleted or erased data stays in these backups until they expire.
GDPR requestsWe process Shopify's customers/redact and shop/redact requests automatically when they arrive. Customer data requests are logged; Enterprise stores can export that customer's records from the GDPR page, and any store can ask us at support@bedrk.dev.
Data portabilityProfessional and Enterprise plans can export reports as CSV or PDF (up to 10,000 rows per report; a cut-short file says so). Enterprise adds a JSON export, evidence packs and the REST API. Starter does not include exports.

Backup & Recovery

Backup frequencyA full database backup every day, copied to Cloudflare R2 over HTTPS.
ChecksEach backup is checked for a valid format and a sudden drop in size, and we get an email if the day's backup didn't reach R2. A monthly test restore currently checks a smaller database's backup; a full test restore of the production database is planned and has not been done yet.
Recovery pointUp to about 24 hours of data could be lost if the server failed between backups. Everything runs in one server and one region.

Monitoring & Incident Response

Health monitoringEvery 5 minutes the server checks disk, memory, the database, the containers and the web server, restarts anything that has failed, and emails the developer.
Webhook monitoringA daily check finds stores that have stopped receiving audit events, says why where it can (plan limit, the store's own tracking settings, or no store activity), and alerts the developer, who fixes any webhook problem by hand.
Incident responseAlerts go to the developer by email. Recovery steps (webhooks, data, restoring a backup) are written down in internal runbooks. We don't have a formal written incident response plan yet.

Vulnerability & Change Management

DependenciesDependencies are pinned in a lockfile and installed with npm ci. We update them as part of regular code audits. There is no automated vulnerability scan in our build yet.
OS patchingWe patch the server ourselves: automatic security updates, plus manual updates and reboots.
Code auditsRegular internal code and security reviews (AI-assisted), with tracked fixes. No independent penetration test has been done yet.
Release processChanges go through pull requests with automated lint, type checks, tests and a build (urgent fixes can ship before their pull request is merged, after the same checks). Changes are tried on the development copy first, and each production release needs the owner's explicit approval. Previous versions are kept so a release can be rolled back.
SQL injectionDatabase queries go through the ORM with parameters. Raw SQL uses tagged-template parameters, not string building.
XSSReact escapes output by default, and email templates escape HTML explicitly.
SSRFOutbound webhook and logo URLs must be HTTPS, private and internal IP ranges are blocked, and the checked address is the one we connect to.
Rate limitingPer-store webhook rate limits by plan, with temporary quarantine for floods, and per-key limits on the REST API.

Compliance Status

SOC 2Adminlog is not SOC 2 certified and has not been audited. Adminlog can help you collect evidence for your own SOC 2 audit, such as change history, alerts and exports.
GDPRWe handle Shopify's GDPR webhooks automatically and support access and erasure requests (see above). We don't have a published Data Processing Agreement (DPA) yet.
CCPAWe don't sell personal information or share it for advertising. Deletion and export are available as described above.
PCI DSSNot applicable. Adminlog never receives, stores or transmits payment card data. Payments stay inside Shopify.

Contact

For security questions, vulnerability reports, or to request more documentation:

Bedrock Digital Apps
Email: support@bedrk.dev

Adminlog by Bedrock Digital Apps — Security Overview v2.0