139 lines
4.4 KiB
Markdown
139 lines
4.4 KiB
Markdown
# Governance Integration
|
|
|
|
How plugins interact with GovernanceService, CeremonyService, and NotaryService.
|
|
|
|
## Services Overview
|
|
|
|
| Service | Proto Package | Purpose |
|
|
|---------|--------------|---------|
|
|
| GovernanceService | `quartermaster.v1` | MutationIntent lifecycle (create, redeem, revoke) |
|
|
| CeremonyService | `bascule.v1` | Multi-stakeholder approval workflows |
|
|
| NotaryService | `quartermaster.v1` | Merkle tree anchoring for audit |
|
|
|
|
All communication uses gRPC with mTLS via SPIFFE SVIDs.
|
|
|
|
## Intent Lifecycle
|
|
|
|
Every credential operation follows the intent lifecycle:
|
|
|
|
```
|
|
CreateIntent ──> [authorized] ──> RedeemIntent ──> SAT ──> Operation ──> Anchor
|
|
|
|
|
v
|
|
[ceremony_pending] ──> CeremonyService ──> [approved] ──> RedeemIntent
|
|
|
|
|
v
|
|
[denied] ──> Abort
|
|
```
|
|
|
|
### CreateIntent
|
|
|
|
```protobuf
|
|
rpc CreateIntent(CreateIntentRequest) returns (CreateIntentResponse);
|
|
```
|
|
|
|
Fields:
|
|
- `registry_type`: `"credential"` for all credential operations
|
|
- `verb`: `"issue"`, `"rotate"`, or `"revoke"`
|
|
- `artifact_scope`: JSON description of the credential parameters
|
|
- `tenant_id`: Owning tenant UUID
|
|
- `identity_claim`: OIDC token or external event claim
|
|
- `ttl_seconds`: Intent lifetime (default 300)
|
|
- `max_redemptions`: Always `1` for credential operations
|
|
- `idempotency_key`: `"{registry_type}:{verb}:{credential_id}"`
|
|
|
|
Response includes:
|
|
- `intent_id`: Unique identifier for the intent
|
|
- `ceremony_id`: Non-empty if a governance ceremony is required
|
|
- `denied`: True if the Accord policy immediately rejects the operation
|
|
|
|
### RedeemIntent
|
|
|
|
Called after the intent is authorized (immediately or after ceremony approval):
|
|
|
|
```protobuf
|
|
rpc RedeemIntent(RedeemIntentRequest) returns (RedeemIntentResponse);
|
|
```
|
|
|
|
Returns a `SatToken` containing:
|
|
- `sat_hash`: Cryptographic binding of the SAT contents
|
|
- `bearer_svid`: SPIFFE ID authorized to perform the operation
|
|
- `scopes`: `SatScopeMsg` entries defining permitted operations
|
|
- `issued_at` / `expires_at`: SAT validity window
|
|
|
|
## Ceremony Flow
|
|
|
|
When `CreateIntentResponse.ceremony_id` is non-empty:
|
|
|
|
1. Plugin monitors ceremony status via `CeremonyService.GetCeremony`
|
|
2. Approvers use `ApproveCeremony` or `DenyCeremony` (via Bascule shell or API)
|
|
3. On approval, GovernanceService transitions the intent to `authorized`
|
|
4. Plugin proceeds with `RedeemIntent`
|
|
|
|
Ceremony types (from Accord policy):
|
|
- **Autonomous**: No approval needed, intent authorized immediately
|
|
- **SelfGrant**: Requestor self-approves
|
|
- **SingleApproval**: One external approver required
|
|
- **QuorumApproval**: Multiple approvers required (configurable quorum)
|
|
- **EmergencyBreakGlass**: Proceed immediately, require post-hoc approval
|
|
|
|
## MutationEnvelope Construction
|
|
|
|
After the credential operation succeeds, the plugin constructs a MutationEnvelope for audit anchoring:
|
|
|
|
### Step 1: Canonicalize Payload
|
|
|
|
Serialize the credential event payload using RFC 8785 JSON Canonicalization Scheme (JCS):
|
|
- Sorted keys
|
|
- No whitespace
|
|
- Deterministic number formatting
|
|
|
|
### Step 2: Domain-Separated Hash
|
|
|
|
```
|
|
payload_hash = SHA-256("guildhouse.credential.v1:" + jcs_bytes)
|
|
```
|
|
|
|
The domain prefix prevents cross-protocol hash collisions.
|
|
|
|
### Step 3: Build Envelope
|
|
|
|
```json
|
|
{
|
|
"domain": "guildhouse.credential.v1",
|
|
"payload_hash": "<hex-sha256>",
|
|
"timestamp": "<rfc3339>",
|
|
"actor_svid": "<spiffe-id>",
|
|
"tenant_id": "<uuid>",
|
|
"event_type": "issue",
|
|
"intent_id": "<intent-id>",
|
|
"sat_hash": "<hex-sha256>"
|
|
}
|
|
```
|
|
|
|
### Step 4: Anchor
|
|
|
|
JCS-canonicalize the envelope, SHA-256 hash it, submit as a leaf to `NotaryService.CreateAnchor`.
|
|
|
|
## Error Handling
|
|
|
|
| Failure | Behavior |
|
|
|---------|----------|
|
|
| GovernanceService unreachable | **Fail closed** — credential operation fails |
|
|
| Ceremony timeout | Treat as denial, abort operation |
|
|
| NotaryService unreachable | Credential operation proceeds, queue leaf for retry |
|
|
| No Accord policy match | Default to SingleApproval (fail safe) |
|
|
|
|
## Plugin Configuration
|
|
|
|
All plugins share governance connection configuration:
|
|
|
|
```hcl
|
|
plugin_data {
|
|
governance_addr = "governance.quartermaster.svc.cluster.local:50051"
|
|
ceremony_addr = "ceremony.bascule.svc.cluster.local:50052"
|
|
notary_addr = "notary.quartermaster.svc.cluster.local:50051"
|
|
trust_domain = "guildhouse.example.org"
|
|
cluster_id = "guildhouse-prod"
|
|
}
|
|
```
|