Authentication
Authentication
Every agent connecting to Lettuce presents a bearer token on each request (Authorization: Bearer <token>). Tokens are stored in the macOS Keychain and created with scopes and an optional folder allowlist.
Token format
A token is URL-safe base64 of 32 random bytes — about 256 bits of entropy, no prefix:
kJ8x2Vn-Qe7rL0pZ4aB1cD3eF5gH6iJ8kL0mN2oP4q
It’s shown once, at creation. After that the raw value lives only in the Keychain; logs record only the agent’s label, never the secret.
Creating tokens
From the shell:
lettuce keys add --label "Claude Desktop" --scope write --propose
lettuce keys add --label "Reader" --scope read
lettuce keys add --label "Triage" --scope write --allow Inbox,Areas/Work
--label(required) — a human name, shown in logs and the Agents sidebar. Keys are referenced by label (there are no separate key IDs).--scope—read,write, orall(= read + write). Defaults toall.--propose— makes a write-scoped key queue proposals instead of committing (Suggestions mode).--allow— a comma-separated folder allowlist; omit for whole-vault access.
The secret prints once. The app’s Settings → General → API keys section manages the same Keychain-backed keys from the GUI.
Scopes
| Scope | Read tools | Write tools (write_note, apply_edits, patch_section, …) |
|---|---|---|
read |
✅ | ❌ |
write |
✅ | ✅ |
all |
✅ | ✅ (read + write) |
Propose-only is a modifier, not a scope. Add --propose to a write-scoped key and the server intercepts each write and queues it as a proposal you approve from the proposals UI — nothing lands on disk until you accept. The agent calls the same write tools either way; the key’s mode decides whether they commit or queue. See Suggestions mode/01 Overview.
There is no separate propose_edits tool: proposing is a property of the key, not a distinct call.
Vault scoping
Each server instance serves a single vault — the one Lettuce.app has open, or the path given to lettuce serve. Tool calls don’t carry a vault argument; every path is relative to that one vault. To span multiple vaults, run one server (and token) per vault. A token can still be narrowed to a subset of folders within its vault via the --allow allowlist.
Removing / rotating
lettuce keys list # label, scopes, allowlist, mode, value
lettuce keys remove --label "Triage" # removes every key with this label
There’s no in-place rotate: to rotate, remove the label and add a fresh key, then reconfigure the agent with the new value. Removal is immediate — subsequent requests with the old token get a 401.
Where tokens live
Tokens are stored in the macOS Keychain (the same store the app uses); the raw value never lands in your vault, .lettuce/, or the logs. Incoming tokens are compared in constant time. Lose a token and you can’t recover it — remove the label and add a new one.
Related
Suggestions mode/01 Overview — why propose-only is the recommended default for autonomous agents
Troubleshooting/02 Proposals tab is empty — scope mismatches
Troubleshooting/04 Keychain reset — clearing stuck credentials