feat(attestation): add SAT-SPEC-0002 protobuf definitions
Add protobuf message definitions for the four-layer attestation architecture defined in SAT-SPEC-0002. Package: substrate.attestation.v2 Files: - common.proto: QmReceipt (hash-chained Ed25519-signed receipts) - platform.proto: PlatformClaim, TpmQuoteBinding (L1 hardware identity) - software.proto: SoftwareClaim, BuildProvenance (L2 image provenance) - governance.proto: GovernanceClaim, AccordReference, DelegationReference (L3) - session.proto: SessionClaim, ActorContext, PostureEvidence, PostureLevel (L4) - sat.proto: SatBundle (composite, optional claim fields for has_*() codegen) Also adds buf.yaml for lint/breaking-change checks. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
9a4076df49
commit
98aa2b0ec7
8 changed files with 244 additions and 0 deletions
35
attestation/v2/README.md
Normal file
35
attestation/v2/README.md
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
# attestation/v2 — SAT-SPEC-0002 Protobuf Definitions
|
||||||
|
|
||||||
|
Protobuf message definitions for the Substrate Attestation Token v2 (SAT-SPEC-0002),
|
||||||
|
the four-layer attestation architecture for Substrate nodes.
|
||||||
|
|
||||||
|
## Package
|
||||||
|
|
||||||
|
`substrate.attestation.v2`
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
| File | Layer | Messages |
|
||||||
|
|------|-------|----------|
|
||||||
|
| `sat.proto` | — | `SatBundle` (top-level composite) |
|
||||||
|
| `platform.proto` | L1 Platform | `PlatformClaim`, `TpmQuoteBinding` |
|
||||||
|
| `software.proto` | L2 Software | `SoftwareClaim`, `BuildProvenance` |
|
||||||
|
| `governance.proto` | L3 Governance | `GovernanceClaim`, `AccordReference`, `DelegationReference` |
|
||||||
|
| `session.proto` | L4 Session | `SessionClaim`, `ActorContext`, `PostureEvidence`, `PostureLevel` (enum) |
|
||||||
|
| `common.proto` | — | `QmReceipt` |
|
||||||
|
|
||||||
|
## Layer Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
L4 Session ← actor identity + posture evaluation
|
||||||
|
L3 Governance ← accords, delegations, ceremonies
|
||||||
|
L2 Software ← image provenance + QM build receipt
|
||||||
|
L1 Platform ← TPM measurements + hardware identity
|
||||||
|
```
|
||||||
|
|
||||||
|
Each layer's claim hash binds to the layers below it (hash chaining).
|
||||||
|
The composite `sat_hash` in `SatBundle` covers all present layers.
|
||||||
|
|
||||||
|
## Spec
|
||||||
|
|
||||||
|
Canonical specification: `substrate/docs/specs/SAT-SPEC-0002.md`
|
||||||
20
attestation/v2/common.proto
Normal file
20
attestation/v2/common.proto
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package substrate.attestation.v2;
|
||||||
|
|
||||||
|
// ─── QM Receipt ─────────────────────────────────────────────────────
|
||||||
|
//
|
||||||
|
// The Quartermaster receipt is the fundamental trust primitive for
|
||||||
|
// non-hardware claims. Every QM receipt is hash-chained, self-contained,
|
||||||
|
// and verifiable with the QM's Ed25519 public key.
|
||||||
|
|
||||||
|
message QmReceipt {
|
||||||
|
string receipt_id = 1; // Unique identifier (UUIDv7)
|
||||||
|
bytes claim_hash = 2; // SHA-256 hash of the notarized claim
|
||||||
|
repeated bytes referenced_hashes = 3; // Previous layer claim hashes (binding chain)
|
||||||
|
string issuer = 4; // QM instance identity (SPIFFE ID)
|
||||||
|
string timestamp = 5; // ISO 8601, QM clock (authoritative)
|
||||||
|
uint64 chain_position = 6; // Position in the QM's hash chain (monotonic)
|
||||||
|
optional string previous_receipt = 7; // Receipt ID of previous chain entry
|
||||||
|
bytes signature = 8; // Ed25519 signature
|
||||||
|
}
|
||||||
44
attestation/v2/governance.proto
Normal file
44
attestation/v2/governance.proto
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package substrate.attestation.v2;
|
||||||
|
|
||||||
|
// ─── Layer 3: Governance Claim ──────────────────────────────────────
|
||||||
|
//
|
||||||
|
// Governance state binding: active accords, delegations, and ceremony
|
||||||
|
// state. Hash-chained via governance_epoch for tamper detection.
|
||||||
|
|
||||||
|
message GovernanceClaim {
|
||||||
|
uint32 layer = 1; // MUST be 3
|
||||||
|
bytes governance_state_hash = 2;
|
||||||
|
repeated AccordReference active_accords = 3;
|
||||||
|
repeated DelegationReference active_delegations = 4;
|
||||||
|
uint32 pending_ceremonies = 5;
|
||||||
|
uint64 governance_epoch = 6;
|
||||||
|
bytes previous_governance_hash = 7;
|
||||||
|
bytes platform_claim_hash = 8;
|
||||||
|
bytes software_claim_hash = 9;
|
||||||
|
bytes claim_hash = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AccordReference {
|
||||||
|
string accord_id = 1;
|
||||||
|
bytes accord_hash = 2;
|
||||||
|
string forge_repo = 3;
|
||||||
|
string forge_commit = 4;
|
||||||
|
repeated string parties = 5;
|
||||||
|
string scope = 6; // Summary
|
||||||
|
string activated_at = 7; // ISO 8601
|
||||||
|
optional string expires_at = 8;
|
||||||
|
string qm_receipt = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DelegationReference {
|
||||||
|
string delegation_id = 1;
|
||||||
|
string delegator = 2;
|
||||||
|
string delegate = 3;
|
||||||
|
repeated string scope = 4;
|
||||||
|
string delegator_accord = 5;
|
||||||
|
optional string ceremony_id = 6;
|
||||||
|
string qm_receipt = 7;
|
||||||
|
string expires_at = 8; // ISO 8601
|
||||||
|
}
|
||||||
31
attestation/v2/platform.proto
Normal file
31
attestation/v2/platform.proto
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package substrate.attestation.v2;
|
||||||
|
|
||||||
|
// ─── Layer 1: Platform Claim ────────────────────────────────────────
|
||||||
|
//
|
||||||
|
// Hardware-rooted identity and integrity measurements. Anchored to TPM
|
||||||
|
// Endorsement Key (EK) and backed by TPM Quote over PCR digest.
|
||||||
|
|
||||||
|
message PlatformClaim {
|
||||||
|
uint32 sat_version = 1; // MUST be 2
|
||||||
|
uint32 layer = 2; // MUST be 1
|
||||||
|
string machine_id = 3; // H(TPM EK public key)
|
||||||
|
bytes tpm_ek_public = 4;
|
||||||
|
bytes tpm_ak_cert = 5;
|
||||||
|
bytes pcr_digest = 6;
|
||||||
|
string pcr_bank = 7; // "sha256" or "sha384"
|
||||||
|
repeated uint32 pcr_selection = 8;
|
||||||
|
optional bytes ima_log_hash = 9;
|
||||||
|
bool uefi_secureboot = 10;
|
||||||
|
uint64 boot_timestamp = 11; // TPM monotonic counter
|
||||||
|
bytes nonce = 12;
|
||||||
|
bytes claim_hash = 13; // Computed, not serialized for hashing
|
||||||
|
TpmQuoteBinding tpm_binding = 14;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TpmQuoteBinding {
|
||||||
|
bytes quoted = 1;
|
||||||
|
bytes signature = 2;
|
||||||
|
string signature_algorithm = 3; // "ECDSA-P256"
|
||||||
|
}
|
||||||
26
attestation/v2/sat.proto
Normal file
26
attestation/v2/sat.proto
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package substrate.attestation.v2;
|
||||||
|
|
||||||
|
import "attestation/v2/platform.proto";
|
||||||
|
import "attestation/v2/software.proto";
|
||||||
|
import "attestation/v2/governance.proto";
|
||||||
|
import "attestation/v2/session.proto";
|
||||||
|
|
||||||
|
// ─── Top-level SAT Bundle ───────────────────────────────────────────
|
||||||
|
//
|
||||||
|
// Composite attestation bundle containing all four layers.
|
||||||
|
// Layers are optional — a minimal bundle may contain only L1 + L4.
|
||||||
|
// The explicit `optional` keyword generates has_*() accessors in
|
||||||
|
// codegen (Rust/prost, Python/protobuf) to distinguish absent layers
|
||||||
|
// from present-but-empty layers.
|
||||||
|
|
||||||
|
message SatBundle {
|
||||||
|
uint32 sat_version = 1; // MUST be 2
|
||||||
|
optional PlatformClaim platform_claim = 2;
|
||||||
|
optional SoftwareClaim software_claim = 3;
|
||||||
|
optional GovernanceClaim governance_claim = 4;
|
||||||
|
optional SessionClaim session_claim = 5;
|
||||||
|
bytes sat_hash = 6; // H(L1 || L2 || L3 || L4)
|
||||||
|
string qm_receipt_id = 7; // Top-level QM receipt
|
||||||
|
}
|
||||||
50
attestation/v2/session.proto
Normal file
50
attestation/v2/session.proto
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package substrate.attestation.v2;
|
||||||
|
|
||||||
|
// ─── Layer 4: Session Claim ─────────────────────────────────────────
|
||||||
|
//
|
||||||
|
// Per-session attestation binding actor identity to platform, software,
|
||||||
|
// and governance state. Posture is verifier-computed, not self-asserted.
|
||||||
|
|
||||||
|
message SessionClaim {
|
||||||
|
uint32 layer = 1; // MUST be 4
|
||||||
|
string session_id = 2; // UUIDv7
|
||||||
|
ActorContext actor = 3;
|
||||||
|
PostureEvidence posture_evidence = 4;
|
||||||
|
PostureLevel posture_level = 5;
|
||||||
|
string timestamp = 6; // ISO 8601
|
||||||
|
bytes nonce = 7;
|
||||||
|
bytes platform_claim_hash = 8;
|
||||||
|
bytes software_claim_hash = 9;
|
||||||
|
bytes governance_claim_hash = 10;
|
||||||
|
bytes claim_hash = 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ActorContext {
|
||||||
|
string actor_id = 1; // OIDC sub or SPIFFE ID
|
||||||
|
string actor_type = 2; // "human" | "agent" | "system" | "node"
|
||||||
|
string auth_method = 3; // "oidc" | "oidc+entra" | "spiffe" | "service_account"
|
||||||
|
optional string delegated_by = 4;
|
||||||
|
optional string delegation_id = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PostureEvidence {
|
||||||
|
bool platform_attested = 1;
|
||||||
|
string platform_method = 2;
|
||||||
|
bool software_verified = 3;
|
||||||
|
string software_method = 4;
|
||||||
|
bool governance_bound = 5;
|
||||||
|
string governance_method = 6;
|
||||||
|
bool identity_verified = 7;
|
||||||
|
string identity_method = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum PostureLevel {
|
||||||
|
POSTURE_LEVEL_UNSPECIFIED = 0;
|
||||||
|
POSTURE_LEVEL_NONE = 1;
|
||||||
|
POSTURE_LEVEL_LOCAL = 2;
|
||||||
|
POSTURE_LEVEL_VERIFIED = 3;
|
||||||
|
POSTURE_LEVEL_GOVERNED = 4;
|
||||||
|
POSTURE_LEVEL_ATTESTED = 5;
|
||||||
|
}
|
||||||
29
attestation/v2/software.proto
Normal file
29
attestation/v2/software.proto
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package substrate.attestation.v2;
|
||||||
|
|
||||||
|
// ─── Layer 2: Software Claim ────────────────────────────────────────
|
||||||
|
//
|
||||||
|
// Software provenance and capability declaration. Binds the running
|
||||||
|
// image to its build pipeline via QM-notarized build receipts.
|
||||||
|
|
||||||
|
message SoftwareClaim {
|
||||||
|
uint32 layer = 1; // MUST be 2
|
||||||
|
string image_id = 2;
|
||||||
|
bytes image_hash = 3;
|
||||||
|
bytes capability_manifest = 4; // H(manifest JSON)
|
||||||
|
repeated string capabilities = 5; // Informational
|
||||||
|
BuildProvenance build_provenance = 6;
|
||||||
|
string qm_build_receipt = 7;
|
||||||
|
bytes platform_claim_hash = 8; // L1 binding
|
||||||
|
bytes claim_hash = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BuildProvenance {
|
||||||
|
string source_repo = 1;
|
||||||
|
string source_commit = 2;
|
||||||
|
string builder_identity = 3; // SPIFFE ID or OIDC sub
|
||||||
|
string build_timestamp = 4; // ISO 8601
|
||||||
|
bool build_reproducible = 5;
|
||||||
|
uint32 builder_count = 6;
|
||||||
|
}
|
||||||
9
buf.yaml
Normal file
9
buf.yaml
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
version: v2
|
||||||
|
modules:
|
||||||
|
- path: .
|
||||||
|
lint:
|
||||||
|
use:
|
||||||
|
- STANDARD
|
||||||
|
breaking:
|
||||||
|
use:
|
||||||
|
- FILE
|
||||||
Loading…
Reference in a new issue