Skip to content

Configure credentials

User-supplied secrets (AI API keys, VCS tokens) are stored in one of three modes, selected by the init wizard. Whichever you pick, the resolved secret crosses the boundary as secrecy::SecretStringDebug renders [REDACTED] and memory is zeroed on drop.

The three modes

  1. Env-var reference (recommended default) — config references an env var, e.g. {provider}.api.env = "MYTOOL_ANTHROPIC_API_KEY". Nothing secret is written to disk.
  2. OS keychain (opt-in) — requires the credentials feature on rtb in the tool's Cargo.toml. The secret lives in the OS keychain via rtb-credentials; regulated downstreams omit the feature and link-time DCE keeps keyring out of the binary.
  3. Literal in config (legacy) — refused under CI=true.

Resolution precedence

At runtime the Resolver walks, in order:

{provider}.api.env  →  env var
                    →  {provider}.api.keychain
                    →  {provider}.api.key (literal)
                    →  well-known fallback env var

The well-known fallbacks are the conventional names — ANTHROPIC_API_KEY, OPENAI_API_KEY, GITHUB_TOKEN, … — so a tool works out of the box in environments that already export them.

Enable the keychain

# the downstream tool's Cargo.toml
[dependencies]
rtb = { version = "0.5", features = ["credentials"] }

Verify

The doctor command's credentials::no-literal check warns when any literal credential is present in config — run it before shipping a config template. See rtb-credentials for the CredentialStore / Resolver / CredentialRef API.

Never log the exposed secret

Calling expose_secret() is required to use a SecretString, but the exposed &str must never be logged or formatted. Free-form strings that might contain a secret should pass through rtb-redact first.