Deed
Deed answers one question for every app you build: who is this, and can they prove it? It's a peer of Atomic, Backbone, and Canvas, not a primitive that lives under any of them, because identity is a different kind of problem than data storage or compute. Five primitives cover the whole shape of it: KeyAuth for passwordless login, JWT for general-purpose tokens, Vault for recovery blobs the slice can't read, Link for multi-device continuity, and Pocket for the app data that follows an identity to every device it uses.
Reach every primitive through the SDK exactly like Backbone's: no connection strings, no accounts to register anywhere but your own slice. Deed runs on its own listener, separate from Backbone's; there is no service to provision.
The primitives
- KeyAuthPasswordless login with a device key pair.
- JWTSign and verify with your slice's own key.
- VaultA recovery blob the slice cannot read.
- LinkEnroll a second device by signed attestation.
- PocketE2EE data that follows an identity everywhere.
Every primitive is called from inside your Atomic functions through the SDK. Deed's one CLI command is
read-only: drift deed status.
Encrypting client-side
Vault's and Pocket's guarantees are only as strong as the encryption you do before you call them. Drift
ships a zero-dependency ES module for that half: e2ee.js, a thin wrapper over WebCrypto
with no npm install and no build step. Copy it into your app's JS from
github.com/ondrift/cloud, under
cli/cmd/canvas/templates/. It is vendored by hand; there is no scaffold command.
import { generateKey, encryptJSON, decryptJSON } from "./e2ee.js";
const key = generateKey(); // 32 random bytes, hex
const sealed = await encryptJSON(key, { balance: 42 });
await fetch("/api/pocket", { method: "POST", body: JSON.stringify(sealed) });
encryptBytes and decryptBytes do the same for files.
encryptWithPassphrase and encryptWithSeed wrap a key under a passphrase or a
recovery seed, and that ciphertext is exactly what belongs in Vault
so a user recovers on a new device without the slice ever holding the key.
The content key must never travel through your slice.
Limits
- Value
- 4 KB on the free tier
- Past it
413, not persisted
- Value
- 100 on the free tier
- Past it
- The oldest entry is deleted
- Value
- 16 KB on the free tier
- Past it
413, not persisted
- Value
- 2 KB
- Past it
400
- Value
- 16 KB
- Past it
400
- Value
- 256 bytes
- Past it
400
- Value
- 120 s, single use
- Past it
- The handshake restarts at
Challenge
- Value
- 300 s
- Past it
- The enrollment restarts at
Begin
- Value
- 30 days
- Past it
Verifyreportsexpired
The Vault and Pocket rows come from your slice's tier; the rest are fixed. There is no
deed section in the Driftfile, so none of these are raised in the manifest.
Inspecting Deed
One read-only CLI command reports what the active slice is holding:
It prints a line each for Vault (entries), Link (identities) and Pocket (items), the quickest way to see whether Deed is holding anything at all. Everything else is SDK-only.