guildhouse-spire-plugins/specs/spiffe-ssh-svid.md

534 lines
31 KiB
Markdown

# SSH-SVID: SSH Certificates with SPIFFE Identity
## Abstract
This document defines the SSH SPIFFE Verifiable Identity Document (SSH-SVID), a standard OpenSSH certificate type whose subject identity is derived from a SPIFFE ID. An SSH-SVID binds a SPIFFE identity to an SSH public key via a certificate signed by a SPIFFE-managed SSH Certificate Authority, enabling workloads to authenticate to SSH servers using the same identity framework that governs their X.509 and JWT credentials. This specification extends the SPIFFE standard into the SSH certificate domain, providing automated, short-lived, attestation-backed SSH credentials without requiring modifications to the SSH protocol or server implementations.
## Status
**Draft Specification** -- Version 0.1.0
This document is a draft and is not yet approved by any standards body. It is published for review and comment by the SPIFFE community. Distribution of this document is unlimited.
## Table of Contents
1. [Terminology](#1-terminology)
2. [Introduction](#2-introduction)
3. [Certificate Format](#3-certificate-format)
4. [Issuance Flow](#4-issuance-flow)
5. [Trust Model](#5-trust-model)
6. [Key Management](#6-key-management)
7. [Certificate Lifetime and Rotation](#7-certificate-lifetime-and-rotation)
8. [Security Considerations](#8-security-considerations)
9. [Compatibility](#9-compatibility)
10. [References](#10-references)
## Notational Conventions
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119][rfc2119] and [RFC 8174][rfc8174] when, and only when, they appear in all capitals, as shown here.
## 1. Terminology
**SSH-SVID**: An OpenSSH certificate that encodes a SPIFFE ID as its principal identity. An SSH-SVID is a SPIFFE Verifiable Identity Document expressed in the SSH certificate format.
**SPIFFE ID**: A URI of the form `spiffe://<trust-domain>/<path>` that uniquely identifies a workload within a trust domain, as defined by the [SPIFFE specification][spiffe-spec].
**Trust Domain**: A SPIFFE administrative realm identified by the authority component of a SPIFFE ID (e.g., `example.org` in `spiffe://example.org/web-server`). All identities within a trust domain share a common root of trust.
**SPIRE**: The SPIFFE Runtime Environment, a production-ready reference implementation of the SPIFFE APIs that performs node and workload attestation and issues SVIDs.
**Workload API**: The SPIFFE-defined API (typically exposed over a Unix domain socket) through which workloads obtain their SVIDs and trust bundles. Defined in the [SPIFFE Workload API specification][spiffe-workload-api].
**X.509-SVID**: A SPIFFE Verifiable Identity Document encoded as an X.509 certificate, as defined by the [SPIFFE X.509-SVID specification][x509-svid-spec].
**JWT-SVID**: A SPIFFE Verifiable Identity Document encoded as a JSON Web Token, as defined by the [SPIFFE JWT-SVID specification][jwt-svid-spec].
**SSH Certificate Authority (CA)**: A cryptographic key pair whose private key signs SSH certificates and whose public key is distributed to relying parties for certificate verification. In the context of this specification, the SSH CA is managed by the SPIRE Server.
**SSH User Certificate**: An OpenSSH certificate of type `SSH_CERT_TYPE_USER` (value 1) that authenticates a user (or workload) to an SSH server, as defined by the [OpenSSH certificate format][openssh-cert].
**SSH Host Certificate**: An OpenSSH certificate of type `SSH_CERT_TYPE_HOST` (value 2) that authenticates an SSH server to a connecting client. While this specification focuses on user certificates, the trust model described herein applies to host certificates by analogy.
## 2. Introduction
SSH is the de facto standard for remote access to Unix systems and is widely used for workload-to-workload communication, configuration management, and operational automation. Despite its ubiquity, SSH authentication remains overwhelmingly reliant on static, long-lived key pairs that are manually provisioned, distributed, and revoked.
This static key management model introduces several problems:
- **Key sprawl**: Long-lived SSH keys accumulate across infrastructure with no reliable inventory or lifecycle management.
- **Manual rotation**: Key rotation requires human intervention or bespoke automation, leading to keys that persist far beyond their intended lifetime.
- **Weak identity binding**: An SSH public key identifies a cryptographic key, not a workload. There is no standard mechanism to assert that a given SSH key belongs to a specific service, pod, or process.
- **No attestation**: Traditional SSH key distribution trusts the provisioning process implicitly. There is no runtime verification that the entity presenting a key is the workload it claims to be.
- **Siloed trust**: SSH trust (via `authorized_keys` and `known_hosts`) is managed independently from the workload identity systems used for service mesh, mTLS, and API authentication.
The SPIFFE framework addresses these problems for X.509 and JWT credentials by providing attestation-backed, automatically rotated, short-lived identity documents. However, the SPIFFE standard does not currently define an SSH certificate type, leaving SSH as a gap in the unified workload identity model.
SSH-SVID closes this gap. By encoding a SPIFFE ID as the principal of a standard OpenSSH certificate, SSH-SVID enables:
- Automatic SSH credential issuance through the existing SPIRE Workload API
- Runtime workload attestation before any SSH credential is granted
- Short-lived certificates that eliminate the need for key revocation infrastructure
- A unified identity across mTLS (X.509-SVID), bearer tokens (JWT-SVID), and SSH (SSH-SVID)
- Trust bundle federation across organizational boundaries, including SSH CA keys
This specification defines the certificate format, issuance flow, trust model, key management requirements, and security considerations for SSH-SVIDs.
## 3. Certificate Format
### 3.1 Certificate Type
An SSH-SVID MUST be an OpenSSH user certificate as defined by the [OpenSSH certificate key format][openssh-cert].
The certificate key type MUST be one of the following:
- `ssh-ed25519-cert-v01@openssh.com` (REQUIRED support)
- `sk-ssh-ed25519-cert-v01@openssh.com` (OPTIONAL; for hardware-backed keys)
Implementations MAY support `ecdsa-sha2-nistp256-cert-v01@openssh.com` for interoperability. Implementations MUST NOT issue SSH-SVIDs using RSA key types.
The certificate type field MUST be set to `SSH_CERT_TYPE_USER` (value 1).
### 3.2 Key ID
The Key ID field of the SSH certificate MUST contain the SPIFFE ID of the workload, encoded as a UTF-8 string in its canonical URI form:
```
spiffe://<trust-domain>/<path>
```
The Key ID MUST NOT contain query parameters, fragments, or trailing slashes. The Key ID MUST conform to the SPIFFE ID format defined in [Section 2 of the SPIFFE specification][spiffe-spec].
### 3.3 Valid Principals
The Valid Principals field MUST include the workload's SPIFFE ID as the first entry.
The Valid Principals field MAY include additional principals derived from the workload's SPIRE registration entry. These additional principals enable mapping to local Unix accounts or roles on the target SSH server.
Example Valid Principals for a workload registered as `spiffe://example.org/ns/prod/sa/web-server`:
```
spiffe://example.org/ns/prod/sa/web-server
web-server
deployer
```
If no additional principals are configured in the workload registration, the Valid Principals field MUST contain exactly one entry: the SPIFFE ID.
### 3.4 Serial Number
The Serial Number field MUST be a monotonically increasing 64-bit unsigned integer, unique per SSH CA signing key. The serial number MUST NOT be reused for the lifetime of the CA key.
Serial numbers are used for audit logging and MAY be used for revocation via `RevokedKeys` in OpenSSH's `KRL` (Key Revocation List) format in exceptional circumstances, although the short-lived nature of SSH-SVIDs (see [Section 7](#7-certificate-lifetime-and-rotation)) makes explicit revocation unnecessary under normal operation.
### 3.5 Validity Period
The `valid after` and `valid before` fields MUST be set to constrain the certificate's lifetime. The requirements for these values are specified in [Section 7](#7-certificate-lifetime-and-rotation).
Implementations MUST NOT issue SSH-SVIDs with an empty validity period (i.e., valid from the Unix epoch to the maximum time value).
### 3.6 Critical Options
Critical options constrain the certificate's use. An SSH server MUST reject the certificate if it encounters an unrecognized critical option.
The following critical options apply to SSH-SVIDs:
- **`source-address`**: SHOULD be set when the workload's network location is known to the issuing SPIRE Server. The value MUST be a comma-separated list of CIDR address ranges from which the certificate is valid. When set, the SSH server MUST reject connections from addresses outside the specified ranges.
- **`force-command`**: MAY be set to restrict the certificate to a specific command, based on the workload registration entry.
Implementations MUST NOT set critical options that are not defined by [OpenSSH][openssh-cert] or by a companion specification explicitly referenced from the workload's SPIRE registration.
### 3.7 Extensions
Extensions grant capabilities to the certificate holder. An SSH server that does not recognize an extension MUST ignore it.
SSH-SVIDs SHOULD include the following standard OpenSSH extensions, unless the workload's registration entry explicitly restricts them:
- `permit-pty`
- `permit-user-rc`
SSH-SVIDs MAY include additional standard extensions:
- `permit-X11-forwarding`
- `permit-agent-forwarding`
- `permit-port-forwarding`
- `no-touch-required` (for `sk-` key types)
SSH-SVIDs MAY include vendor-specific extensions prefixed with a domain namespace. In particular, the Shellstream system defines extensions under the `shellstream@guildhouse.io` namespace, as specified in the companion Shellstream specification. Vendor extensions MUST use the `<name>@<domain>` format to avoid collision.
### 3.8 Certificate Encoding
The complete SSH-SVID certificate structure, using the `ssh-ed25519-cert-v01@openssh.com` type as an example, is as follows:
```
string "ssh-ed25519-cert-v01@openssh.com"
string nonce
string pk ; Ed25519 public key
uint64 serial ; monotonically increasing
uint32 type ; SSH_CERT_TYPE_USER (1)
string key id ; SPIFFE ID
string valid principals ; SPIFFE ID + optional additional
uint64 valid after ; certificate start time
uint64 valid before ; certificate expiry time
string critical options ; source-address, etc.
string extensions ; permit-pty, vendor extensions, etc.
string reserved ; empty
string signature key ; SSH CA public key
string signature ; CA signature over the certificate
```
This structure is identical to standard OpenSSH certificates. The SPIFFE identity is carried entirely within the existing Key ID and Valid Principals fields.
## 4. Issuance Flow
SSH-SVID issuance follows the existing SPIRE attestation and credential delivery model, extended with an SSH certificate signing capability.
### 4.1 Flow Overview
```
+-----------+ +--------------+ +--------------+ +--------+
| | (1) | | (3) | | (4) | |
| Workload +-------> SPIRE Agent +-------> SPIRE Server +-------> SSH CA |
| | | | | | | |
| | <-----+ | <-----+ | <-----+ |
| | (6) | | (5) | | (4) | |
+-----------+ +--------------+ +--------------+ +--------+
(2)
Workload Attestation
```
### 4.2 Detailed Steps
**Step 1: SSH-SVID Request**
The workload requests an SSH-SVID from the SPIRE Agent via the Workload API. The request is made over a Unix domain socket. The workload provides its SSH public key (or requests that the Agent generate an ephemeral key pair on its behalf).
The Workload API endpoint for SSH-SVID issuance is an extension to the standard SPIFFE Workload API:
```
rpc FetchSSHSVID(FetchSSHSVIDRequest) returns (FetchSSHSVIDResponse)
```
The request MUST include the workload's public key. The request MAY include requested principals beyond the SPIFFE ID.
**Step 2: Workload Attestation**
The SPIRE Agent identifies the calling workload using kernel-level attestation (e.g., Unix PID, Kubernetes pod identity, or Docker container labels). The Agent verifies that the calling process matches a registered workload entry in the SPIRE Server.
This step is identical to workload attestation for X.509-SVIDs and JWT-SVIDs. No SSH-specific attestation is required.
**Step 3: Agent-to-Server Request**
The SPIRE Agent forwards the SSH-SVID request to the SPIRE Server over the Agent-Server mTLS channel. The request includes:
- The workload's SPIFFE ID (determined by attestation)
- The workload's SSH public key
- Any additional requested principals
The Agent-to-Server RPC is analogous to the existing X.509-SVID minting RPC:
```
rpc MintSSHSVID(MintSSHSVIDRequest) returns (MintSSHSVIDResponse)
```
**Step 4: Certificate Generation**
The SPIRE Server generates the SSH certificate:
1. The Server validates that the SPIFFE ID is registered and that the requested principals are authorized for the workload.
2. The Server invokes the **CredentialComposer** plugin chain, which populates the certificate fields according to this specification and the workload's registration entry.
3. The Server signs the certificate using the SSH CA private key, managed by the **KeyManager** plugin.
The CredentialComposer plugin is the extension point where operators can customize certificate fields (extensions, critical options, additional principals) without modifying the SPIRE Server core.
**Step 5: Certificate Delivery to Agent**
The SPIRE Server returns the signed SSH certificate to the SPIRE Agent over the existing mTLS channel. The response includes:
- The signed SSH-SVID certificate (encoded per [Section 3.8](#38-certificate-encoding))
- The SSH CA trust bundle (the CA public key and any federated CA public keys)
**Step 6: Certificate Delivery to Workload**
The SPIRE Agent delivers the SSH-SVID to the workload via the Workload API Unix domain socket. The response includes:
- The signed SSH certificate
- The corresponding private key (if the Agent generated the key pair)
- The SSH CA trust bundle for known_hosts configuration
- The certificate's expiry time
The workload MAY write the certificate to disk (e.g., for use with `ssh -o CertificateFile=`) or hold it in memory for programmatic use.
### 4.3 Workload API Extension
The SSH-SVID Workload API extension defines the following messages:
```protobuf
message FetchSSHSVIDRequest {
bytes public_key = 1; // SSH public key (Ed25519)
repeated string principals = 2; // Additional requested principals
}
message FetchSSHSVIDResponse {
repeated SSHSVID svids = 1;
repeated SSHTrustBundle trust_bundles = 2;
}
message SSHSVID {
string spiffe_id = 1;
bytes certificate = 2; // Signed OpenSSH certificate
bytes private_key = 3; // Private key (if Agent-generated)
int64 expires_at = 4; // Unix timestamp
}
message SSHTrustBundle {
string trust_domain = 1;
repeated bytes ca_public_keys = 2; // SSH CA public keys
}
```
The full protobuf definitions are specified in the companion `ssh-credential-composer` plugin specification.
## 5. Trust Model
### 5.1 SSH CA as Part of the SPIRE Trust Bundle
The SSH CA public key MUST be included in the SPIRE trust bundle for the trust domain. This extends the existing trust bundle structure, which already contains X.509 root certificates and JWT signing keys, to include SSH CA public keys.
A trust bundle with SSH-SVID support contains:
- X.509 root certificates (for X.509-SVID validation)
- JWT signing public keys (for JWT-SVID validation)
- SSH CA public keys (for SSH-SVID validation)
### 5.2 Trust Bundle Federation
When two trust domains are federated, each domain's trust bundle MAY include SSH CA public keys from the other domain. This enables cross-domain SSH-SVID validation: a workload in `trust-domain-a` can authenticate to an SSH server in `trust-domain-b` if the server trusts `trust-domain-a`'s SSH CA key.
Federation of SSH CA keys follows the same mechanism as X.509 root certificate federation in SPIRE, using the SPIFFE Federation API.
### 5.3 SSH Server Configuration
SSH servers that accept SSH-SVIDs MUST be configured with the SSH CA public key(s) from the SPIRE trust bundle. This configuration uses standard OpenSSH server directives:
**`TrustedUserCAKeys`**: Points to a file containing the SSH CA public key(s). This file MUST be kept current with the SPIRE trust bundle. Implementations SHOULD use a sidecar or agent process that watches the SPIRE trust bundle and updates this file automatically.
```
# /etc/ssh/sshd_config
TrustedUserCAKeys /etc/ssh/spire_ca_keys
```
**`AuthorizedPrincipalsFile`**: Maps SPIFFE IDs to local Unix accounts. This file determines which SPIFFE IDs are authorized to access which local accounts.
```
# /etc/ssh/authorized_principals/%u
# For user "deploy":
spiffe://example.org/ns/prod/sa/web-server
spiffe://example.org/ns/prod/sa/ci-runner
```
When `AuthorizedPrincipalsFile` is configured, the SSH server validates that the certificate's Valid Principals include an entry that matches a line in the principals file for the target Unix account.
Alternatively, if the SSH server's `AuthorizedPrincipalsCommand` directive is available (OpenSSH 8.0+), implementations MAY use a command that queries the SPIRE trust bundle dynamically to resolve SPIFFE ID-to-account mappings.
### 5.4 Certificate Chain Model
SSH certificates use a single-level trust model: each certificate is signed directly by the CA key. There are no intermediate certificate authorities in the SSH certificate format. Consequently, the SSH CA public key present in the SPIRE trust bundle directly validates all SSH-SVIDs issued within that trust domain.
This single-level model simplifies validation but requires careful CA key management (see [Section 6](#6-key-management)).
## 6. Key Management
### 6.1 CA Key Lifecycle
The SSH CA key pair is managed by the SPIRE Server's **KeyManager** plugin. The KeyManager is responsible for generating, storing, and making available the CA private key for certificate signing operations.
Implementations SHOULD use a KeyManager that stores CA keys in hardware security modules (HSMs) or secure enclaves. The companion `substrate-keymanager` specification defines a KeyManager implementation suitable for production deployments.
The SSH CA key MUST NOT be exported from the KeyManager in plaintext. All signing operations MUST be performed within the KeyManager boundary.
### 6.2 Key Types
The following key types are defined for SSH CA keys:
| Key Type | Status | Notes |
|---|---|---|
| Ed25519 | REQUIRED | All implementations MUST support Ed25519 CA keys |
| ECDSA P-256 | OPTIONAL | MAY be supported for interoperability |
| RSA | NOT RECOMMENDED | RSA SHOULD NOT be used due to larger key/signature sizes and weaker security margins at equivalent key lengths |
The SSH CA key type determines the certificate signature algorithm. An Ed25519 CA key produces `ssh-ed25519` signatures; an ECDSA P-256 CA key produces `ecdsa-sha2-nistp256` signatures.
### 6.3 CA Key Rotation
SPIRE manages CA key rotation through the **upstream authority** mechanism. When a CA key rotation occurs:
1. The new CA public key MUST be added to the trust bundle before any certificates are signed with the new CA private key.
2. Both the old and new CA public keys MUST be present in the trust bundle during the transition period.
3. The old CA public key MUST remain in the trust bundle until all certificates signed by the old key have expired.
4. SSH servers MUST receive the updated trust bundle (containing both CA public keys) before certificates signed by the new key are presented.
The trust bundle propagation delay introduces a window during which a newly rotated CA key may not yet be trusted by all SSH servers. Implementations MUST account for this delay by ensuring the new key is in the trust bundle for at least one full certificate lifetime before the old key is removed.
### 6.4 Workload Keys
Workload SSH key pairs (the key pair bound to the certificate) MUST be ephemeral. A new key pair SHOULD be generated for each SSH-SVID request.
Workload keys MUST be Ed25519. This requirement ensures small key sizes, fast signing, and consistent security properties across all SSH-SVIDs.
Workload private keys MUST NOT be persisted to durable storage beyond the certificate's lifetime. If the SPIRE Agent generates the key pair on behalf of the workload, the Agent MUST delete its copy of the private key after delivering it to the workload.
## 7. Certificate Lifetime and Rotation
### 7.1 Lifetime Requirements
SSH-SVIDs MUST be short-lived. The following constraints apply:
| Parameter | Value | Requirement Level |
|---|---|---|
| Default TTL | 5 minutes | RECOMMENDED |
| Minimum TTL | 30 seconds | MUST NOT issue below |
| Maximum TTL | 1 hour | MUST NOT exceed |
The `valid after` field MUST be set to the current time at issuance (with no more than 60 seconds of clock skew tolerance subtracted).
The `valid before` field MUST be set to `valid after` plus the configured TTL.
Operators MAY configure per-workload TTLs within the bounds above via SPIRE registration entries.
### 7.2 Rotation
Workloads MUST re-request SSH-SVIDs before the current certificate expires. The SPIRE Workload API handles rotation automatically when the workload uses the streaming `FetchSSHSVID` API variant.
Certificates SHOULD be renewed when 50% of the certificate's lifetime has elapsed (the "half-life" renewal point). For a certificate with a 5-minute TTL, renewal SHOULD occur at 2 minutes 30 seconds after issuance.
Implementations MUST tolerate brief periods where both the old and new certificates are valid (i.e., the validity periods overlap). This overlap is expected and does not constitute a security concern given the short lifetimes involved.
### 7.3 Revocation
SSH-SVIDs do not require a revocation infrastructure (CRL, OCSP, or equivalent) under normal operation. The short certificate lifetime ensures that a compromised certificate becomes unusable within minutes.
In exceptional circumstances (e.g., a compromised workload key that must be revoked immediately), operators MAY use OpenSSH Key Revocation Lists (KRLs) distributed to SSH servers. KRL-based revocation is an operational concern outside the scope of this specification.
The absence of revocation infrastructure is a deliberate design choice: it reduces operational complexity, eliminates availability dependencies on revocation endpoints, and aligns with the SPIFFE principle that short-lived credentials are preferable to long-lived credentials with revocation.
## 8. Security Considerations
### 8.1 Workload Attestation as Trust Anchor
The security of SSH-SVIDs depends entirely on the correctness of SPIRE's workload attestation. If an attacker can spoof a workload's identity during attestation (e.g., by compromising the kernel, container runtime, or node agent), they can obtain SSH-SVIDs for arbitrary SPIFFE IDs.
Operators MUST ensure that the workload attestation mechanism is appropriate for their threat model. Kubernetes-based attestation (using the TokenReview API and pod metadata) is RECOMMENDED for containerized workloads. Unix PID-based attestation SHOULD only be used when stronger mechanisms are unavailable.
### 8.2 SPIFFE ID Visibility
SSH-SVIDs do not provide confidentiality of the workload's SPIFFE ID. The SPIFFE ID is encoded in the certificate's Key ID and Valid Principals fields, both of which are transmitted in cleartext during SSH authentication (the certificate is sent before the encrypted channel is fully established in the SSH protocol).
Operators SHOULD be aware that SPIFFE IDs may reveal information about internal service topology (e.g., namespace names, service account names). If this information is sensitive, operators SHOULD use opaque path components in SPIFFE IDs.
### 8.3 Agent-to-Server Communication
Communication between the SPIRE Agent and SPIRE Server MUST use mutual TLS (mTLS), authenticated with X.509-SVIDs. This is the default communication model in SPIRE.
The Agent-to-Server channel carries SSH-SVID signing requests, which include the workload's public key and SPIFFE ID. Compromise of this channel would allow an attacker to request SSH-SVIDs for any workload the compromised Agent is authorized to attest.
### 8.4 Workload API Socket Protection
The Unix domain socket used for the Workload API MUST be protected by filesystem permissions. The socket SHOULD be accessible only to the workload processes that are entitled to receive SVIDs.
In Kubernetes environments, the Workload API socket is typically mounted into the pod's filesystem via a `hostPath` or CSI volume. The SPIRE Agent MUST verify the connecting process's identity (via kernel-level attestation) regardless of filesystem permissions.
### 8.5 Rate Limiting
The SPIRE Server SHOULD enforce rate limits on SSH-SVID issuance to prevent abuse. Rate limits SHOULD be applied per workload registration entry (i.e., per SPIFFE ID).
A RECOMMENDED rate limit is no more than 60 SSH-SVID issuances per SPIFFE ID per minute. This allows for normal rotation (approximately 1 request per renewal interval) while preventing runaway issuance loops.
### 8.6 CA Key Compromise
Compromise of the SSH CA private key allows an attacker to forge SSH-SVIDs for any SPIFFE ID in the trust domain. Mitigations include:
- Storing CA keys in HSMs or secure enclaves (see [Section 6.1](#61-ca-key-lifecycle))
- Monitoring certificate issuance logs for anomalous serial numbers or SPIFFE IDs
- Implementing CA key rotation on a regular schedule (see [Section 6.3](#63-ca-key-rotation))
- Maintaining the ability to rapidly rotate the CA key and propagate the new trust bundle in response to a compromise
### 8.7 Clock Skew
SSH certificate validation depends on accurate system clocks. Clock skew between the issuing SPIRE Server and the validating SSH server can cause valid certificates to be rejected (if the server's clock is behind) or expired certificates to be accepted (if the server's clock is ahead).
Implementations SHOULD account for clock skew by subtracting a small tolerance (no more than 60 seconds) from the `valid after` timestamp. Operators MUST ensure that all systems participating in SSH-SVID issuance and validation synchronize their clocks via NTP or an equivalent mechanism.
## 9. Compatibility
### 9.1 OpenSSH Server Compatibility
SSH-SVIDs are standard OpenSSH certificates. Any OpenSSH server at version 8.0 or later can validate SSH-SVIDs without modification. The server requires only:
- The SSH CA public key in `TrustedUserCAKeys`
- Principal-to-account mappings in `AuthorizedPrincipalsFile` or `AuthorizedPrincipalsCommand`
No patches, plugins, or custom builds of OpenSSH are required.
### 9.2 SSH Client Compatibility
SSH-SVIDs can be used with any OpenSSH client (version 8.0+) via standard mechanisms:
- **Certificate file**: `ssh -o CertificateFile=/path/to/ssh-svid-cert.pub`
- **Identity file**: `ssh -i /path/to/key` (when the certificate is in the same directory with the `-cert.pub` suffix, the client loads it automatically)
- **SSH agent**: `ssh-add /path/to/key` followed by `ssh-add -L` to verify the certificate is loaded
### 9.3 SSH Agent Compatibility
The standard `ssh-agent` can hold SSH-SVIDs. The SPIRE Agent or a helper process MAY load SSH-SVIDs into the workload's `ssh-agent` automatically, removing expired certificates and adding renewed ones as part of the rotation cycle.
When using `ssh-agent`, the certificate lifetime constrains the agent's key lifetime. Implementations SHOULD use `ssh-add -t <seconds>` to set a key lifetime matching the certificate's remaining validity.
### 9.4 Non-OpenSSH Implementations
SSH-SVIDs are compatible with any SSH implementation that supports OpenSSH certificate validation, including but not limited to:
- Dropbear (with certificate support enabled)
- libssh (version 0.9+)
- Paramiko (with certificate validation)
- Go's `golang.org/x/crypto/ssh` package
Implementations that do not support OpenSSH certificates cannot validate SSH-SVIDs. This is a limitation of those implementations, not of this specification.
## 10. References
### Normative References
- **[RFC 2119]** Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997. https://www.rfc-editor.org/rfc/rfc2119
- **[RFC 8174]** Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, May 2017. https://www.rfc-editor.org/rfc/rfc8174
- **[SPIFFE Specification]** SPIFFE Project, "Secure Production Identity Framework for Everyone", v1.0. https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE.md
- **[SPIFFE Workload API]** SPIFFE Project, "SPIFFE Workload API". https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE_Workload_API.md
- **[X.509-SVID Specification]** SPIFFE Project, "X.509 SPIFFE Verifiable Identity Document". https://github.com/spiffe/spiffe/blob/main/standards/X509-SVID.md
- **[JWT-SVID Specification]** SPIFFE Project, "JWT SPIFFE Verifiable Identity Document". https://github.com/spiffe/spiffe/blob/main/standards/JWT-SVID.md
- **[OpenSSH Certificate Format]** OpenSSH Project, "PROTOCOL.certkeys". https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.certkeys
### Informative References
- **[RFC 4251]** Ylonen, T. and C. Lonvick, "The Secure Shell (SSH) Protocol Architecture", RFC 4251, January 2006. https://www.rfc-editor.org/rfc/rfc4251
- **[RFC 4252]** Ylonen, T. and C. Lonvick, "The Secure Shell (SSH) Authentication Protocol", RFC 4252, January 2006. https://www.rfc-editor.org/rfc/rfc4252
- **[RFC 4253]** Ylonen, T. and C. Lonvick, "The Secure Shell (SSH) Transport Layer Protocol", RFC 4253, January 2006. https://www.rfc-editor.org/rfc/rfc4253
- **[SPIRE Documentation]** SPIFFE Project, "SPIRE: the SPIFFE Runtime Environment". https://spiffe.io/docs/latest/spire-about/
- **[SPIFFE Trust Bundle]** SPIFFE Project, "SPIFFE Trust Domain and Bundle". https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE_Trust_Domain_and_Bundle.md
[rfc2119]: https://www.rfc-editor.org/rfc/rfc2119
[rfc8174]: https://www.rfc-editor.org/rfc/rfc8174
[spiffe-spec]: https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE.md
[spiffe-workload-api]: https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE_Workload_API.md
[x509-svid-spec]: https://github.com/spiffe/spiffe/blob/main/standards/X509-SVID.md
[jwt-svid-spec]: https://github.com/spiffe/spiffe/blob/main/standards/JWT-SVID.md
[openssh-cert]: https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.certkeys