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.Configure servers to trust CA: Add CA public key to sshd_config once
- 2.User authenticates to CA: Prove identity with SSO, MFA, device trust
- 3.CA issues certificate: Short-lived (4-12 hours) with metadata embedded
- 4.User connects with certificate: SSH server verifies CA signature
- 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 configurationStep 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 sshdCopy 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@serverCertificate 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-forwardingServer-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
aliceAdvanced: 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 replayEmergency 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 expiresFleet-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 worksUsers 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 sshworkflow - • Document emergency procedures
- • Monitor certificate issuance rates
Phase 3: Certificate Only (Week 5+)
Disable SSH keys completely:
AuthorizedKeysFile none # Keys disabledAll 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 systemsPermission 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 PrincipalsSecurity 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.