SSH Certificates Bind Identity to Principals and Constraints
A raw SSH public key answers a narrow question: does the connecting client possess the private key corresponding to this public key? Authorization still needs another mapping. A server commonly places accepted keys in authorized_keys, often with options that restrict what a particular key may do.
OpenSSH certificates add a signed identity layer around a public key. A certificate can carry principals, a validity interval, critical options, extensions, a serial number, and a key identifier. A server configured to trust the signing CA can validate that certificate without storing the holder’s raw public key as a separate authorization entry.
This changes key distribution, not the basic possession check. The client still proves possession of the private key. The certificate supplies signed metadata that the server can evaluate as part of authentication and authorization.
A certificate signs a public key plus metadata
An OpenSSH user certificate contains the subject public key and fields covered by the CA signature. Conceptually:
subject public key
principal set
valid-after / valid-before
critical options
extensions
serial + key ID
|
v
CA signatureThe signature prevents those signed fields from being altered without detection. It does not encrypt them, and it does not make the subject private key recoverable from the certificate.
For user authentication, the server needs a trust anchor for the relevant user CA. In OpenSSH, TrustedUserCAKeys can name a file containing CA public keys accepted for user certificates. Trusting that CA is a broad delegation: certificates signed by it can become eligible for authentication when their other checks also pass.
That delegation makes CA private-key handling a high-value control. Compromise of a trusted user CA can permit unauthorized certificate issuance within the scope accepted by servers that trust it.
Principals are authorization names, not arbitrary labels
A user certificate may contain one or more valid principals. The server compares those principals with the identity it is prepared to accept for the target account, subject to its configuration.
certificate principals: [deploy, release]
|
v
server policy for target account
|
accept or rejectThis mapping deserves explicit design. A principal can represent an account name, role, workload identity, or another naming scheme supported by the deployment. The important property is that issuance policy and server policy agree on its meaning.
AuthorizedPrincipalsFile and AuthorizedPrincipalsCommand provide mechanisms for defining accepted principals independently of a user’s raw authorized_keys entries. This can keep the certificate trust model separate from legacy per-key authorization.
A certificate with no valid principal list has special handling in OpenSSH and should not be treated as equivalent to a tightly scoped principal set. Issuers should encode the intended identity scope deliberately rather than relying on an empty field as a convenience.
Validity intervals limit certificate lifetime
OpenSSH certificates carry valid-after and valid-before values. A server checks the current time against that interval during certificate validation.
Short-lived certificates can reduce reliance on distributing and later deleting individual user keys. An identity system can authenticate a person or workload, issue a certificate for a bounded interval, and let SSH servers trust the CA.
identity check
|
v
issue short-lived certificate
|
v
SSH access during validity window
|
v
certificate expiresExpiry is not revocation. A certificate remains cryptographically signed after its validity interval ends; it simply fails the time check. If access must be terminated before expiry, the deployment needs a revocation or trust-removal mechanism appropriate to its design.
OpenSSH supports revoked-key data through RevokedKeys. Operational designs can also rotate or remove CA trust, but removing a CA affects every certificate chained to that trust anchor, so it is a much broader action than revoking one credential.
Critical options and extensions have different failure semantics
Certificates can carry critical options and extensions. The distinction is security-relevant.
A critical option imposes a condition that must be recognized and satisfied for the certificate to be accepted. An implementation that does not support a critical option must reject the certificate rather than silently ignore the restriction.
OpenSSH defines critical options such as source-address, which can restrict the source addresses from which the certificate is valid. It also supports force-command, which can constrain the command executed after authentication.
Extensions describe capabilities that may be enabled, including facilities such as PTY allocation, agent forwarding, port forwarding, X11 forwarding, and user ~/.ssh/rc execution, depending on the certificate and server configuration.
The CA therefore signs more than identity. It can sign part of the session policy. Issuance code should treat these fields as security policy inputs rather than free-form metadata.
Server policy still applies after certificate validation
A valid certificate is not a universal permission token. SSH server configuration remains part of the decision.
sshd can apply account restrictions, Match blocks, forwarding controls, command restrictions, authentication-method requirements, and other policy. Certificate extensions do not override server-side prohibitions. A certificate that permits a capability does not force the server to enable it.
This produces two layers:
certificate policy
AND
server policy
|
v
resulting session permissionsKeeping the layers separate prevents an issuer from accidentally being treated as the sole authority over every SSH session property. The CA controls what it signs; each server controls what it is willing to honor.
CA rotation needs an overlap plan
Replacing a trusted SSH CA is a trust-anchor migration. Servers need the new CA public key before certificates signed only by that CA can authenticate. Removing the old CA too early can reject still-valid credentials; keeping it indefinitely preserves trust in an authority intended for retirement.
A controlled sequence can use an overlap period:
servers trust old CA
|
add new CA trust
|
issue with new CA
|
old certificates age out or are revoked
|
remove old CA trustThe exact interval depends on certificate lifetime and deployment policy. The useful invariant is simpler: certificate issuance and server trust distribution must be coordinated.
Audit fields help connect issuance to access
Serial numbers and key identifiers can support operational correlation. They are signed certificate fields, so an issuer can assign values that connect a credential to an issuance record.
These fields do not replace authentication logs or an issuance audit trail. A useful deployment records who or what requested a certificate, which principals and constraints were granted, which CA signed it, its validity interval, and the resulting serial or key identifier.
That record becomes especially important when certificates are short-lived and generated frequently. The server may no longer have a static list of every accepted subject key, so the issuance system becomes a central source of credential history.
CA trust is the main security boundary
SSH certificates reduce per-host key distribution by moving trust toward a signing authority. That simplification concentrates authority at the CA.
The resulting design is strongest when issuance policy is narrow: authenticate the requester, constrain principals, keep validity bounded, apply critical options where required, protect the CA private key, and retain enough audit data to trace issued credentials. Servers then validate a signed credential against local trust and local session policy rather than maintaining a copy of every user key.
The certificate is not a replacement for server authorization. It is a signed statement that gives authorization policy structured identity and constraint data to evaluate.
References
- OpenBSD,
ssh-keygen(1)manual: https://man.openbsd.org/ssh-keygen - OpenBSD,
sshd_config(5)manual: https://man.openbsd.org/sshd_config - OpenBSD,
PROTOCOL.certkeys: https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.certkeys