SECURITY

Nothing worth stealing

No marketing copy here — just the facts about what Permitly stores and how the system protects your users.

What Permitly stores

Field What it is Why we store it
end_user_ref Opaque string you provide — we recommend using a non-PII internal ID Match consents back to your users without us knowing who they are
end_user_email Optional. Only stored if you send it in the API request Allow email notifications if you opt in
Consent metadata Scope keys, status (pending/approved/declined/revoked), timestamps Core product function — the consent record itself
API key hash bcrypt hash of your key — never the key itself Authenticate your API requests
Audit events Event type, agent, actor, IP address, user-agent, timestamp Compliance record and dashboard activity feed

What Permitly does NOT store

  • User passwords — We have no login for end users. None to store.
  • Payment data — Billing is handled by Stripe. We never see card numbers.
  • OAuth access tokens — We do not proxy OAuth flows. We only store consent metadata.
  • The signed JWT itself — We store only the jti (JWT ID) reference for revocation. The token lives on your side.
  • Private keys in recoverable form — ECDSA signing keys are stored encrypted at rest. We cannot extract plaintext.

How consent tokens work

  • Issued on approval as a signed JWT, using ECDSA P-256 per-agent key pair.
  • Short-lived by default — the exp claim is set at issuance. Expired tokens are rejected.
  • Your backend verifies the token via POST /v1/consent/verify before granting agent access.
  • Revocation is immediate — a revoked token returns 422 on verify, even before exp.

Builder verification

Before any builder's agent can send a consent request to a real end user, the builder's account must complete two one-time checks:

  • Domain ownership — proven via a DNS TXT record, the same pattern used by Google Search Console and Apple Pay domain registration.
  • A payment method on file — via Stripe, with no charge made. This is an accountability signal, not a billing requirement.

Once verified, the builder's domain is displayed on every consent page their agents send — so as an end user, you have something concrete to check an agent's claimed identity against, not just a name and logo the builder typed in. Verification doesn't guarantee an agent is who it claims to be, but it raises the cost of impersonation and gives you, and us, a real account to act on if something looks wrong.

How to revoke consent

USER SELF-SERVICE

Every approval email contains a /manage/{token} link. The user can revoke any consent without needing a Permitly account.

BUILDER API

DELETE /v1/consent/{id} revokes immediately. Both paths fire the consent.revoked webhook instantly.

Retention

Plan Audit log retention
Free 30 days
Starter 1 year
Pro 3 years

Active consents and the core consent record are retained until revoked or the account is deleted, regardless of plan.

Questions?

Security questions or vulnerability reports: security@permitly.dev
Privacy policy: permitly.dev/trust