Key storage
On the box
Section titled “On the box”Everything sensitive sits in the vault directory
(GRAY_VAULT_DIR, default /var/lib/voice-brain/), separated from the brain’s
working directory on purpose — agents work in the workspace; the vault is not
their playground.
| Credential | Where | Mode |
|---|---|---|
| Account + session credentials (and the box code until it’s used) | <vault>/selfhost_auth.json | 0600 |
| Paired SSH hosts + pinned host keys | <vault>/console_targets.json | 0600 |
| Plan entitlement | <vault>/entitlement.json | 0600 |
| Model/API keys | the box .env (installer writes it tight) | owner-only |
The brain’s file jail (GRAY_FILE_ROOT) scopes what agents can touch; keep the
vault outside it (the default layout already is).
On the phone
Section titled “On the phone”- The box session token — the phone’s secure keystore.
- Passkey private keys — the platform authenticator (Secure Enclave on iPhone, the hardware keystore on Android), never readable by Gray.
- No model keys, ever. The app has no field to enter one.
In transit
Section titled “In transit”Phone ↔ box traffic is HTTPS inside your tailnet. Premium-voice sessions use
short-lived tokens minted by the box (about 5 minutes of headroom per mint), so
your real OPENAI_API_KEY never leaves the box.
Rotation
Section titled “Rotation”Rotate a model key by editing .env and restarting the service. Rotate your
session by signing out (or Lock down & revoke — see
Security model). Re-pair a host to rotate its pinned key.