Secrets (kv)
An encrypted local store for the things you keep re-pasting: database passwords, API tokens, certificates, private key files.
It is age-backed, it lives beside your config, and it never writes a value to a log, an argv or the terminal unless you ask it to.
rta kv set db-password
rta kv get db-password
rta kv listChoosing the lock, once
A passphrase store needs no setup — that is what you get by default. Everything else is a one-time decision:
rta kv init --generate--generate makes a dedicated age key for this store and locks it to that. After it, nothing needs a flag and nothing needs typing: no passphrase, no --identity. And unlike your SSH login key, losing it costs you this store and nothing else.
rta kv init --identity ~/.ssh/id_ed25519 # a key you already have
rta kv init --recipient age1abc... # let somebody else read it too--identity accepts age or SSH keys. A passphrase-protected SSH key is asked for its passphrase the way ssh asks — ssh-agent cannot help here, because an agent signs and never decrypts.
RTA_KV_PASSPHRASE and RTA_KV_IDENTITY supply either without a flag, which keeps them out of shell history.
Storing things
rta kv set api-token # prompts, nothing in history
rta kv set tls-cert --file server.pem
rta kv set db-password --description "staging replica"rta detects what kind of thing it is — string, JSON, certificate, private key, SSH key, file — and kv list shows the kind and description without ever showing a value. --kind overrides the detection.
Getting them back
rta kv get db-password # to stdout
rta kv get tls-cert --out server.pem # to a file, at 0600
rta kv copy db-password # to the clipboard, never displayed
rta kv edit config-json # opens $EDITOR, re-encrypts on saveAnd for a whole shell environment:
eval "$(rta kv env --prefix APP_)"
rta kv env --format dotenv > .envSeeing the store without opening it
rta kv status
rta kv list
rta kv show db-password # everything about it except the value
rta kv recipients # which public keys can decrypt this storekv status answers "where is the store and what can open it" without unlocking it, which makes it safe to run anywhere — including in a script that is checking whether a machine is set up.
Changing the lock afterwards
rta kv rekey --recipient age1colleague... # add a reader
rta kv rekey --generate # move to a dedicated key
rta kv rekey --only --recipient age1me... # drop every other readerrekey always refuses to lock you out. That is not a courtesy — it is the difference between a key-rotation command you can use and one you use once.
What this means for agents
This is the part to read before connecting an MCP client.
kv.get is classified as a write, even though it only reads the store — revealing a secret is the sensitive act, not the lookup. An MCP agent needs --allow-write kv before it can even attempt the call, and on top of that the store still has to open, which is a separate question from calling the capability.
rta doctorkv store info unlocks from this environment — an MCP server started here
can read secrets, bounded only by grantsIf you locked the store with --generate or an identity that is available in your shell, then a server started from that shell can open it. That is not a bug; it is what "no passphrase to type" means. What bounds it is grants:
rta grant allow kv.get db-password --ttl 15m --max-uses 1Without a grant naming it, an agent's kv.get is refused and the refusal is written down.
Reach for --max-uses 1 here more than anywhere else. A secret an agent needs once is the clearest case in the whole model: one key, one read, then the grant is gone whether or not you remember it.
Two further bounds worth knowing:
requireScope: [kv.get]in a team policy makesrta grant allow kv.get— which would cover the entire store — an error. Only a grant naming one key is accepted.- Values are masked in the record.
rta agent logshows thatkv.get db-passwordhappened, not what came back.