122 lines
6.1 KiB
Markdown
122 lines
6.1 KiB
Markdown
# SSH Certificate Issuance Flow
|
|
|
|
End-to-end flow from workload request to governed SSH session.
|
|
|
|
## Sequence
|
|
|
|
```
|
|
Workload SPIRE Agent SPIRE Server ssh-credential- Governance Notary
|
|
composer Service Service
|
|
| | | | | |
|
|
| FetchSSHSVID | | | | |
|
|
|-------------->| | | | |
|
|
| | Attest(pid) | | | |
|
|
| |--+ | | | |
|
|
| | | oidc-attestor | | |
|
|
| |<-+ | | | |
|
|
| | | | | |
|
|
| | MintSSHSVID | | | |
|
|
| |-------------->| | | |
|
|
| | | ComposeWorkloadCred | |
|
|
| | |-------------->| | |
|
|
| | | | | |
|
|
| | | | CreateIntent | |
|
|
| | | |-------------->| |
|
|
| | | | intent_id | |
|
|
| | | |<--------------| |
|
|
| | | | | |
|
|
| | | | RedeemIntent | |
|
|
| | | |-------------->| |
|
|
| | | | SAT | |
|
|
| | | |<--------------| |
|
|
| | | | | |
|
|
| | | | Build SSH cert with |
|
|
| | | | Shellstream extensions |
|
|
| | | | | |
|
|
| | | | CreateAnchor | |
|
|
| | | |------------------------------>|
|
|
| | | | merkle_root | |
|
|
| | | |<------------------------------|
|
|
| | | | | |
|
|
| | | SSH cert | | |
|
|
| | |<--------------| | |
|
|
| | SSH cert | | | |
|
|
| |<--------------| | | |
|
|
| SSH cert | | | | |
|
|
|<--------------| | | | |
|
|
```
|
|
|
|
## Step-by-Step
|
|
|
|
### 1. Workload Requests SSH SVID
|
|
|
|
The workload calls the SPIRE Workload API via Unix domain socket, requesting an SSH-SVID. It provides its SSH public key (Ed25519).
|
|
|
|
### 2. Agent Attests Workload
|
|
|
|
The SPIRE Agent identifies the calling process via kernel-level attestation. The `oidc-attestor` plugin verifies the workload's OIDC token and returns selectors. The agent matches selectors against registration entries.
|
|
|
|
### 3. Agent Forwards to Server
|
|
|
|
The agent sends a `MintSSHSVID` request to the SPIRE Server over the Agent-Server mTLS channel, including the workload's SPIFFE ID, public key, and requested principals.
|
|
|
|
### 4. CredentialComposer Pipeline
|
|
|
|
The SPIRE Server invokes the `ssh-credential-composer` plugin during credential minting.
|
|
|
|
### 5. Governance Intent
|
|
|
|
The composer calls `GovernanceService.CreateIntent` with:
|
|
- `registry_type`: `"credential"`
|
|
- `verb`: `"issue"`
|
|
- `artifact_scope`: JSON describing the SSH certificate parameters
|
|
- Identity from SPIRE attestation
|
|
|
|
If the Accord policy requires a ceremony, the flow blocks until approval.
|
|
|
|
### 6. SAT Issuance
|
|
|
|
The composer calls `GovernanceService.RedeemIntent` to obtain a SAT (Substrate Attestation Token) authorizing the credential issuance.
|
|
|
|
### 7. SSH Certificate Construction
|
|
|
|
The composer builds the SSH certificate:
|
|
- **Key ID**: SPIFFE ID
|
|
- **Principals**: SPIFFE ID + additional principals from registration
|
|
- **TTL**: Per-workload configuration (default 5 minutes)
|
|
- **Extensions**: Standard SSH extensions + Shellstream governance extensions
|
|
|
|
Shellstream extensions embedded:
|
|
- `sat-scope@guildhouse.io` — SAT authorization scope
|
|
- `sat-hash@guildhouse.io` — SHA-256 of the SAT
|
|
- `tenant-id@guildhouse.io` — Tenant UUID
|
|
- `roles@guildhouse.io` — Assigned roles
|
|
- `merkle-root@guildhouse.io` — Governance tree root at issuance
|
|
- `governance-epoch@guildhouse.io` — Current epoch counter
|
|
|
|
### 8. Merkle Anchoring
|
|
|
|
The composer constructs a MutationEnvelope (RFC 8785 JCS + domain-separated SHA-256) and submits the leaf hash to `NotaryService.CreateAnchor`.
|
|
|
|
### 9. Certificate Delivery
|
|
|
|
The signed SSH certificate flows back through the server → agent → workload chain. The workload receives the certificate, private key (if agent-generated), and SSH CA trust bundle.
|
|
|
|
## Using the Certificate
|
|
|
|
The workload uses the SSH-SVID to connect to governed hosts:
|
|
|
|
```bash
|
|
ssh -o CertificateFile=/tmp/ssh-svid-cert.pub \
|
|
-i /tmp/ssh-svid-key \
|
|
target-host.example.org
|
|
```
|
|
|
|
## Server-Side Validation
|
|
|
|
The SSH server:
|
|
1. Validates the certificate signature against `TrustedUserCAKeys` (from SPIRE trust bundle)
|
|
2. Checks the certificate validity period
|
|
3. Matches principals against `AuthorizedPrincipalsFile`
|
|
4. Reads Shellstream extensions for authorization decisions (tenant, roles, SAT scope)
|
|
5. Optionally verifies the merkle proof against the NotaryService for audit
|