ssh-agent and ssh-add in CI Pipelines
ssh-agent runs a background process that holds your private keys; ssh-add loads keys into it so ssh, scp, and git use them automatically.
An agent keeps the private key out of files that later steps might leak and serves it to every SSH command in the job. In GitHub Actions the webfactory/ssh-agent action wraps this pattern.
What it does
ssh-agent starts and prints the environment variables (SSH_AUTH_SOCK, SSH_AGENT_PID) that connect clients to it. eval-ing that output exports them into the shell. ssh-add then loads a key into the running agent, after which ssh and scp authenticate without -i.
Common usage
eval "$(ssh-agent -s)"
ssh-add ./deploy_key # or: ssh-add - <<< "$DEPLOY_KEY"
ssh user@host "deploy.sh"GitHub Actions (webfactory/ssh-agent)
- uses: webfactory/ssh-agent@v0.9.0
with:
ssh-private-key: ${{ secrets.DEPLOY_KEY }}
- run: |
ssh-keyscan host >> ~/.ssh/known_hosts
ssh user@host "deploy.sh"In CI
The webfactory/ssh-agent action starts an agent and loads the key from a secret for the whole job, so subsequent ssh, scp, and git steps just work. You still seed known_hosts yourself with ssh-keyscan. The agent keeps the key in memory rather than on disk, which is safer than an -i key file.
Common errors in CI
Could not open a connection to your authentication agent. means SSH_AUTH_SOCK is not exported; you forgot to eval the ssh-agent output, or it ran in a different shell. "Error loading key: invalid format" from ssh-add means a corrupted or truncated key secret. With the agent loaded but the wrong key offered, add -o IdentitiesOnly=yes and -i to pin the key.