Skip to content

Security

How your data is handled

Specific claims about how the system is built, not a list of logos. Everything here describes code that exists.

Your data is in its own database

Each organisation gets a separate Postgres database rather than a shared table with an organisation column. The application resolves which database to open per request, and it verifies where it landed: after connecting, it checks that the database’s own metadata names the organisation it was asked for, and refuses the connection if it does not.

That check exists because the failure it prevents is silent. A routing bug in a shared-table system serves one customer’s records to another and nothing anywhere complains. Here, the connection is refused.

The isolation is tested by trying to break it: the test suite takes one tenant’s real database credential and attempts to open another tenant’s database with it, and fails the build if that ever succeeds.

Credentials are encrypted, not merely stored

Tenant database credentials are held under envelope encryption: a per-record data key, encrypted by a master key held in a key management service, with the wrapped key and the ciphertext stored together. The master key never appears in the application’s configuration or in a log.

Connection strings are redacted from every error the database layer raises, including inside stack traces: Postgres drivers put the full DSN into connection errors as a matter of course, which is how a credential ends up in an error report.

Passwords and codes are stored as hashes

Passwords use Argon2id at OWASP-recommended parameters. Verification codes, password reset tokens and recovery codes are stored only as hashes, so a read of our own database cannot be replayed as a login.

Password policy follows NIST SP 800-63B: a length minimum, a check against your business’s own name, and a breach lookup against a public corpus using k-anonymity, so your password is never sent anywhere to check it. There are no forced composition rules, because they push people toward predictable passwords.

Our staff cannot look without asking

Access to your workspace is requested with a written reason, granted by somebody in your organisation, limited to at most four hours, and revocable by you instantly. It appears in your own audit trail, and an action taken under a grant is recorded as ours rather than as yours.

There is no standing consent and no permanent impersonation. A support engineer with a valid login and no grant cannot open your data: the check runs at the point of use rather than on a schedule, so revoking access takes effect on the next request.

Platform staff sign in to a separate admin area, and every staff account is created with a second factor from an authenticator app enrolled.

Backups are taken per organisation, and restores are rehearsed

A logical backup of your database is taken nightly, checksummed, and recorded individually with its own retention. Cluster-level point-in-time recovery restores everything at once and cannot answer "put this one organisation back to Tuesday", which is why per-organisation backups exist as well.

Restores are verified daily rather than rehearsed annually: a scheduled job restores recent archives into a scratch database and asserts that the checksum matches, the restore completes, the tables exist and the metadata names the expected organisation.

A real recovery renames the live database rather than dropping it, so a restore of the wrong archive is recoverable.

Your data leaves whenever you want it

Export is free, complete and available whenever you ask, including after you cancel, for the length of the retention window. It is not a retention lever and it is not a paid tier.

The application surface

Every response carries a Content-Security-Policy with a per-request nonce, along with nosniff, a strict referrer policy, frame-ancestors none and a permissions policy. Sign-in, verification, password reset, payments and the API are rate limited per address and per account, on a sliding window.

Requests for a resource in an organisation you are not a member of return "not found" rather than "forbidden", because a 403 confirms that the resource exists.

Reporting a vulnerability

Email admin@primemgr.com with “Security” in the subject, what you found, and how to reproduce it. We reply within two working days and keep you told what we are doing about it.

Please test only against an account of your own, do not read, change or keep anybody else’s data, and do not run anything that degrades the service for others (no denial-of-service, spam or social engineering of our staff or customers). Give us a reasonable time to fix a problem before you talk about it publicly. If you act in good faith within these lines, we will not pursue or support legal action against you.

Machine-readable contact details are at /.well-known/security.txt.

Found something that looks wrong, but not a vulnerability? Tell us at our contact page. We would rather hear it from you than from somebody else.

Last updated .