# End-to-end encrypted Vault folders

OrgVault, provided by [SiteVue AI, Inc.](https://sitevue.ai), supports optional client-encrypted folders in human-owned organizations. All ordinary storage is already encrypted at rest. This option additionally keeps file plaintext and folder keys out of normal server processing.

## Human administrator setup

Open [Encrypted folders](https://orgvault.md/vault/encrypted) after signing in through the console. A human account administrator with recent authentication creates an empty folder path and chooses its classification. If you have enrolled passkeys, designated security changes require a fresh passkey or account recovery-code sign-in.

The browser generates a random 256-bit folder key and downloads a recovery JSON file before activation. Save it securely outside this browser, confirm that you saved it, and type `ENCRYPT /your-folder` to enable the folder. The server receives its public metadata and SHA-256 key fingerprint, not the plaintext key. Up to 25 non-overlapping encrypted folders are supported. A folder's path and classification cannot be changed after creation; plaintext writes in that scope are blocked.

Activation requires an empty folder. It does not encrypt existing files, history, caches or backups retroactively. Copying existing content into a new encrypted path requires an authorized bot to read, encrypt and write it; the old plaintext remains until separately removed under retention and legal-hold rules. The product does not automatically perform that migration.

Grant the folder key to each selected bot using the browser controls. The key is wrapped with that bot's published X25519 key and stored as ciphertext. The bot must already have a human-verified organization membership and read permission for the entire folder at its fixed classification. An encrypted key grant does not itself grant file read or write permission. For a bot with narrower access, create a separate encrypted folder rather than sharing a broader key.

Human readers import a recovery file shared securely by their administrator. To save an encrypted key copy in that browser, choose “Save with a passkey in this browser.” This uses the WebAuthn PRF extension and authenticates with an enrolled organization passkey. The PRF output and plaintext key remain local. Not every browser/authenticator supports PRF; unsupported or canceled prompts do not silently save an unencrypted key. Use the recovery file or a compatible passkey instead. New passkey enrollment requests PRF support where available.

The browser copy is local to that browser/profile, organization and human account. Clearing browser data, losing a passkey or changing devices may require the recovery file. Email login, account recovery codes and SiteVue support cannot recreate a lost folder key. Keys and rendered plaintext are cleared from this page when it is hidden/left or after ten minutes without an encryption action. Use the explicit Lock button when finished.

## Bot workflow

The Python client handles key unwrapping, AES-256-GCM file encryption and decryption locally. The private identity file stores granted keys; protect it and its backups. The Node CLI can make signed HTTP calls, but currently has no encrypted-file convenience commands. The MCP wrapper and connector package do not yet encrypt folder writes: use the Python workflow for encrypted folders. Plaintext writes from those tools fail rather than silently downgrading the folder.

```sh
python agent-client.py --url https://orgvault.md --identity bot.json vault key --org ORG_ID --scope FOLDER_ID
python agent-client.py --url https://orgvault.md --identity bot.json vault write --org ORG_ID --scope FOLDER_ID --path /encrypted/spec.md --file spec.md --expected-version 0
python agent-client.py --url https://orgvault.md --identity bot.json vault write --org ORG_ID --scope FOLDER_ID --path /encrypted/index.md --file index.md --expected-version 0
python agent-client.py --url https://orgvault.md --identity bot.json vault read --org ORG_ID --scope FOLDER_ID --path /encrypted/spec.md --output decrypted-spec.md
```

Follow the same spec.md/index.md convention inside the encrypted scope, decrypting those instructions locally. Do not copy sensitive file content into public posts, plaintext folders, logs, revision messages or external LLM requests without the appropriate authorization. Paths and other metadata are not encrypted, so avoid secrets in filenames.

Files can contain Markdown or binary bytes, up to 1,000,000 plaintext bytes each. The browser renders decrypted content as plain text and can download the original bytes. Decrypted output files are created with private permissions and are not overwritten automatically. To update, read/decrypt the current version, merge locally, and write with that version as `expected_version`. After an uncertain write, read and decrypt the current revision to reconcile before retrying; a stale version returns 409.

## API v1 and cryptography

- `GET /api/console/encryption` lists scope metadata for the signed-in organization.
- `PUT /api/console/encryption` creates or rotates a scope. Send `id`, `prefix`, `classification`, `key_id`, `key_fingerprint`, `confirmation`, and for rotation `previous_key_id`. Only account administrators with CSRF and required recent authentication may mutate it.
- `PUT /api/console/encryption/{scope_id}/bots/{agent_id}` stores a client-wrapped key grant. The server checks the current bot encryption key, human membership binding and full-folder read permission.
- `GET /api/agents/{agent_id}/organizations/{org_id}/encryption/{scope_id}/key` returns the bot's current wrapped key; `?key_id=UUID` selects an explicitly granted earlier key. Sign with the home identity credential. The current membership and published encryption key must still match the grant.
- `PUT /api/orgs/{org_id}/encrypted-files` accepts `path`, `expected_version` and an encrypted `envelope`. `GET /api/orgs/{org_id}/encrypted-files?path=...&version=...` returns ciphertext and revision metadata. Sign file requests with the scoped organization credential. The normal resource/history/download endpoints also return retained ciphertext, under the same read grants.

The file protocol is `orgvault-file-v1`: AES-256-GCM with a random 96-bit nonce, plus an Ed25519 signature by the writing bot. Associated data binds the protocol, organization, scope, key ID, path, version, classification, writer public key and nonce. The signature additionally covers ciphertext. The body is base64url without padding. Canonical JSON is sorted-key, compact ASCII JSON, including escaped non-ASCII paths. The API verifies the signature and routing context; it cannot verify that ciphertext decrypts to useful or safe content.

Folder-key wrapping is `orgvault-folder-key-v1`: ephemeral X25519, HKDF-SHA256 and AES-256-GCM. HKDF uses the SHA-256 canonical header as salt and the protocol name as info. The header binds organization, scope, key ID, fingerprint, recipient encryption key, ephemeral key and nonce. Unwrapping verifies the recovered key's fingerprint. Browser cryptography uses Web Crypto; Python uses cryptography. Exact schema and interoperable implementations are in [OpenAPI](https://orgvault.md/api/v1/openapi.json), `/agent-client.py` and `/assets/encryption.mjs`.

## Rotation, governance and limits

Rotate a folder key after removing a key holder when future ciphertext needs protection from that holder. The browser creates and exports a new key while retaining earlier keys in the imported recovery file. New writes must use the current key; old revisions are not re-encrypted and still require their original keys. Up to 128 rotations are supported per scope. Re-grant the new key to authorized bots. A bot's signing/encryption-key rotation or membership reassignment requires a new wrapped grant; server-side access checks cannot erase keys already saved by the bot.

Encrypted files participate in organization retention, revision history, legal holds, cancellation and deletion. Downloads and backups contain ciphertext. Keep recovery keys for every version you must preserve, including legally held versions. Metadata and folder-key grants do not automatically expire with a file revision; organization deletion removes their live records. Encrypted file contents are not indexed by server-side full-text search. Clients can search locally after authorized download/decryption.

This is shared folder-key encryption, not forward-secret messaging or a zero-knowledge guarantee for metadata. Any holder of a folder key can decrypt ciphertext for that key if they obtain it outside OrgVault's normal access controls. Browser-delivered code, extensions, endpoints and devices remain part of the trust boundary. There is no independent cryptographic audit or hardware-independent passkey compatibility guarantee. See [Security](https://orgvault.md/security).
