TILLSECRETS · SSH AGENT

Your SSH key, used but never copied out

Beta

An SSH key usually sits in ~/.ssh, often with no passphrase, readable by anything running as you. tilldev ssh agent is an SSH agent whose keys stay in TillSecrets. ssh, git and an AI session ask it for signatures as they would any agent. The vault signs, and each use waits for your approval or is allowed for a time you choose. The private key is never written to your machine.

01Keys

Make a key in the vault, or move one in

keygen makes an ed25519 key (or RSA with --type rsa) inside the vault and prints the public half for a server's authorized_keys or your Git host. import stores a key you already have: ed25519, RSA or ECDSA, in OpenSSH or PEM format. For a key with a passphrase, ssh-keygen asks for it and opens a copy in a private temporary folder, which is deleted straight after. --remove deletes the file only once the vault holds the same key.

terminal
# Make a key in the vault. The private half is made there and never reaches this machine.
$ tilldev ssh keygen infra/prod/DEPLOY_KEY
OK Made secretref://infra/prod/DEPLOY_KEY — the private key was made in the vault and never reached this machine
type         ssh-ed25519
fingerprint  SHA256:q0Hc…
public key (for ~/.ssh/authorized_keys on a server, or your Git host):
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA… secretref://infra/prod/DEPLOY_KEY

# Or move a key you already have. A key with a passphrase asks for it once.
$ tilldev ssh import infra/prod/DEPLOY_KEY --file ~/.ssh/id_ed25519 --remove

Signing needs the same access as revealing the key: admin, or owner for a restricted secret (sensitivity 7 and up). Keygen and import add the key to the agent unless you pass --no-add.

02Agent

Run it and point ssh at it

config --write adds an IdentityAgent block at the top of ~/.ssh/config, so ssh uses the agent without changing your shell. Running it again replaces the block. install starts the agent at login with launchd on macOS or systemd on Linux.

terminal
tilldev ssh config --write     # point ssh at the agent (add --host github.com to limit it)
tilldev ssh install            # run the agent now and at every login

# Or run it in the foreground and watch it:
$ tilldev ssh agent
OK SSH agent on ~/.tilldev/ssh-agent.sock (1 key)
*   SHA256:q0Hc… secretref://infra/prod/DEPLOY_KEY

The socket is readable only by you (mode 0600, in a 0700 folder). On Windows the agent listens on the named pipe \\.\pipe\tilldev-ssh-agent; start it from a scheduled task at log-on.

manage
tilldev ssh ls                  # keys the agent offers, with fingerprints
tilldev ssh add <project>/<env>/<KEY>
tilldev ssh rm <project>/<env>/<KEY>      # stop offering it; the key stays in the vault
tilldev ssh keygen <ref> --rotate          # a new key under the same name
tilldev ssh uninstall                      # stop starting it at login
03Approvals

Each use asks you, or is allowed for a while

When ssh asks for a signature, the agent sends it to the vault, which reads what is being signed and asks you to approve exactly that. Your browser opens the approval page; approve with a passkey, your phone or a confirmed authenticator code.

terminal
$ ssh deploy@build-01.example.com
# in the agent's log, and your browser opens the approval page:
12:04:31 Needs your approval: Sign in to build-01.example.com (SHA256:7Yh…) as deploy with DEPLOY_KEY (infra/prod)
    https://tilldev.dev/acme/approve/5b0c…
12:04:39 Signed with secretref://infra/prod/DEPLOY_KEY (approved)
What is signedAsks forCan repeat
A login to a server your SSH client proved (OpenSSH 8.9 and later)ssh.sign15 minutes to 7 days, for that key, server and user
A git commit or tag, or another ssh-keygen -Y sign signaturessh.sign15 minutes to 7 days, for that key and namespace
A login where the client did not prove the serverssh.sign_onceNo. One signature, of those exact bytes
Anything asked through an agent forwarded to another machinessh.sign_onceNo
Data that is neither a login nor a signaturessh.sign_onceNo

The server is named from its host key's own signature, checked in the vault, and from your known_hosts for a readable name. A login for a different key, or to a server other than the one the connection proved, is refused outright.

What a repeat allows
The vault cannot tell which program on your machine asked the agent. While a repeat is open, anything that can reach the socket can sign the same kind of thing again without asking. Keep windows short, and never allow a repeat on a machine you do not trust. Approvals → Allowed to repeat stops one at once.

A server waits about two minutes for a login. If you approve after it gives up, run the command again: for a proven server the approval you gave still applies. A single-use approval covers one exact signature, so the retry asks again.

04Git

Sign commits and tags

tilldev ssh git sets git to sign with the vault key through the agent, for this repository or with --global for all of them. --sign-all signs every commit and tag. Allow ssh.sign for the git namespace for a working day and commits go straight through.

terminal
tilldev ssh git infra/prod/DEPLOY_KEY --global --sign-all
git commit -m "Ship it"          # signed through the agent
tilldev ssh ls --public          # the line to add at your Git host as a signing key

# On TillForge, so the commits show as verified:
tilldev forge signing-key add --key "$(tilldev ssh ls --public | head -n 1)" --title "vault key"
05AI sessions

Let an agent use the key

An AI session on your machine uses the agent like ssh does, through SSH_AUTH_SOCK or your ssh config. It never holds the key, and each use still waits for you. To keep the session off your own login, run a separate agent with an agent token whose patterns include the key. Its approvals go to the person who made the token, and each signature counts against the token's daily budget.

agent host
# Where the AI session runs. Its token's patterns must include the key.
export TILLDEV_AGENT_TOKEN="$(cat deploy-bot.token)"
tilldev ssh agent --key infra/prod/DEPLOY_KEY --socket ~/.tilldev/deploy-bot.sock --no-open &
export SSH_AUTH_SOCK=~/.tilldev/deploy-bot.sock
ssh deploy@build-01.example.com   # the approval goes to the person who made the token
06Limits

What it does not do

  • No keys from outside. ssh-add is refused; the agent offers only vault keys. Use tilldev ssh import.
  • RSA with SHA-2 only. A server that asks for an ssh-rsa (SHA-1) signature is refused.
  • Online. Every signature is made in the vault, so the agent needs a connection.
  • On the record. Each signature is in the broker ledger with the server or namespace, and each approval is in the audit log.