Skip to content
WatchMyCover

You are being asked to put other companies’ insurance documents in here.

So this page states what protects them, and what does not yet. Everything below is true of the system as built. Where something is planned rather than built, it says so.

What we do not claim. WatchMyCover is not SOC 2 certified and not ISO 27001 certified. No third-party penetration test has been carried out. We have run our own reviews, and the findings from them — including the ones that were failures — are summarised below. If your procurement process needs a certification, we do not have one to give you.

What is in place

One tenant cannot reach another
Every request is scoped to the caller’s organisation, re-read from the database each time. Reads carry the organisation id in the query itself, so another customer’s record does not match; writes first confirm the record belongs to the caller’s organisation. Cross-tenant reads, updates, archives, certificate writes, template overwrites, histories and exports each have a test asserting a 404.
Certificate documents are private, and proxied
Uploaded documents are held in a private bucket with no public URLs and no signed links. Every download passes through the API, is authorised against the caller’s organisation at that moment, and is recorded in the audit trail. Files are served as attachments with nosniff, never rendered on our domain, and their type is decided from their first bytes: PDF, PNG or JPEG only.
Confirmed addresses and two-factor sign-in
A new account confirms its email address by a link before it can use anything in the app, so nobody can send email to other people in a company name they do not control. Anyone can turn on two-factor sign-in with an authenticator app, with ten single-use backup codes; five wrong codes lock the account for fifteen minutes. Our own operations console refuses anyone who has not turned it on.
Sessions and authorisation
Session cookies are httpOnly, secure and SameSite=lax, because the app and the API share a site. Authorisation is re-read from the database on every request rather than trusted from the session, so removing someone’s access takes effect immediately. A password reset link works once, expires after an hour and signs out every other session.
An audit trail you can read
Every change writes an audit record: vendors, certificates, templates, projects, the team, share links, chasing, sign-ins, password changes and resets, two-factor changes, document downloads and register exports. Each vendor’s page shows its own history and every verdict it has had, and owners and admins can read the whole organisation’s trail in the app.
Links that are credentials
Upload links, report links and invitations are 32 random bytes; only a hash is stored. An upload link is created as each email is sent, so it is never stored in readable form, and archiving the vendor revokes every one. Report links expire within 90 days and can be withdrawn; they stop, with upload links, if the account is cancelled.
Rate limits
Sign-in, registration and password reset are capped at 8 requests a minute, authenticated reads at 120, writes at 40, the heavy operations (CSV export, import, full re-check) at 10, and the contact form at 5 an hour. Counters are held in Postgres, so the limit holds however many instances are running. The payment provider’s webhook is authenticated by its signature instead, and health checks are not limited.
Input is validated and stripped
Every request body is parsed by a schema that discards unknown keys. The platform-admin flag cannot be set through any endpoint; a member’s role can be changed only by the owner, and an invitation’s role only by an owner or admin. Request bodies are capped at 256 KB, CSV imports at 4 MB and uploaded files at 10 MB, with a per-account storage ceiling above that.
The browser
Pages that handle a session or a token (the app, sign-in, invitations, password reset, upload and report pages) run only scripts carrying a nonce generated for that request. The marketing pages allow inline scripts, which their framework needs when built ahead of time; they hold no session and render nothing a visitor typed. Framing is denied, and sign-in redirects accept only paths on our own site.
Exports cannot execute
Any CSV cell beginning with an equals sign, plus, minus, at sign, tab or carriage return is escaped, so an exported register cannot run a formula when someone opens it in a spreadsheet. Covered by a test.
Errors, logs and analytics do not leak
One handler owns every error response; anything unexpected becomes a generic 500 carrying only a request id. Logs redact credentials, cookies, secrets and the tokens in upload, report, invitation, reset and confirmation links. Error reports and product analytics go to PostHog with route patterns, identifiers, counts and statuses only: never a name, an address, a certificate value or a document.
Dependencies
Dependencies are audited before each release. On 23 September 2026, npm audit reported zero vulnerabilities across the API, the web app and the worker.

What is not in place

A security page listing no gaps is a security page nobody checked. These are ours.

Two-factor sign-in is optional
Customers choose whether to turn it on, and an owner cannot yet require it of their team.
Roles are broad
Any member can import vendors, archive them, create requirement templates and export the whole register. Only owners and admins edit or delete templates, manage the team and share links, and change settings. Finer-grained roles are planned.
Two kinds of event are not in the audit trail yet
Subscription changes arriving from the payment provider are applied but not recorded as audit rows (payment successes and failures are), and a single upload link cannot be withdrawn on its own: archiving the vendor withdraws them all.
Inline styles are allowed
The style policy allows inline styles, which the interface components set. A style cannot run code.

Reporting something

If you find a vulnerability, write to info@watchmycover.com with enough detail to reproduce it. We will confirm receipt, and we will not take action against anyone who reports a genuine issue in good faith and does not access other customers’ data while doing so. We have no bug bounty programme and are not going to pretend otherwise.

What we hold and why is set out in the privacy policy.