credentials¶
Feature: Credentials. Passthrough subtree — --output must appear after the
word credentials. Unlike config, there is no default subcommand: bare
mytool credentials is a usage error.
Every subcommand works from the tool's declared credentials, which come from
App::credentials() — populated by ApplicationBuilder::credentials_from(...). A
tool that never wires a provider has an empty credential set: list prints an empty
table, doctor succeeds trivially, and everything taking a <NAME> fails with
no credential named `<NAME>` and the help text no credentials are configured
for this tool.
The four layers a credential can declare¶
A CredentialRef may declare any combination of env, keychain, literal and
fallback_env. The resolver tries them in that order and stops at the first hit.
credentials list¶
Prints one row per declared credential.
$ mytool credentials list
name | service | account | mode | status
-----------+-----------+---------+------+--------
api-token | mytool | default | env | -
| Column | Value |
|---|---|
name |
The credential's declared name |
service / account |
From the keychain layer, or - when there is none |
mode |
The first configured layer: env, keychain, literal, fallback-env, or unconfigured |
status |
Always - |
mode is read off the config shape, not from a probe — list performs no I/O and
never touches the keychain. status is a placeholder column that is always -;
test and doctor are the subcommands that report real resolution status.
Honours --output json.
credentials test <NAME>¶
Probes one credential and prints where it resolved.
status |
Meaning |
|---|---|
resolved |
The resolver found a value; source names the layer |
missing |
No layer produced a value |
refused-in-ci |
Only a literal was available and the environment is CI |
error |
The keychain backend failed — locked store, OS-level error |
unknown |
A resolution outcome this version does not recognise |
Anything other than resolved prints the row and then fails the command with
credential `<NAME>` did not resolve. Honours --output json.
credentials doctor¶
test for every declared credential at once. Prints all rows, then fails with
one or more credentials did not resolve if any row is not resolved. Honours
--output json.
credentials add <NAME>¶
Prompts for a secret without echoing it, then stores it — if there is somewhere to store it.
| The credential declares | What add does |
|---|---|
A keychain layer |
Prompts, writes to the OS keychain under the declared service/account, prints a confirmation |
No keychain, but an env layer |
Prompts, discards the secret, and prints the export line you should run yourself |
Only a literal |
Refuses (see below) |
| Nothing settable | Fails with credential `<NAME>` has no env layer to populate |
add cannot set an environment variable for you¶
For an env-layer credential the wizard collects the secret and then throws it away:
set the secret in your shell:
export <the env var the credential declares>=...
(rtb-cli does not write to the calling shell's environment.)
A process cannot modify its parent shell's environment, and putting the secret into the running process's own environment would leak it to every child process. The prompt is still shown, which reads as if something was stored — nothing was.
add refuses a literal-only credential¶
with help edit your config to add an env or keychain layer first. Storing into a
layer the config does not declare would create a value the resolver never reaches.
credentials remove <NAME>¶
Deletes the credential from the OS keychain.
Removing a credential that is not in the keychain is not an error:
remove refuses to half-remove a literal¶
A credential with a literal and no keychain layer fails:
with help edit your config file to remove the literal value. Reporting success
while the secret stayed in the config file would be worse than refusing.
A credential with both a literal and a keychain layer is removed from the keychain only — the literal stays in the config file, and the resolver will keep finding it.
Ignores --output¶
add and remove are interactive and print prose, not rows. They accept
--output and ignore it.