Keyless VPS Deployments via GitHub Actions OIDC and Short-Lived SSH Certificates
Eliminate static private deployment keys in GitHub secrets by exchanging OpenID Connect JWT tokens for temporary signed SSH credentials.
Netbay Engineering
Netbay Engineering
On this page
Storing long-lived SSH private keys ('SSH_PRIVATE_KEY') inside GitHub repository secrets is an entrenched bad practice. If repository permissions are misconfigured, or if an untrusted pull request runs CI code, static deployment keys can be exfiltrated, granting persistent root or deployment access to your production servers indefinitely.
In 2026, the gold standard for secure deployment is Keyless OpenID Connect (OIDC) authentication paired with an automated SSH Certificate Authority (SSH CA).
Instead of storing private keys, GitHub Actions requests an ephemeral cryptographic JWT token. An internal CA gateway validates the token's claims and issues a signed, 5-minute SSH user certificate that automatically expires after deployment.
The OIDC SSH Certificate Exchange Workflow
Here is how keyless SSH authentication operates without static secrets:
- Workflow OIDC Token: GitHub Actions generates a cryptographically signed JSON Web Token (JWT) containing identity claims (repository, commit ref, workflow filename).
- Auth Gateway Validation: An authentication daemon (such as Smallstep CA or a lightweight Go service) validates GitHub's public JSON Web Key Set (JWKS).
- SSH CA Certificate Issuance: The gateway signs a temporary SSH public key submitted by the runner, generating a valid certificate with a strict 300-second validity window.
- Target Server Admission: OpenSSH on the target VPS trusts the CA public key ('TrustedUserCAKeys /etc/ssh/ca.pub') and admits the runner without needing authorized_keys modifications.
GitHub Actions Workflow Configuration
Configure 'id-token: write' to enable OIDC minting:
# .github/workflows/deploy.yml
name: Keyless Production Deploy
on:
push:
branches: [main]
permissions:
id-token: write # Mandatory for GitHub OIDC token generation
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Request OIDC Token and Mint SSH Certificate
run: |
# 1. Generate ephemeral local SSH key pair
ssh-keygen -t ed25519 -N "" -f id_deploy
# 2. Exchange GitHub OIDC token with Auth Gateway
ID_TOKEN=$(curl -sLS "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=netbay-deploy" -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" | jq -r .value)
# 3. Post public key + ID token to CA
curl -sX POST https://ca.example.in/v1/sign -H "Authorization: Bearer $ID_TOKEN" --data-binary @id_deploy.pub -o id_deploy-cert.pub
chmod 600 id_deploy id_deploy-cert.pub
- name: Execute Deploy over Keyless SSH
run: |
ssh -i id_deploy -o CertificateFile=id_deploy-cert.pub deploy@prod.example.in "
echo 'Authenticated with short-lived certificate!'
docker compose pull && docker compose up -d
"Configuring OpenSSH to Trust the CA
On the target VPS, add a single line to '/etc/ssh/sshd_config':
# /etc/ssh/sshd_config
TrustedUserCAKeys /etc/ssh/ca.pub
AuthorizedPrincipalsFile /etc/ssh/auth_principals/%uIn '/etc/ssh/auth_principals/deploy', specify that only certificates issued with the principal 'netbay-deployer' are allowed.
Video Guide on Git and Repository Secrets Management
Review modern Git workflow security and credential management techniques:
Transitioning to keyless OIDC deployments ensures that static credentials never enter your CI configuration, elevating supply chain defense.
Deploy to secure Linux VPS nodes on Netbay Cloud with advanced firewall and identity integration at netbayhosts.in.
Keep reading
Follow along on a real VPS
Deploy Linux in under 60 seconds
These guides are written against Ubuntu, Debian, and RHEL-family images — the same ones on NetBay.
Deploy an instance