Credentials
Custody is injected. LLM does not own where secrets live. The application that embeds it hands
in a SecretResolver, and a catalog names only a SecretRef: a validated opaque lookup name — not
a secret value, and not a choice of storage backend. The same catalog works unchanged whether the
resolver reads a file, a keychain, or something the application wrote itself.
pub trait SecretResolver: Send + Sync {
fn resolve<'a>(&'a self, reference: &'a SecretRef)
-> BoxFuture<'a, Result<ResolvedSecret, SecretError>>;
// `refresh` has a default that returns `RefreshUnsupported`.
}
The guarantees
- Resolution happens at request time, so rotation works without restarting the caller.
- Returned material is zeroized on drop, redacted in
Debug, and has noSerializeorDisplayimplementation. - LLM never searches ambient vendor directories, runs a login flow or writes a credential file.
- Configuration carries references, never values. An entry value never belongs in argv, TOML, tracing or a diagnostic.
- A coordinated resolver serializes resolution and refresh per reference, and refreshes only the credential generation that was actually rejected — so concurrent callers cannot refresh the same generation repeatedly.
Anonymous is a first-class mode
Anonymous accounts require an absent reference; authenticated modes require a present one. Billing kind — metered, subscription or self-hosted — is independent of both protocol and authentication presentation. A rejected subscription credential never changes the billing kind or the account.
Optional local adapters
The default feature set has no file or native credential-store dependency. The adapters are opt-in:
| Feature | Source | Availability |
|---|---|---|
file | An explicit absolute path per reference | Linux; other platforms return UnsupportedPlatform on resolve |
keychain | An explicitly injected keyring_core::CredentialStore with a service and entry per reference | Any compatible injected store |
native-keychain | A native-store constructor; includes keychain | Linux Secret Service, macOS Keychain, Windows Credential Manager |
More columns: swipe horizontally, or focus the table and use the arrow keys.
These adapters read existing material only. They do not create entries, perform a login, refresh a token, search a vendor configuration directory, pick another source when a reference is absent, or modify the process-global keyring store. Provisioning and rotation are the operator's.
They identify exact content rather than issuer generations, so they return RefreshUnsupported;
independently replaced bytes are visible on the next resolve.
Resolve a local secret shows the file adapter's protection rules.
Planned: resolution through a shared secrets library
A further adapter is planned but not implemented: an optional feature that resolves a
SecretRef as a name in a scoped secret store provided by a separate secrets library. It waits
for a release of that library, and it must not change any route reference or add a dependency to
the core crates. Until it exists, inject your own SecretResolver for any store the two local
adapters do not cover.