Back to Blog
TutorialNovember 28, 202415 min read

Certificate-Based SSH: A Complete Guide

SSH keys are everywhere, but they're a security nightmare. Learn how to replace them with short-lived certificates for better security, simplified operations, and complete audit trails.

Marcus Johnson
Senior DevOps Engineer

The SSH Key Problem

SSH keys have been the standard for server authentication for decades. Generate a key pair, copy the public key to authorized_keys, and you're done. Simple, right?

Except it's not. SSH keys create massive operational and security problems:

Security Issues

  • • Keys never expire
  • • No centralized revocation
  • • Lost keys = lost control
  • • No audit trail of usage
  • • Shared keys spread across teams

Operational Headaches

  • • Key distribution is manual
  • • authorized_keys sprawl
  • • No offboarding process
  • • Unknown key inventory
  • • Break-glass access impossible

I've seen production environments with hundreds of orphaned SSH keys in authorized_keys files. Nobody knows who generated them, when, or if they're still needed. And when someone leaves the company? Good luck finding and removing all their keys across hundreds of servers.

How SSH Certificates Work

SSH certificates solve these problems by introducing a certificate authority (CA) that signs short-lived credentials. Instead of distributing public keys to every server, you configure servers to trust the CA. The CA then issues certificates to users that are automatically trusted by all servers.

How It Works

  1. 1.Configure servers to trust CA: Add CA public key to sshd_config once
  2. 2.User authenticates to CA: Prove identity with SSO, MFA, device trust
  3. 3.CA issues certificate: Short-lived (4-12 hours) with metadata embedded
  4. 4.User connects with certificate: SSH server verifies CA signature
  5. 5.Certificate expires: No cleanup, no revocation lists to maintain

Setting Up TigerAccess SSH CA

Let's walk through a complete implementation using TigerAccess. We'll start with a single server and expand to fleet-wide deployment.

Step 1: Install TigerAccess

# Install TigerAccess on your auth server
curl -fsSL https://get.tigeraccess.io | bash

# Start auth service (certificate authority)
tigeraccess start --roles=auth

# The CA generates signing keys automatically
# Public key: /var/lib/tigeraccess/ca/user_ca.pub
# You'll need this for server configuration

Step 2: Configure SSH Servers

Each SSH server needs to trust the CA. Add this to /etc/ssh/sshd_config:

# Trust TigerAccess CA for user certificates
TrustedUserCAKeys /etc/ssh/tigeraccess_ca.pub

# Require certificate authentication
PubkeyAuthentication yes
AuthorizedKeysFile none  # Disable authorized_keys

# Optional: Require specific certificate principals
# AuthorizedPrincipalsFile /etc/ssh/authorized_principals/%u

# Restart SSH to apply changes
sudo systemctl restart sshd

Copy the CA public key to all servers:

# Copy CA public key to each server
scp /var/lib/tigeraccess/ca/user_ca.pub \
    user@server:/etc/ssh/tigeraccess_ca.pub

# Or use configuration management
# Ansible example:
- name: Configure SSH certificate authentication
  copy:
    src: tigeraccess_ca.pub
    dest: /etc/ssh/tigeraccess_ca.pub
    owner: root
    group: root
    mode: '0644'

Step 3: User Authentication Flow

Now users can get certificates instead of managing SSH keys:

# User installs TigerAccess client
brew install tigeraccess  # macOS
# or
curl -fsSL https://get.tigeraccess.io/client | bash  # Linux

# Configure auth server
tac config set auth-server https://tigeraccess.company.com

# Login with SSO (triggers OAuth flow)
tac login
# Opens browser -> SSO login -> MFA challenge -> Success

# TigerAccess issues certificate (default 8h TTL)
# Certificate stored in ~/.tigeraccess/keys/

# Connect to servers - no SSH keys needed!
tac ssh user@production-server

# Or use regular ssh with certificate
ssh -i ~/.tigeraccess/keys/user-cert.pub user@server

Certificate Metadata and Principals

SSH certificates can embed metadata that servers use for authorization decisions. The most important field is principals—the list of usernames the certificate holder can authenticate as.

# Issue certificate with specific principals
# User alice@company.com gets certificate for Unix users: alice, deploy
tacctl user cert issue alice@company.com \
  --principals=alice,deploy \
  --ttl=4h

# View certificate details
ssh-keygen -L -f ~/.tigeraccess/keys/user-cert.pub

# Output:
Type: ssh-rsa-cert-v01@openssh.com user certificate
Public key: RSA-CERT SHA256:abc123...
Signing CA: RSA SHA256:def456...
Key ID: "alice@company.com"
Serial: 1234567890
Valid: from 2024-11-28T10:00:00 to 2024-11-28T14:00:00
Principals:
        alice
        deploy
Extensions:
        permit-pty
        permit-port-forwarding

Server-Side Principal Validation

Servers can require specific principals for different users:

# /etc/ssh/sshd_config
AuthorizedPrincipalsFile /etc/ssh/authorized_principals/%u

# /etc/ssh/authorized_principals/deploy
# Only allow certificates with "deploy" principal to login as deploy user
deploy
ci-bot

# /etc/ssh/authorized_principals/alice
# Allow alice to login as herself
alice

Advanced: Role-Based Access Control

TigerAccess can issue certificates based on RBAC roles, allowing dynamic principal assignment:

