Amp-Hour

Security

Effective 2026-10-07 · Version 2026-10-07.2

A plating shop's database holds its customers, its prices, its employees' hours and the records an auditor or an inspector will ask for. This page describes, specifically, how the hosted Amp-Hour service protects it. Everything here describes the software as deployed; when the software changes, this page changes.

  1. Architecture
  2. Encryption in transit
  3. Encryption at rest
  4. Authentication
  5. Sessions
  6. Rate limiting and lockout
  7. Access control
  8. Audit and security event logs
  9. Backups
  10. Vulnerability disclosure
  11. Incident response
  12. Security reviews
  13. Subprocessors
  14. What we do not do

1. Architecture

Amp-Hour is one server process written for Node.js with no third-party packages: the HTTP server, the database driver and the cryptography are the ones built into Node. There is no framework, no package registry dependency and no build step, so there is no supply chain of other people's code to audit or to be surprised by.

Each shop has its own SQLite database file. Accounts, shop memberships, sessions and subscriptions live in a separate platform database that holds no shop records. When you are signed in to a shop, every query the server runs for you is run against that shop's file and no other: there are no shared tables of shop data, so a bug in a query or a mistake in a filter cannot return another shop's jobs, customers or prices. A shop's file is also what its backup and its downloadable export are made from, which is why a shop can take its whole database with it.

The service runs on DigitalOcean in the United States behind the Caddy web server, which terminates TLS and forwards requests to the application. The application container runs read-only, with no extra privileges and every Linux capability dropped except the three its start-up script needs to hand the data directory to the unprivileged application user; the only writable path is the data volume.

2. Encryption in transit

All connections use HTTPS with TLS 1.2 or 1.3; plain HTTP requests are redirected. Certificates are issued and renewed automatically by Let's Encrypt. The server sends HTTP Strict Transport Security (one year, including subdomains), so a browser that has visited once refuses to connect insecurely afterwards. Response headers also set a Content Security Policy that allows scripts only from amphour.io, forbid framing by other sites, disable content-type sniffing, limit the Referer header to our own origin, and isolate the browsing context from other origins.

Email we send travels to the mail provider over TLS. Backup copies sent off-site are uploaded over HTTPS with signed requests.

3. Encryption at rest

The databases and backups live on a DigitalOcean block storage Volume, which DigitalOcean encrypts at rest, when the service is deployed as our deployment guide prescribes. Off-site backup copies are stored in DigitalOcean Spaces object storage in a different region from the server; Spaces encrypts stored objects at rest.

Passwords are never stored; see section 4. Card numbers never reach our servers; see section 13.

4. Authentication

5. Sessions

Signing in sets one cookie, sid, which carries a random 256-bit session identifier. The cookie is HttpOnly (not readable by scripts), Secure (sent only over HTTPS) and SameSite=Lax (not sent on requests other sites make to us). A session ends after 7 days without use and in any case 14 days after sign-in, whichever comes first, and when you sign out.

Settings > Security lists every open session of your account with its browser, address, start and last activity, and lets you end any one of them or all but the current one. When your account signs in from a browser and address it has not used before, we email you with the time, address and browser so you can act if it was not you.

State-changing requests are accepted only from our own pages: they must carry a JSON content type that browsers will not send cross-site, and a request whose Origin header does not match amphour.io is refused.

6. Rate limiting and lockout

7. Access control

Within a shop, each person has one of five roles. Administrators manage the team, billing, settings and data; managers run the shop and see financial reports; office staff handle quotes, orders, shipping and invoicing; QC signs off inspections and certificates; operators record work on the floor. Every API route declares which roles may call it, and the server enforces that on every request regardless of what the page shows: prices, job costing, pay rates, invoices, purchasing and financial reports are withheld from QC and operator logins by the server, not only by the screens. Only administrators can grant the administrator or manager role; managers add and manage office, QC, operator and portal logins. Removing a member under Settings > Team ends their access to that shop at once.

Customer portal logins are a separate kind of user. A portal user is bound to one customer record and every portal query is filtered by that customer, so they see their own quotes, jobs, shipments, certificates and invoices and nothing else. Portal users cannot reach any staff page or route. The shop switches the portal, and each part of it, on or off under Settings > Customer portal, and the server honours those switches.

