monkeys

How it works

Where monkeys keeps a secret, how a command is handed one, how anything printed back is redacted, and what a .monsecrets bundle is made of.

A name, a secret and a command sit in three different places. Which one a thing is in decides who can read it.

holdswho can read it
your repository.monkeys: the key names, and the values that were never secretanyone with the repository
this machinethe vault: the secrets themselvesyou, and whatever runs as you
one commandboth, in its environmentthat command, while it runs

What each command moves

fromto
remembera promptthe vault, and the name into .monkeys
runthe vaultone command's environment
export—a lookup line for your shell
pack · unpackthe vaultan encrypted file, and back
forget · dropthe vaultgone

Nothing moves a secret to your screen, which is why there is no get.

What run does

Nothing reaches the command line, so your shell history and the process table see key names at most. The parent stays in front to read the output, and carries the command's exit status and signals back as its own.

What comes back

monkeys run OPENROUTER_API_KEY sh -c 'echo "key=$OPENROUTER_API_KEY"'
key=[redacted OPENROUTER_API_KEY]

Only what could still be the start of a secret is held back, so output is not buffered. A file the command opens itself never passes through monkeys.

The vault, and what it is not

A secret is one keychain item on macOS, filed under the service monkeys, and one Secret Service item on Linux. monkeys keeps nothing of its own anywhere, so there is no database to back up or leak.

Anything running as you can read that vault, the same way it can read your shell startup files. This takes secrets out of the repository, not out of reach; the caveats say where that line falls.

On this page