Private image storage
Studio gallery originals and free-gallery web-size viewing copies are stored in a private Cloudflare R2 bucket without a public custom domain. Authorized or signed image routes read them through a Worker binding and return transformed previews. Preview transforms fail closed instead of substituting an unprotected source, and protected responses include noindex and noimageindex headers.
Access links and passwords
Anonymous edit and client links use separate random tokens whose hashes are stored in the database. Optional gallery passwords and account passwords are stored as salted PBKDF2-SHA256 hashes, not as readable passwords.
Short-lived asset delivery
Preview URLs use signed tokens with bounded lifetimes. Studio original downloads use short-lived presigned R2 requests and remain subject to gallery access and download settings; free anonymous galleries are view-only.
Transport and browser controls
Production hosts redirect to HTTPS. Sessions use HTTP-only cookies, login and anonymous-creation endpoints are rate limited, and private HTML routes return no-store plus noindex headers.
Anonymous-gallery lifecycle
Anonymous client and edit access ends 14 days after creation. A scheduled, secret-protected cleanup job removes expired gallery records and their R2 objects; access expiry does not depend on the cleanup job running.
Studio-gallery lifecycle
Studio galleries close and move to a reversible archive 14 days after creation. Archived galleries reject client access and uploads while retaining their records and images until restored or deliberately deleted.
Tenant checks
Registered galleries resolve within a studio context. Admin image and gallery requests check the authenticated studio or system-admin session before returning protected data.