# Security and data handling

CherrySub verifies store evidence before app attribution and persists immutable event history with mutable projections. Its boundaries separate service operators, hosted project users, app servers, and public clients. These are implemented controls, not a blanket certification or guarantee of compliance for every deployment.

## Account and project access

Hosted browser and CLI sessions use opaque `JSESSIONID` values. Server-side records retain token hashes and enforce expiry, email verification, project membership, and operation-specific roles. Owners/admins configure project resources; viewers inspect them. Personal saved analyses and export requests also bind to the requesting account.

Passwords are hashed with bcrypt. Verification, reset, and invitation links use bounded-lifetime opaque tokens with hash storage. Password reset and session-revocation flows invalidate their documented sessions. A copied URL does not grant project access.

## Application credentials

App API keys are shown once and stored as digests plus safe hints. Public `iap_pk_` keys require an app/customer-bound `iap_ct_` token for runtime operations. The token's subject must match the receipt or subscriber identity before any store I/O or ownership transition.

`iap_sk_` stays on the authenticated application backend. Root admin keys configure the operator boundary and are not a substitute for hosted project login. Do not ship either kind of server authority in public client bundles, generated documentation examples, analytics events, or support notes.

## Store verification

Apple signed evidence is checked against the pinned Apple root/certificate-purpose chain, ES256 signatures, and online certificate status. Nested signed transaction/renewal data is independently verified and cross-checked against app identity/environment. Production includes the signed numeric app ID check. A certificate responder outage is retriable; it does not activate a runtime verification bypass.

Google Pub/Sub ingress checks the OIDC signature, exact configured audience, expected service-account email, and verified email claim before processing the notification. Purchase notification numbers are a doorbell; an authenticated Android Publisher read supplies authoritative purchase state.

Invalid or unknown evidence is not trusted to select another app. Rejected-delivery metadata is bounded and separated from trusted purchase history.

## Encrypted secrets and rotation

Managed store credentials and webhook signing secrets are encrypted at rest with configured master-key rings. API responses expose safe metadata rather than plaintext. Operators must keep matching encryption configuration across the processes that read/write those secrets.

Prepend a new master key while retaining decryption coverage for old encrypted records. Re-encrypt/rotate the affected managed secrets using the supported processes and verify startup coverage before removing old keys. A database backup without its corresponding encryption keys is not sufficient for recovery.

Webhook secret rotation signs with overlapping old/new secrets for 24 hours. The CLI keeps Apple passwords, Apple session cookies, and Google OAuth tokens local to the process and does not store them in profiles. Its saved session profiles use private file permissions on macOS/Linux and normal private user-directory ACLs on Windows.

## Webhook and export boundaries

Outbound delivery requires public HTTPS destinations, rejects private/special networks, rechecks DNS when connecting, and refuses redirects. Receivers still need raw-body signature verification, timestamp validation, durable idempotency, and safe downstream processing.

Exports contain normalized report fields, not raw credentials or complete ledger payloads. Private object storage, token-hash metadata, expiring fragment-token download links, no-store responses, and spreadsheet-formula neutralization reduce unintended disclosure. Anyone intentionally given a still-valid download token may be able to retrieve its report; treat that link as a secret.

## Retention and deletion

The ledger is append-only and application disable does not erase its history. Deleting a support note or saved view affects that object, not customer purchases. The current product does not expose a general self-service customer-data erasure workflow.

Data-retention periods, backup retention, access review, incident response, and legal/compliance obligations remain deployment/operator policies. Do not infer a promised retention period, data residency guarantee, or certification from the existence of an EU staging host or encrypted storage.

## Operational checks

Keep database/app ports private behind HTTPS, protect metrics, apply deployment-wide rate limits in addition to process-local receipt throttling, back up data and required keys separately under controlled access, and test restoration. Use supported dependency/toolchain patches and verify releases before changing live routing.

Production topology, high availability, and zero-downtime requirements are separate from the current single-origin staging setup. [Self-hosting](/docs/self-hosting) · [Limits and status](/docs/limits-and-release-status).
