← ClaudeAtlas

authoring-e2ee-featurelisted

The decide-the-columns -> schema -> ciphertext DAL -> seal/open at the screen -> store-policy -> DSR record -> reviewers recipe for encrypting one feature end-to-end with the opt-in e2ee module, so the server never holds plaintext or a key that decrypts it. Use when asked to encrypt a feature, add client-side encryption, or make a column unreadable to the server.
BhodiSea/next-expo-supabase-agent-harness · ★ 1 · API & Backend · score 70
Install: claude install-skill BhodiSea/next-expo-supabase-agent-harness
# Authoring an E2EE feature Encryption sits ON TOP of the authorization boundary, never in place of it: RLS keyed on `auth.uid()` still decides which rows a caller may read, and `@app/crypto` decides whether the bytes mean anything once read. Everything in the `authoring-vertical-slice` recipe still applies — migration, RLS, `./client` read, procedure, both screens, tests, provenance, green gate. This recipe is what that slice gains when a column must be unreadable to the server, and what it LOSES in exchange. Build in this strict order. Steps 1, 5, 6 and 7 are irreversible-ish in different ways: a column encrypted for a month cannot be retroactively indexed, and a user who loses the device AND the recovery code cannot be given their data back. ## Step 0 — preconditions, all three Do not start until all of these are true: 1. **The module is enabled** — `packages/platform/crypto/` exists (`@app/crypto`). If it does not, the module is opt-in and enabling it is a separate, reviewed act: read `docs/modules/e2ee/README.md` first, in particular "What this deliberately does NOT solve". 2. **Host adapters are wired.** `createWebCryptoProvider()` (and, if the feature shares, `createWebCryptoX25519Provider()`) cover web and Node and return `null` where there is no Web Crypto. The MOBILE `CryptoProvider` / `X25519Provider` and BOTH surfaces' `KeystoreAdapter` are consumer code — `docs/modules/e2ee/mobile-provider.patch.md` is the recipe. Hermes ships no Web Crypto