← All posts
Series BeaconSSH Series — Part 4 of 6

Short-Lived Credentials and the Future of SSH Access

·
beaconsshsshsecuritypki

Static SSH keys don’t expire. That sentence should concern anyone operating infrastructure at scale.

A key generated three years ago by an engineer who left the company two years ago may still grant access to production servers. Nobody remembers adding it. Nobody audited it. It just sits in authorized_keys, quietly waiting.

This post explains why BeaconSSH uses short-lived certificates and how that decision cascades through the entire security model.

The Problem with Static Keys

SSH keys have no built-in expiry. Once a key is added to authorized_keys, it remains valid until someone manually removes it. In practice, this means:

  • Keys accumulate. Every new engineer, every CI system, every automation script adds keys. Removal requires coordination nobody prioritizes.
  • Ownership becomes unclear. Which key belongs to whom? The filename might hint at it, or it might say id_rsa.pub.
  • Revocation requires touching every host. To revoke a key, you must find and delete it from every machine it was added to.
  • No time boundary. A leaked key from a laptop stolen six months ago still works today.

Short-Lived Certificates Change the Game

BeaconSSH certificates have a validity window — typically 5 to 30 minutes. When the window closes, the certificate is useless. No action required. No cleanup. No hosts to update.

This inverts the security model:

PropertyStatic KeysShort-Lived Certificates
Default statePermanently validExpired
RevocationManual, per-hostAutomatic (time)
Leaked credential riskIndefiniteBounded (minutes)
AuditWhich key? When added?Signed, timestamped, logged

The most important row: default state. With static keys, the default is “access persists.” With short-lived certificates, the default is “access expired.” You must actively obtain a new certificate to regain access. The system is secure by default.

Why Not Just Set Key Expiry?

OpenSSH doesn’t support expiry on raw public keys in authorized_keys. You can add expiry-time as a key option, but:

  • It requires modifying the authorized_keys file — the same coordination problem as key addition
  • There’s no enforcement mechanism beyond the SSH daemon reading the file
  • There’s no standard way to rotate expired keys automatically

Certificates solve this at the protocol level. The expiry is inside the signed certificate. The SSH daemon checks it on every connection attempt. No external coordination needed.

The Revocation Non-Problem

Traditional PKI systems spend enormous effort on revocation — CRLs, OCSP, KRL distribution. BeaconSSH largely sidesteps this.

If a certificate lives for 15 minutes, the maximum damage window after a credential leak is 15 minutes. That’s the worst case — and it’s often acceptable.

When is 15 minutes not acceptable? Two scenarios:

  1. Compromised CA key — this isn’t a certificate revocation, it’s a CA rotation emergency. The response is to rotate the CA key and let all certificates expire.
  2. Regulatory requirement for immediate termination — update TrustedUserCAKeys on affected hosts directly.

For both cases, the solution operates at the CA trust level, not the individual certificate level. No CRL distribution. No OCSP responder. No KRL management.

ssh-agent and the Exposure Window

Even with short-lived certificates, the credential exists in memory during its validity period. ssh-agent stores the private key and makes it available to any process running as the same user.

BeaconSSH mitigates this:

  • Keys are loaded into the agent with a lifetime matching certificate validity
  • The agent drops the key automatically when the lifetime expires
  • The CLI explicitly removes keys on logout or certificate expiry
  • If the CLI crashes, the agent still drops the key on schedule

The exposure window is bounded by the certificate lifetime, not by process lifetime or user session length.

Choosing the Right Lifetime

Certificate lifetime is a tradeoff between security and usability:

  • 5 minutes — minimal exposure, but operations longer than 5 minutes require renewal mid-flight
  • 15 minutes — good default, covers most interactive and automated operations
  • 30 minutes — comfortable for longer workflows, but larger damage window

BeaconSSH handles renewal transparently: the CLI checks remaining validity before each operation and requests a new certificate when the remaining time drops below 20% of the original lifetime. Users and automation don’t manually track expiry.

Summary

Short-lived certificates make the system secure by default. Access expires. Credentials become useless. The revocation problem is replaced by a much simpler question: how long should a certificate live? The answer depends on your threat model and operational needs — but the default is always “expired,” which is the right place to start.

The next post covers the other side of the system: how hosts learn to trust the CA and validate certificates without any runtime connection to BeaconSSH.