Description
Local Provider Key Custody lets the operator configure the embedding, AI-fill, and chat provider credentials used by a self-hosted instance without storing those secrets in the Dots database. The daemon opens an operating-system keyring backend when available and falls back to a permission-restricted local file for environments that cannot provide a keychain. Records are versioned, validated, and written atomically.
The API surface is write-only for secret values. It returns provider, presence, backend, capability, take-effect, and restart-required status, but never the raw key. Stored keys are layered into the daemon’s provider environment at boot. Chat can rescan live, while provider clients composed once at startup report that a restart is required.
Selling Points
- Keeps instance credentials outside the knowledge database they unlock, reducing accidental export and backup exposure.
- Uses native OS credential storage when available, with an explicit and permission-restricted fallback for headless environments.
- Shows which capabilities are active and whether a restart is needed without ever echoing a secret.
- Supports separate keys for embeddings, AI features, and chat instead of forcing one provider or credential.
- Applies environment-overrides-first layering, so controlled deployments retain an operator-managed source of truth.
User Story
An operator opens local AI settings and enters Voyage, Anthropic, and OpenRouter credentials. Dots seals them to the machine, reports which secure backend is active, and marks search and AI-fill keys as pending restart while chat activates after a rescan. On the next daemon boot, the stored keys are applied automatically without appearing in a Dotabase row.
Extension Surface
This feature is configurable. packages/api/src/schemas/provider-keys.ts defines the supported settings/status contract, while packages/local-runtime/src/secrets/provider-key-runtime.ts implements get/patch behavior over the secret store. Users choose keys and providers within the shipped roster. The custody backend is not an external plugin axis, and arbitrary secret names cannot be added through the route.
Capabilities & Limits
- Stores separate embedding, AI, and chat credentials with keyring or restricted-file custody.
- Exposes write-only updates and detailed non-secret capability status.
- Applies stored values at boot and supports live chat-provider rescan.
- Limit: embeddings and AI-fill providers composed at startup require a daemon restart after changes.
- Limit: the file fallback protects permissions but cannot offer the same OS-backed isolation as a keychain.
Implementation Map
packages/local-runtime/src/secrets/provider-key-store.tspackages/local-runtime/src/secrets/provider-key-runtime.tspackages/local-runtime/src/secrets/provider-key-env.tspackages/api/src/schemas/provider-keys.ts