·10 min read

SSH Certificates: Scaling Key Management for Enterprise Teams

Move beyond static SSH keys. Learn how SSH certificates enable time-limited access, role-based permissions, and centralized revocation for large teams.

SSHCertificatesEnterpriseSecurityCA

Traditional SSH key management works fine for individuals: generate a key pair, copy the public key to every server, and you're done. But at scale — dozens of servers, hundreds of developers, frequent onboarding and offboarding — this approach breaks down.

Enter SSH certificates: a standardized way to issue time-limited, role-based credentials signed by a trusted Certificate Authority (CA).

The Problem with Static Keys

Consider a typical startup scenario:

  • 50 developers
  • 200 production servers
  • Developers join and leave monthly
  • Servers are provisioned and decommissioned weekly

With static keys, every change requires:

  1. Onboarding: Copy the new developer's public key to all 200 servers
  2. Offboarding: Remove the departing developer's key from all 200 servers
  3. Rotation: Periodically regenerate all keys and redistribute them

This is error-prone, slow, and doesn't scale.

How SSH Certificates Work

SSH certificates solve these problems by introducing a Certificate Authority (CA):

Traditional Flow (Static Keys)

Developer → Public Key → Copied to Every Server

Certificate Flow

Developer → Public Key → CA Signs Certificate → Server Trusts CA → Access Granted

The server only needs to trust the CA's public key. When a developer presents a certificate, the server verifies it was signed by the CA and grants access accordingly.

Certificate Components

An SSH certificate contains:

  • Public key — The user's or host's key
  • Identity — Username or hostname
  • Valid principals — Which usernames this cert allows
  • Validity period — Start and end timestamps
  • Extensions — Permissions (e.g., can forward ports, can use agent)
  • Critical options — Restrictions (e.g., source IP, command whitelist)
  • Signature — Signed by the CA

Setting Up an SSH CA

Step 1: Generate CA Keys

# Generate CA key pair
ssh-keygen -t ed25519 -f ca_key -C "SSH CA Key"

# This creates:
# ca_key     (private key — keep secure!)
# ca_key.pub (public key — distribute to servers)

Step 2: Configure Servers to Trust the CA

On each server, add the CA's public key to sshd_config:

# /etc/ssh/sshd_config
TrustedUserCAKeys /etc/ssh/ca_key.pub

Restart sshd:

sudo systemctl restart sshd

Now any certificate signed by this CA will be accepted.

Step 3: Issue User Certificates

# Sign a user's public key
ssh-keygen -s ca_key \
  -I alice@company.com \
  -n alice,deployer \
  -V +1w \
  -O clear \
  -O permit-port-forwarding \
  -O permit-agent-forwarding \
  alice_id_ed25519.pub

# This creates: alice_id_ed25519-cert.pub

Flags explained:

  • -I: Identity (logged in auth logs)
  • -n: Valid principals (usernames this cert allows)
  • -V: Validity period (+1w = one week from now)
  • -O clear: Remove default extensions
  • -O permit-*: Explicitly allow features

Step 4: Connect with the Certificate

ssh -i ~/.ssh/alice_id_ed25519 alice@server.example.com

SSH automatically uses the -cert.pub file alongside the private key.

Time-Limited Access

One of the biggest advantages of certificates is automatic expiration.

Issue a certificate valid for 8 hours:

ssh-keygen -s ca_key \
  -I bob@company.com \
  -n bob \
  -V +8h \
  bob_id_ed25519.pub

After 8 hours, the certificate is invalid. No need to manually revoke anything — the server rejects expired certificates automatically.

This is perfect for:

  • Contractors: Issue certs matching contract duration
  • Incident response: Grant temporary emergency access
  • Audits: Ensure all access has an expiration date

Role-Based Certificates

Different roles need different permissions. Create separate CA signing keys for each role:

Developer Certificate

ssh-keygen -s ca_key_dev \
  -I "dev-${USER}" \
  -n "${USER}" \
  -V +1w \
  -O clear \
  -O permit-port-forwarding \
  -O permit-agent-forwarding \
  dev_key.pub

Deployer Certificate

ssh-keygen -s ca_key_deploy \
  -I "deploy-${USER}" \
  -n deployer \
  -V +24h \
  -O clear \
  -O permit-port-forwarding \
  -O force-command=/usr/local/bin/deploy.sh \
  deploy_key.pub

The force-command option restricts the deployer to running only the deployment script.

Admin Certificate

ssh-keygen -s ca_key_admin \
  -I "admin-${USER}" \
  -n root,admin,"${USER}" \
  -V +4h \
  -O clear \
  -O permit-port-forwarding \
  -O permit-agent-forwarding \
  -O permit-pty \
  admin_key.pub

Admin certs have shorter validity and broader access.

Host Certificates

So far we've discussed user certificates (proving who you are). SSH also supports host certificates (proving the server is legitimate).

Why Host Certificates Matter

Without host certificates, SSH relies on the known_hosts file to verify server identity. This leads to:

  • TOFU (Trust On First Use): Blindly accepting the first connection
  • MITM risk: An attacker could intercept the initial connection
  • Key rotation pain: Updating known_hosts when servers change