Messages between staff are stored in the shop's database and are readable only by the people in the conversation; a message can be edited only by its author while they are still in the conversation, and removed by its author or a manager.

Amp-Hour staff can enter a shop for support. Doing so requires two-factor authentication, is written to the platform audit log, and is written to that shop's own security log as a visible "support access" event with the time and the operator's address, so the shop's administrators can always see when we were there and ask us why.

8. Audit and security event logs

Each shop's database carries an audit log of changes to its records: who changed what and when, visible to its administrators. Separately, the platform keeps a security event log. For your own account (Settings > Security) it shows sign-ins with address and browser, failed attempts and lockouts, password and two-factor changes, sessions you ended, exports you downloaded, invitations, promotion codes applied, and deletion requests. For a shop, its administrators and managers see the shop's events: sign-ins of its members, members added, removed or changed, every export and backup download, demo-data clears, policy changes, and every time Amp-Hour staff entered the shop.

LogContentsKept
Shop audit logRecord changes in the shop, by userLife of the shop; it is part of the shop's database
Security event logSign-ins, failures, lockouts, password and two-factor changes, sessions, exports, member changes, support access, deletions400 days
Web server access logTime, address, URL, status, user agent90 days
Platform audit logOperator and billing actionsLife of the platform

We review the security event log on a regular schedule for lockouts against one account from many addresses, exports at unusual hours, and support entries we cannot account for.

9. Backups

Once a day the server takes a consistent snapshot of every shop's database and of the platform database using SQLite's VACUUM INTO, which produces a clean copy without interrupting the application. Each copy is compressed and recorded in a manifest with its size and SHA-256 digest. Daily sets are kept for 30 days on the data volume and then deleted. When an off-site copy is configured, every set is also uploaded to object storage in a different region, so that a failure of the server, or its deletion, does not take the backups with it.

Every quarter we restore a backup into a scratch copy, verify its integrity and compare it with the live shop, and record the result; a backup that has not been restored is not trusted. Shops do not depend on us for this: an administrator can download the shop's complete database as one SQLite file, or any table as CSV, at any time from Settings > Data.

10. Vulnerability disclosure

If you find a security problem in Amp-Hour, we want to hear about it. Email support@amphour.io with what you found, how to reproduce it and, if you have one, a suggested fix. We acknowledge reports within 3 business days, tell you what we found when we have investigated, and tell you when it is fixed. We do not currently pay bounties; we will credit you by name if you want.

We will not take legal action against research done in good faith, which means: test against your own trial shop or an account you own, stop as soon as you have shown the problem exists, do not read, change or delete anyone else's data, do not run denial-of-service or load tests, do not use social engineering against our staff or our customers, and give us a reasonable time to fix the problem before you publish. Machine-readable contact details are at /.well-known/security.txt, and the repository's SECURITY.md says what is in scope.

11. Incident response

An incident is anything that could have exposed a shop's data to someone who should not have it. When we confirm one, we first contain it (ending sessions, rotating credentials, taking the site offline if necessary), then preserve the logs, then work out which shops and which data were involved. We notify the owner of every affected shop within 72 hours of confirming the incident, in plain words: what happened, when, what data of theirs was involved, what we did, and what they should do. We write a post-mortem for every incident and change whatever let it happen.

12. Security reviews

October 2026: an adversarial review of the authentication surface, every API route, the HTTP layer and the browser code, each finding reproduced before it was reported. Findings covered role escalation by managers, a request that could stop the server, address-based rate-limit evasion behind the proxy, financial data reaching floor logins through the API, unbounded uploads and imports, and spreadsheet-formula injection in exports. All were fixed and each is pinned by an automated test that runs with every change. We will note further reviews here.

13. Subprocessors

The companies that process data on our behalf, what each does and where, are listed in the Privacy Policy: DigitalOcean (hosting and storage), Stripe (payments), Microsoft 365 or Resend (transactional email) and GoDaddy (domain and DNS). We notify shop owners 30 days before adding one that would handle shop data.

14. What we do not do

Questions about anything on this page: support@amphour.io.