User-level credential storage for model providers.
Persists API keys (and, in the future, OAuth tokens) under
~/.deepagents/.state/auth.json (file mode 0600, parent 0700) so users can
enter credentials directly in the TUI rather than exporting environment
variables before launch.
Security notes:
ApiKeyCredential.key) must never be logged, formatted
via %r/!r, or interpolated into exception messages — every helper here
reports only structural facts ("set credential for provider X").O_EXCL | 0o600 to a temp path, then atomically
replaced. A second chmod 0600 runs on the final path so filesystems that
ignore the create-mode argument still end up with private perms. Permission
failures are reported back to the caller in WriteOutcome.warnings so the
UI can surface them to the user — logger.warning alone is invisible
inside a Textual TUI session.Return all stored credentials keyed by provider name.
Return the stored API key for provider, or None if unset.
Returns None for stored OAuth credentials too — callers that need
OAuth tokens should read load_credentials() directly and narrow on
type.
Persist an API key for provider.
Empty / whitespace-only keys are rejected so callers don't accidentally
write a sentinel that masks a working environment variable (see
apply_stored_credentials in model_config — a stored empty would
unconditionally overwrite the env var).
Remove a stored credential for provider.
Return providers that currently have a stored credential, sorted.
A persisted API key credential.
The type field is the discriminator that lets OAuthCredential (added
later) coexist in the same file without migration.
A persisted OAuth subscription credential.
Stub kept here so the StoredCredential discriminated union narrows
correctly today and the OAuth implementation lands as a pure addition.
No code path produces or consumes this shape yet.
Result of a credential write that may have warnings to surface.
Tagged union of every persisted credential shape, narrowed by type.