# Define roles in TigerAccess
tacctl roles create developer \
  --allow-login=alice,bob,charlie \
  --allow-nodes='env=dev'

tacctl roles create sre \
  --allow-login=root,admin \
  --allow-nodes='env=prod' \
  --require-approval=true

# Assign users to roles
tacctl users add-role alice@company.com developer
tacctl users add-role bob@company.com sre

# When alice logs in, she gets certificate with principals: alice
# When bob logs in, he gets principals: root,admin
# But bob needs approval for prod access (JIT workflow)

Session Recording

One of the biggest advantages of proxied SSH access is complete session recording for compliance and forensics:

# Enable session recording in TigerAccess config
# /etc/tigeraccess/config.yaml
ssh:
  recording:
    enabled: true
    mode: node  # Record at proxy level
    storage: s3://company-sessions/

# All SSH sessions are now recorded
# View recorded session
tacctl sessions ls

# Output:
ID       USER    NODE         START                DURATION
abc123   alice   prod-web-1   2024-11-28 10:15:00  45m 23s
def456   bob     prod-db-1    2024-11-28 11:00:00  12m 05s

# Replay session
tacctl sessions play abc123
# Opens terminal player with full session replay

Emergency Access and Break-Glass

Certificate-based access makes emergency scenarios easier, not harder:

# Emergency access during auth server outage
# Generate temporary certificate manually on auth server
tigeraccess cert issue emergency-admin \
  --principals=root \
  --ttl=1h \
  --out=/tmp/emergency-cert.pub

# Copy to engineer's machine
scp /tmp/emergency-cert.pub engineer@laptop:/tmp/

# Engineer uses emergency certificate
ssh -i /tmp/emergency-cert.pub root@server

# Full audit trail:
# - Who issued emergency cert
# - Who used it
# - What commands executed
# - When certificate expires

Fleet-Wide Rollout Strategy

Rolling out certificate-based SSH across hundreds or thousands of servers requires planning. Here's the strategy we recommend:

Rollout Phases

Phase 1: Dual Mode (Week 1-2)

Enable both SSH keys and certificates:

TrustedUserCAKeys /etc/ssh/tigeraccess_ca.pub
AuthorizedKeysFile .ssh/authorized_keys  # Still works

Users can choose which method to use. Monitor adoption.

Phase 2: Certificate Primary (Week 3-4)

Make certificates the default, keys fallback:

  • • Train users on tac ssh workflow
  • • Document emergency procedures
  • • Monitor certificate issuance rates

Phase 3: Certificate Only (Week 5+)

Disable SSH keys completely:

AuthorizedKeysFile none  # Keys disabled

All access via certificates. Clean up authorized_keys files.

Troubleshooting Common Issues

Certificate not accepted by server

# Debug SSH connection with verbose output
ssh -vvv -i ~/.tigeraccess/keys/user-cert.pub user@server

# Common issues:
# 1. Wrong principals (certificate has "alice", connecting as "root")
#    Solution: Request cert with correct principals

# 2. Certificate expired
#    Solution: tac login to get new certificate

# 3. Server doesn't trust CA
#    Solution: Verify TrustedUserCAKeys in sshd_config

# 4. Clock skew between CA and server
#    Solution: Sync NTP on all systems

Permission denied despite valid certificate

# Check server logs
sudo journalctl -u sshd -f

# Common causes:
# - AuthorizedPrincipalsFile doesn't include principal
# - File permissions on authorized_principals
# - Certificate extensions (permit-pty) restricted

# Verify certificate principals match
ssh-keygen -L -f ~/.tigeraccess/keys/user-cert.pub | grep Principals

Security Best Practices

  • Keep TTLs short: 4-8 hours for regular users, 1 hour for privileged access
  • Require MFA: Always require MFA for certificate issuance
  • Protect the CA: CA signing keys should be hardware-backed (HSM or KMS)
  • Monitor certificate issuance: Alert on unusual patterns or after-hours requests
  • Regular key rotation: Rotate CA keys annually with proper planning
  • Backup and recovery: Document CA key recovery procedures

Measuring Success

After implementing certificate-based SSH, you should see:

Security Improvements

  • • Zero long-lived credentials
  • • 100% audit coverage
  • • Instant offboarding
  • • MFA on all access
  • • Complete session recordings

Operational Wins

  • • No key distribution
  • • No authorized_keys sprawl
  • • Automatic expiration
  • • SSO integration
  • • Self-service access

Conclusion

SSH certificates aren't new—OpenSSH has supported them since 2010. But adoption has been slow because the tooling was complex and the benefits weren't obvious until you dealt with key sprawl at scale.

TigerAccess makes certificate-based SSH simple: install the agent, configure the CA, and your users get secure, auditable access without managing keys. The security benefits alone justify the migration, but the operational simplification is what makes teams wish they'd done it sooner.

Stop managing SSH keys. Start issuing certificates.

About Marcus Johnson

Marcus is a Senior DevOps Engineer at TigerAccess with 10+ years managing SSH infrastructure at companies ranging from startups to Fortune 100. He's migrated over 50,000 servers from SSH keys to certificate-based authentication.

Ready to Secure Your Infrastructure?

Join thousands of security-conscious teams using TigerAccess to protect their critical infrastructure and AI agents.

No credit card required • 14-day free trial • Enterprise support available