guildhouse-spire-plugins/docs/ssh-certificate-flow.md

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