Host certificates solve this by having servers present certificates signed by a trusted CA.

Setting Up Host Certificates

# Sign a host's public key
ssh-keygen -s ca_key_host \
  -I "prod-web-01.company.com" \
  -h \
  -n prod-web-01.company.com,10.0.1.100 \
  -V +52w \
  /etc/ssh/ssh_host_ed25519_key.pub

# This creates: /etc/ssh/ssh_host_ed25519_key-cert.pub

The -h flag indicates this is a host certificate.

Configure sshd to use it:

# /etc/ssh/sshd_config
HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub

Clients trust the host CA:

# ~/.ssh/config
GlobalKnownHostsFile /etc/ssh/known_hosts_ca

Now clients automatically verify server certificates without manual known_hosts management.

Certificate Revocation

Sometimes you need to revoke a certificate before it expires (e.g., employee termination, compromised key).

Method 1: KRL (Key Revocation List)

Generate a revocation list:

ssh-keygen -k -f revoked_keys.krl ca_key.pub user_cert_to_revoke.pub

Configure sshd to check the KRL:

# /etc/ssh/sshd_config
RevokedKeys /etc/ssh/revoked_keys.krl

Update the KRL whenever you revoke certificates.

Method 2: Short Validity Periods

The simplest revocation strategy: issue certificates with very short validity (e.g., 1 hour). If you need to revoke access, just don't renew the certificate.

This requires an automated certificate issuance system but eliminates the complexity of KRLs.

Automated Certificate Issuance

For large teams, manual certificate signing doesn't scale. Build an automated system:

Architecture

Developer → Auth System (SSO/MFA) → Certificate API → CA Signs → Returns Cert

Example Flow

  1. Developer authenticates via SSO (Okta, Google Workspace)
  2. Backend verifies identity and role
  3. Backend calls ssh-keygen -s or uses a library like golang.org/x/crypto/ssh
  4. Returns signed certificate to developer's SSH agent
  5. Developer connects to servers using the cert

Tools

Several open-source tools automate this:

  • Teleport: Full SSH certificate management platform
  • HashiCorp Vault: SSH secrets engine with certificate signing
  • Smallstep: Modern PKI with SSH certificate support
  • Certstrap: Simple self-hosted SSH CA

FoxTerm Integration

FoxTerm Pro includes built-in SSH certificate support:

Import CA-Signed Certificates

If your organization issues SSH certificates, import them into FoxTerm:

  1. Go to Settings → SSH Keys
  2. Click "Import Certificate"
  3. Select your private key and certificate files
  4. FoxTerm automatically uses the certificate for authentication

Automatic Certificate Renewal

FoxTerm can integrate with your certificate API to automatically renew certificates before they expire. Configure:

  • Certificate endpoint URL
  • Authentication method (API key, OAuth token)
  • Renewal interval (e.g., every 6 hours)

FoxTerm handles the rest — you always have a valid certificate.

Host Certificate Verification

FoxTerm verifies host certificates automatically. If a server presents an invalid or expired certificate, FoxTerm warns you before connecting.

Migration Strategy

Moving from static keys to certificates? Here's a phased approach:

Phase 1: Set Up CA (Week 1)

  • Generate CA keys
  • Configure servers to trust the CA
  • Test with a single user

Phase 2: Dual Authentication (Weeks 2-4)

  • Issue certificates to pilot users
  • Keep static keys as fallback
  • Monitor auth logs for issues

Phase 3: Full Migration (Weeks 5-8)

  • Issue certificates to all users
  • Remove static keys from servers
  • Document certificate workflows

Phase 4: Automation (Weeks 9-12)

  • Build automated certificate issuance
  • Integrate with SSO
  • Set up monitoring and alerting

Best Practices

Security

  • Protect the CA private key: Store in HSM or offline cold storage
  • Use short validity periods: 8 hours for users, 52 weeks for hosts
  • Separate CAs per environment: Dev, staging, prod should have different CAs
  • Audit certificate issuance: Log every certificate signed

Operations

  • Automate everything: Manual signing doesn't scale
  • Monitor expiration: Alert before certificates expire
  • Test revocation: Regularly verify that revoked certs are rejected
  • Document procedures: Onboarding, offboarding, emergency access

Development

  • Use strong key types: Ed25519 or RSA 4096+
  • Include meaningful identities: Use email addresses or employee IDs
  • Limit principals: Only include necessary usernames
  • Restrict extensions: Only permit what's needed

Conclusion

SSH certificates transform key management from a manual chore into an automated, secure, scalable system. They enable:

  • Time-limited access: No more stale keys
  • Role-based permissions: Different access for different roles
  • Centralized revocation: Revoke access instantly
  • Host verification: Prevent MITM attacks
  • Audit trails: Know who accessed what and when

For teams larger than a handful of developers, SSH certificates are not optional — they're essential infrastructure.


FoxTerm Pro supports SSH certificates out of the box. Download at foxterm.app.