Security and trust
Boring where it counts
Trust is a foundation here, not a compliance sprint before the enterprise deal. Everything on this page is built today and covered by tests that run before anything ships. Where we do not have something yet, this page says so.
Controls
How the boundary is enforced
These are the mechanisms, not the marketing words for them. Each one is something a reviewer can point at in the code.
Workspace isolation, deny by default
Every query is scoped by a workspace id taken from the session or the API key, never from anything a client sends. A record in another workspace answers 404 rather than 403, so an id cannot be used to prove that something exists.
API keys, hashed and scoped
Keys are stored hashed. The secret is shown once at creation and never again. Every key carries explicit scopes and separate test and live modes. A missing scope is a refusal that names the scope it wanted.
Signed webhooks with a closed replay window
Each delivery carries an HMAC SHA-256 signature over a timestamp and the raw body. Verify it in constant time and reject anything older than five minutes. Failed deliveries retry with exponential backoff and every attempt is logged with its request and response.
Roles that hold on every read and write
Permissions are checked on the server for every action, not hidden in the interface. A teammate without a permission gets a refusal, not a disabled button they can work around.
An audit trail nobody can edit
Events are append-only rows. They are never updated and never deleted, not by us and not by a workspace admin. A correction is a new row, so the history you read is the history that happened.
Rate limits and idempotency on public routes
Every public route is rate limited. Writes accept an Idempotency-Key so a retry after a timeout returns the first result instead of creating a second record.
Privacy
Consent is part of the data model
Most tools bolt consent on when a customer asks about GDPR. It has been a column on every contact here since the first migration, which changes what the product can guarantee.
Consent is a column, not a checkbox we remember
Consent status, where it came from and when it was given sit on every contact from the first migration, alongside unsubscribe and suppression state. They are not a later retrofit, which is why a send can be blocked at the data layer rather than at the send layer.
Suppression is honored on every send
An unsubscribe or a suppression stops sends for that person across the workspace. It is not per campaign and it is not something a bulk import can quietly override.
Personal data is masked before any model call
Where the product uses a model, personal fields are masked first. New fields that describe a person go through a privacy classification before they are allowed into the schema.
Your data
Leaving is a feature, not a support ticket
A product that makes leaving hard is telling you what it thinks of its own value. Export and deletion are built in and covered by tests.
Export the whole workspace in one click
Contacts, submissions and the event stream, in a format you can load somewhere else. Not a support ticket, not a CSV of the current page.
Deletion that sticks
Delete a person and a tombstone remains, so a later CSV import cannot quietly bring them back. The deletion itself is recorded as an event.
Who else touches the data
The full list of processors
Every company that can see workspace data and what each one does. If this list changes, this page changes with it.
- CloudflareWorkers, R2 object storage and Queues. The public API, the embed and form delivery run here.
- NeonManaged Postgres. One schema, shared by the app and the worker over an HTTP driver.
- VercelHosting for the product interface and this marketing site.
- Amazon SES and SNSEmail sending and delivery notifications. Nothing else runs on AWS.
- StripePayments and billing. Card details go to Stripe and never touch our servers.
What we do not have yet
The part most security pages leave out
A buyer will ask these questions in the first call, so here are the answers before the call.
No third-party certification today
PopzIQ does not hold SOC 2, ISO 27001 or any equivalent audit report. The controls above are real and tested. An auditor has not yet been asked to sign off on them. We will say so on this page when that changes, naming the report and its period.
No published penetration test yet
Security review runs on every change to the trust surface and the isolation, key scoping, webhook signing and rate limit behavior is probed by an automated sweep before each deploy. An external test is not finished, so there is no report to share.
Data residency is not selectable
You cannot pin a workspace to a region today. If that is a requirement for you, email hello@popziq.com so it is weighed against the rest of the roadmap.
Responsible disclosure
Found something? Tell us first
Email security@popziq.com with what you found and how to reproduce it. We aim to acknowledge within two business days and will keep you posted while we fix it. Please do not run tests that degrade service for other workspaces or access data that is not yours.
Every control on this page is enforced on the free plan too. You do not have to talk to anyone to see it working.