Security

Transport, signing, key management, idempotency, PII handling, and the contracts Paperless relies on. Read this with your security team before go-live.

Transport

Signing scheme

All webhooks and push requests are signed with HMAC-SHA256. The canonical string is timestamp + "." + raw_body; see the webhook contract page for the complete spec. Notes specific to security review:

Key management

Inventory of secrets

SecretLives onUsed forPattern
Paperless OAuth client secretPaperless serversAuthenticating Paperless to your /oauth/token.A
OAuth access token (per merchant)Paperless DB, encrypted at restBearer on calls to your APIs.A
OAuth refresh token (per merchant)Paperless DB, encrypted at restMint new access tokens.A
Webhook signing secretBoth sidesHMAC-sign webhook events.A, B
Push API keyBoth sidesAuthenticate push requests.B

Encryption at rest

Paperless encrypts every OAuth token before it touches durable storage. Default implementation uses Fernet (AES-128-CBC + HMAC-SHA256); AWS KMS is supported behind the same interface and selected per deployment. Plaintext tokens never leave RAM on the worker.

On your side, we expect equivalent controls. Concretely:

Rotation

SecretDefault cadenceRotation procedure
Webhook signing secret12 monthsDual-key window (see below).
Push API key12 monthsDual-key window.
OAuth client secretOn demandPaperless re-onboards; merchants do not need to re-consent.
OAuth access tokenPer your TTL (≤ 30 days recommended)Paperless refreshes automatically when ≤ 7 days left.
OAuth refresh tokenPer your policyIf you rotate on every refresh, return the new value in the refresh response.

Dual-key rotation window

For signing secrets and API keys, both sides honor two keys at once during rotation:

  1. Day 0: Paperless issues SECRET_NEW alongside the existing SECRET_OLD.
  2. Days 0–7: receiver accepts a signature that validates under either secret.
  3. You cut over: start signing with SECRET_NEW whenever you are ready.
  4. Day 7: SECRET_OLD is retired. Signatures under it are rejected.

If you need a longer window, request it; 30 days is the maximum.

Idempotency & replay

PII handling

DataAllowed?Notes
Full PANNever sent. Sending a 13–19 digit value as last4 is treated as a possible PAN leak and the receipt is rejected.
Card last4Exactly 4 digits.
Card brandPlain text (VISA, MC, …).
Cardholder nameDo not send.
CVV / expiryNever. PCI-DSS prohibits this anyway.
Customer emailUsed for matching. Stored encrypted at rest.
Customer phoneE.164. Stored encrypted at rest.
Government ID numbersTax number for the merchant only — never for the customer.

Network egress and IP allowlists

Logging and audit

Incident response

If you suspect a signing-key or API-key compromise:

  1. Contact your Paperless solutions engineer immediately. They will rotate the affected key within 1 hour.
  2. Paperless invalidates the old key and rejects any signature that validates under it.
  3. You re-sign in-flight retries under the new key.
  4. Paperless will provide a forensic export of the last 30 days of webhook traffic for that merchant on request.
Do not log secrets

Never log the webhook signing secret, the push API key, or any OAuth token. Log signatures (header value) only at DEBUG level and scrub them at INFO and above.

Compliance posture