Encore
Trust

Receipts, not badges.

Every claim on this page is true of the code that is running right now - not a roadmap, not a marketing layer. Here is how your work and your clients' moments are protected, and a plain list of what we don't claim.

SHA-256 audit chainsOne access gateNo public buckets2FA on every plan

01 · Receipts

Tamper-evident by construction.

sha256(previous hash + event) - append-only, verifiable on read

Every view, download, and share in a delivered gallery is written to an append-only audit chain. Each event's hash is the SHA-256 of the previous event's hash plus the event itself, so the log can't be quietly edited after the fact - alter or remove one row and the chain breaks at exactly that row. Verification re-walks the whole chain and re-computes every hash.

The same chain carries account-level security events - password changes, 2FA on or off, recovery-code rotation, new devices - so "tamper-evident receipts" covers the account, not just the gallery. Even platform-level trust and safety review of a studio's content is written to a chain; cross-tenant access is never silent.

02 · Isolation

One gate on every byte.

shared access gate, re-checked per request - denials are 404, not 403

Every route that serves gallery content - the page itself, per-photo downloads, bulk zips, gallery audio, the live photo feed - passes through one shared access gate before anything leaves storage. The gate re-checks, in order: moderation takedown, studio suspension, expiry, private visibility, and password lock. One helper, one gate, no side doors that keep serving after a gallery goes dark.

Denials return 404, not 403: a private or taken-down gallery is indistinguishable from one that never existed. Password unlock cookies are HMAC-signed over the gallery id plus the current password hash - a cookie issued for one gallery can't open another, a hand-forged cookie fails verification, and rotating the password invalidates every cookie issued before it.

03 · Storage

Private bucket, expiring links.

Cloudflare R2, per-studio key prefixes, presigned GET/PUT only

Originals live in Cloudflare R2 in a private bucket, keyed per studio. There is no public bucket listing; content is served through presigned URLs that expire - a photo download link is signed for minutes, not forever. Uploads work the same way in reverse: the browser gets a short-lived presigned PUT and writes directly to storage, so large files never transit our application servers.

Encryption at rest for stored files is provided by Cloudflare as part of R2 - that's their work, and we credit it to them rather than dressing it up as ours.

04 · Accounts

2FA on every plan.

bcrypt passwords · TOTP + single-use recovery codes · session versioning

Passwords are hashed with bcrypt - never stored in a recoverable form. TOTP two-factor authentication and eight single-use recovery codes are available on every plan, including free; security is not an upsell. Recovery codes are stored as SHA-256 hashes and shown exactly once.

Sensitive changes - password change, 2FA disable, recovery-code rotation - bump a per-user session version that invalidates every other device's session and fire a real-time alert email. Sign in with Apple and Sign in with Google are supported alongside email and password.

05 · API

Tokens we can't leak.

SHA-256 hash storage, prefix display, instant revocation

API bearer tokens are stored as SHA-256 hashes - the same model as GitHub and Stripe keys. A leaked database row does not yield usable tokens, by design: the plaintext is shown once at creation and can't be recovered from what we store. The UI lists only a short display prefix, enough to tell tokens apart without leaking entropy.

Every token is scoped to a single studio, can carry an expiry, and can be revoked instantly. API access is a plan feature. Failed authentication returns a bare 401 with no hint about why - an attacker probing should learn nothing.

06 · Billing

Card data never touches Encore.

Stripe on web, Apple App Store on iOS - we store state, not credentials

Web subscriptions run through Stripe; iOS subscriptions run through Apple's App Store. Payment credentials live with those processors, never on our servers or in our database. We store subscription state - which plan, which interval, active or not - and nothing that could charge a card.

07 · Content safety

A real moderation and takedown program.

public report intake · DMCA agent · review console · enforced at the gate

Anyone can report a gallery without creating an account - a victim of abusive imagery shouldn't need a login to be heard. Copyright claims have a dedicated DMCA intake that notifies our agent and the affected studio. Reports land in a review console where a human acts on them.

Enforcement has teeth: a takedown darkens the gallery for everyone, including its owner, and a studio suspension darkens the entire tenant. Both are checked inside the same access gate every serving route uses, so taken-down content can't keep leaking through a stale link or a cached photo id.

08 · Ownership

Your frames, your receipts, your exit.

30-day trash window → hard purge · CSV audit export

Photographers own their work. Deleting a gallery moves it to trash, where it's recoverable for 30 days; after that a purge job hard-deletes the records and the stored files. Gone means gone.

Your audit log is exportable as CSV - the full hash-chained history of who viewed, downloaded, and shared what, in a format you can hand to a lawyer, a publication, or a licensing dispute. Your receipts leave with you.

The other half of honesty

What we don't claim.

Trust pages tend to be badge soup. Here is ours without the soup - the certifications we don't hold yet, and the protections that belong to our infrastructure providers rather than to us.

SOC 2 / ISO 27001

Not certified. We're a small, photographer-owned platform and we'd rather tell you that plainly than rent a badge. The mechanisms above are the real substance those audits check for; the paperwork comes when the business justifies it.

Third-party penetration test

No certificate to show you yet. The codebase gets internal security review, and the disclosure address below is read by the people who wrote the code.

Encryption at rest

Provided by our infrastructure: Cloudflare R2 encrypts stored files and Neon encrypts the Postgres database as part of their platforms. That's their engineering - we credit it to them instead of claiming it as our own layer.

Formal SLA

No contractual uptime guarantee today. Live and historical status is public at /status - judge us on the record, not a promise.

DPA / procurement paperwork

Need a data processing agreement or a vendor security questionnaire filled out? Email us at security@encore.photo and a human will handle it.

Responsible disclosure

Found something?

Report vulnerabilities to the address below. Reports go straight to the people who wrote the code, we read every one, and we won't come after good-faith research. We don't run a paid bounty program today - we'll say so plainly if that changes.

security@encore.photo