Configuring HashiCorp Vault as SSH Certificate Authority
Centralize SSH access control with signed certificates and time-based access
Securely controlling SSH access to your servers is critical. HashiCorp Vault can act as a central SSH Certificate Authority (CA), allowing you to issue signed user keys, enforce TTLs, and avoid distributing static SSH keys across your infrastructure.
This guide demonstrates how to configure Vault as an SSH CA and automate certificate distribution using cloud-init for scalable, secure SSH access management.
Prerequisites
- HashiCorp Vault installed and running
- Linux Virtual Machine or cloud environment
- Access to Vault with administrative privileges
- Basic understanding of SSH key authentication
Step 1: Enable the SSH Secrets Engine
Enable the SSH engine at a chosen mount point:
vault secrets enable -path=ssh ssh
What this does:
- The
sshmount point manages Vault’s SSH CA and key signing - Vault will generate its own internal SSH CA key for signing user keys
Step 2: Generate the Vault SSH CA Key
vault write ssh/config/ca generate_signing_key=true
Security Benefits:
- Vault now holds an internal SSH CA key
- The private key stays in Vault, ensuring secure signing
- No private key material leaves the Vault environment
Step 3: Extract the SSH CA Public Key
vault read -field=public_key ssh/config/ca > vault-ca.pub
This creates a single vault-ca.pub file that needs to be distributed to your servers. This public key allows your servers to verify certificates signed by Vault’s CA.
Automating CA Distribution with Cloud-Init
Instead of manually copying the public key to each server, you can automate this process using cloud-init. The following example demonstrates this using Proxmox – you’ll need to adapt this approach for your specific hypervisor or cloud platform.
Platform Note: This example uses Proxmox’s snippet functionality. For other platforms like VMware vSphere, AWS, Azure, or GCP, consult your platform’s cloud-init documentation for the equivalent method of injecting custom configuration during VM provisioning.
Example Cloud-Init Snippet (Proxmox)
# user-data.yaml
users:
- name: user
passwd: $6$rounds=4096$salt$hashedpassword
lock_passwd: false
ssh_authorized_keys:
- ssh-ed25519 AAAAC3... user@workstation
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
- name: ansible
ssh_authorized_keys:
- ssh-ed25519 AAAAC3... ansible@controller
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
package_update: true
package_upgrade: true
write_files:
- path: /etc/ssh/vault-ca.pub
content: |
ssh-rsa AAAAB3NzaC1... (your vault CA public key)
permissions: '0644'
bootcmd:
- echo "TrustedUserCAKeys /etc/ssh/vault-ca.pub" >> /etc/ssh/sshd_config
runcmd:
- systemctl restart ssh
Apply to Proxmox Template
# Assuming your cloud image template has ID 1000
qm set 1000 --cicustom "user=local:snippets/user-data.yaml"
Note: This method doesn’t mesh well with Cloud-Init GUI configuration. Either use snippets to configure your cloud images, or use the GUI and handle additional configurations through Ansible or other configuration management tools.
Step 4: Create Role and Sign SSH Keys
Define an SSH Role
Create a role that controls which users can request signed certificates and sets TTL limits:
vault write ssh/roles/dev-role \
key_type=ca \
allow_user_certificates=true \
allowed_users="ansible,darnell" \
default_user="ansible" \
ttl="1h" \
max_ttl="24h"
Generate and Sign SSH Keys
Generate a new SSH key pair:
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_demo
Sign the public key for the ansible user:
vault write -field=signed_key ssh/sign/dev-role \
public_key=@$HOME/.ssh/id_ed25519_demo.pub \
username=ansible \
> $HOME/.ssh/id_ed25519_demo-cert.pub
Set appropriate permissions:
chmod 600 ~/.ssh/id_ed25519_demo
chmod 644 ~/.ssh/id_ed25519_demo-cert.pub
Test SSH Access
Test SSH access using the signed certificate:
ssh -i ~/.ssh/id_ed25519_demo -i ~/.ssh/id_ed25519_demo-cert.pub ansible@your-server
Verify Certificate Details
Inspect the signed certificate to verify its properties:
# View certificate details
ssh-keygen -L -f ~/.ssh/id_ed25519_demo-cert.pub
# Check certificate validity period
ssh-keygen -L -f ~/.ssh/id_ed25519_demo-cert.pub | grep "Valid:"
Security Benefits
Time-Limited Access
- Certificates automatically expire
- No need to revoke individual keys
- Configurable TTL limits
Centralized Control
- Single point of access management
- Audit trail in Vault logs
- Policy-based access control
Eliminates Static Keys
- No permanent keys in authorized_keys
- Dynamic certificate generation
- Reduced attack surface
Conclusion
Using HashiCorp Vault as an SSH Certificate Authority provides a scalable, secure approach to SSH access management. The combination of time-limited certificates, centralized control, and automated distribution via cloud-init creates a robust security model for modern infrastructure.
This approach eliminates the need to manage static SSH keys across your infrastructure while providing comprehensive audit trails and policy-based access controls through Vault’s authentication and authorization mechanisms.
Next Steps: Consider implementing Vault authentication methods (LDAP, OIDC) to tie SSH certificate generation to your existing identity management systems for even more secure and auditable access control.
