Security overview
The technical and organisational measures protecting data in Popfinch, what has been measured, and what is deliberately absent.
- Version
- 0.2
- Effective
- 2 September 2026
- Last updated
- 2 September 2026
Scope and honesty about it
Popfinch is operated by one person on managed infrastructure. That shapes what is possible: the controls below are real and mostly enforced by the database rather than by discipline, and the things a larger operator would have — a separate security team, a penetration test, an ISO certification — do not exist. Both halves are stated because a customer's reviewer needs both.
No certification, audit report or compliance attestation is claimed. Where a control belongs to a vendor, their own reporting is the evidence, not ours.
Access to data
- Row-level security is on for every table. A policy, not a hidden button, is what stops one account reading another's rows, and the same rule applies to a request made by hand against the public database API.
- The application holds no service-role database key. Server-side reach comes from a small number of database functions that check a secret or the signed-in user themselves.
- Roles are owner, editor and viewer, enforced in the database. A person can also be granted one project without joining the organisation.
- API tokens are stored as a SHA-256 hash and never shown again. A token that has not been used for 180 days stops working. A token carries the access of the person who created it and can create or edit drafts; no token can publish a widget.
Data in transit and at rest
- TLS everywhere. The application sends HSTS for a year including subdomains.
- Integration credentials — an email marketing key, a webhook signing secret — are encrypted with AES-256-GCM before storage and are never displayed again after saving.
- The database is encrypted at rest by the provider.
- Widget images are in a public bucket and are readable by anyone holding the URL. That is stated in the terms, because it is a property customers need to know rather than a defect to hide.
The public endpoints
- The widget script is served only for a site key of the right shape, and a project with no domain listed serves nothing at all.
- The event and submission endpoints check the key shape and require the request to come from a domain you listed, so a key copied out of your page source does not work elsewhere.
- Submissions are capped per site per hour in the database, a duplicate submission of the same address to the same widget collapses into one row, and a honeypot field catches the simplest bots.
- The scheduled jobs refuse to run without the correct bearer token.
- The application sends a content security policy with a nonce, frame-ancestors restricted to itself, nosniff, and a referrer policy.
What has been measured
Load tested against production on 2 September 2026 with a temporary project, since deleted. These are measurements of that test, not a promise about tomorrow.
| Test | Result |
|---|---|
| Event beacons, 100 per second for 60 seconds | 5 997 requests, median 56 ms, 99th percentile 294 ms, no errors |
| Event beacons, 250 per second for 30 seconds | 7 500 requests, median 59 ms, 99th percentile 241 ms, no errors |
| Widget script, 200 per second for 30 seconds | 6 000 requests, median 20 ms, no errors |
| Submissions, 30 per second burst | 92 accepted and 358 refused — the hourly ceiling behaving as designed |
No uptime figure exists, because none has been measured over a meaningful period. None is promised anywhere in these documents.
Backups and recovery
Daily database backups are kept for seven days by the provider. Point-in-time recovery is a paid option and is not enabled, so the worst case recovery point is up to 24 hours of data.
A deleted row can survive in a backup until that backup expires. No recovery time is promised, because no restore has been rehearsed against a stopwatch.
Export your leads regularly. A copy you hold is the only backup whose recovery you control.
Monitoring and change control
- Every scheduled job records a heartbeat, and a daily operator digest reports one that stopped.
- Who did what is recorded per organisation and visible to owners on the Team screen.
- Types, lint and an automated test suite run before any deployment, and a check refuses the deployment if the production database no longer matches the recorded schema.
- Database changes are recorded as migration files with the applied change and an updated schema snapshot in the same commit.
What is absent
- No independent penetration test has been carried out.
- No ISO 27001, SOC 2 or comparable certification is held or claimed.
- Point-in-time database recovery is not enabled.
- There is no 24/7 on-call rota. The operator is one person in one time zone.
- No formal business continuity plan has been written or rehearsed.
A customer whose own obligations require any of the above should treat this as a gap to weigh rather than one to assume away.
Reporting a weakness
Write to security@popfinch.com. The security page at /security says what is in scope and what to include, and /.well-known/security.txt carries the same address for tooling. Test only against your own account, do not run denial-of-service tests against the live service, and give a reasonable period before publishing. There is no reward programme and no response-time commitment; a report is read by a person, and nobody reporting in good faith is threatened for it.