☀️ Light Mode

Managing SSH Certificates with HashiCorp Vault

hashicorp vault ssh key management
Configuring HashiCorp Vault as SSH Certificate Authority

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 ssh mount 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.

Managing SSH Certificates with HashiCorp Vault
Managing SSH Certificates with HashiCorp Vault

Tags:

NAXS Labs
Logo