Lets an agent authenticate to APIs and MCP servers WITHOUT ever seeing secret values. Use whenever a task needs an API token, MCP token, password, or key. The agent passes a credential *reference* (a name); a trusted non-LLM broker resolves it from the OS keyring, injects it into the request, scrubs the response, and returns only scrubbed output. The secret value never enters the agent's context or the LLM.
68
81%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
You never possess a secret value. You only pass references (names).
A secret must never enter the model's context window. Do not read secret files, do not print values, do not reconstruct them. To authenticate, you emit a credential reference by name and let a trusted, non-LLM broker resolve→inject→scrub. This is architectural, not advisory: the value stays inside the broker process and is never returned to you.
Secrets live in the OS keyring (Keychain / libsecret / Windows Credential Manager). They are stored out-of-band by a human, e.g.:
keyring set agent-secrets github_token
keyring set agent-secrets openai_api_keyYou reference them by name only — e.g. github_token. You never see the value.
Use this for all API and MCP token use. The broker resolves the named credential, injects it into the request header, performs the call, scrubs the response, and returns only the scrubbed body. The secret exists only inside the broker process for the duration of one request.
python3 scripts/keyring_broker.py request \
--name github_token \
--url https://api.github.com/user \
--header "Authorization: Bearer {secret}"--name is a reference, never a value.{secret} is a placeholder the broker fills internally; you never type the token.For MCP servers: put the credential in the MCP server's environment/config,
resolved by the client runtime — never in tool arguments, conversation, or files.
Prefer OAuth flows where the server holds the token and the client gets a
short-lived, scoped handle. Use ${input:...}/env indirection so no literal
appears in committed config.
Only when a legacy CLI can read a credential solely from its environment and (a) is impossible. The broker injects the value into a single child process's environment (never yours), runs one command, and scrubs its output.
python3 scripts/keyring_broker.py exec \
--name aws_secret_access_key \
--env-var AWS_SECRET_ACCESS_KEY \
-- aws s3 lsWhy discouraged: the value lives in the child's /proc/<pid>/environ for the
process lifetime and is exposed to any subprocess it spawns and to verbose/debug
output you cannot fully control. Scope it to one invocation; never persist it;
never export it into your own shell.
.env, .env.*, .netrc, .npmrc, .pypirc, *.pem, *.key, id_rsa, credentials, kubeconfig, .git-credentials, or any *secret*/*credential*/*password* file to "get the token". Decline and use the broker.keyring set agent-secrets <name> themselves — never handle the value yourself.These are enforced outside the model and assumed by this skill:
scripts/keyring_broker.py implements both mechanisms. The secret value is never
written to stdout/stderr, never logged, and never returned to the caller.
d41d8d9
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.