Store a secret in the OS keychain¶
KeyringStore writes to the macOS Keychain, the Windows Credential
Manager, or the Linux kernel keyring, depending on the target it was
built for.
Write a secret¶
use rtb_credentials::{CredentialStore, KeyringStore, SecretString};
let store = KeyringStore::new();
store.set("mytool", "anthropic", SecretString::from("sk-ant-...".to_string())).await?;
The two strings are the keychain's service and account identifiers.
service is conventionally your tool's name, account the provider or
user. Neither is interpreted by this crate — they are passed straight to
the platform.
set overwrites an existing entry without complaint.
Read it back¶
An absent entry returns CredentialError::NotFound with the name
"mytool/anthropic". Any other backend failure returns
CredentialError::Keychain carrying the platform's message.
Delete it¶
Deleting an entry that does not exist returns Ok(()). There is no need
to check for existence first, and no way to distinguish "deleted" from
"was not there".
Point a config at the entry you just wrote¶
Both subkeys are required — omitting either is a config load error, not a resolution-time miss.
Run it on a Tokio runtime¶
Every KeyringStore method wraps a blocking call in
tokio::task::spawn_blocking, which panics outside a Tokio runtime.
#[tokio::main]
async fn main() -> miette::Result<()> {
let store = KeyringStore::new();
// ...
Ok(())
}
There is no way to use KeyringStore on async-std or smol. If you
need one of those, use EnvStore or write your own CredentialStore.
Expect this to fail on servers, containers and CI¶
Keychain access needs a platform keychain to be present and unlocked.
Headless Linux servers, containers and CI runners generally have
neither, and get fails there with CredentialError::Keychain rather
than NotFound.
That distinction matters when the credential is resolved through a
Resolver: a Keychain error aborts the whole resolution, so a
configured fallback_env will not rescue it. On machines without a
usable keychain, leave the keychain key out of the config entirely and
use an environment variable.
On Linux there is a second constraint. The default backend is kernel keyutils, whose entries vanish when the session ends — a secret written in one login is gone after a reboot. See enabling persistent Linux storage.
Handle the platform differences you cannot avoid¶
| Platform | Persistence | Common failure |
|---|---|---|
| macOS | across reboots | user declines the unlock prompt |
| Windows | across reboots | rare; credential manager is generally available |
| Linux (default) | session only | no session keyring in a container |
Linux (linux-persistent) |
across reboots | no D-Bus session or no keyring daemon |
A tool that must work everywhere should treat the keychain as one optional source among four, not as its storage layer.