An audit reading raw signing keys is correct but unreadable. The Roster maps known principals' keys to their labels and kinds, so a record renders "alice (human)" / "granite-reviewer (agent)" instead of a bare did:key — while an unknown signer stays fully traced by its did:key, just unnamed. It is a NAMING layer, not a TRUST layer, and the docs say so plainly: the key is the authoritative trace; a roster entry is a claim by whoever maintains the file that a key belongs to a label — asserted, not cryptographically proven (the status of /etc/hosts or SSH known_hosts). Resolution never changes what an artifact verifies; it only renders who a verified key is called. register() dedupes on key (the maintainer's latest naming wins); resolve / resolve_did / describe read it; load_or_default / save persist it as plain JSON (public keys and labels only — no secrets). Plus a free did_key(&[u8;32]) so any artifact field can be rendered without constructing a Principal. Runnable: `cargo run -p joule-code-identity --example audit` resolves an author and two reviewer keys to names, and shows an unknown signer still traced. 6 tests; example + clippy clean. Co-Authored-By: Claude Opus 4.8 <[email protected]>
29 lines
1.5 KiB
Rust
29 lines
1.5 KiB
Rust
//! Audit display: resolve the raw signing keys in a methodology record to
|
|
//! human-readable principals via a roster.
|
|
//!
|
|
//! Run: `cargo run -p joule-code-identity --example audit`
|
|
|
|
use joule_code_identity::{did_key, ActorKind, Identity, Roster};
|
|
|
|
fn main() {
|
|
// three distinct principals — an author and two reviewers
|
|
let alice = Identity::from_seed([1; 32], "[email protected]", ActorKind::Human);
|
|
let structural = Identity::from_seed([2; 32], "structural-reviewer", ActorKind::Agent);
|
|
let semantic = Identity::from_seed([3; 32], "granite-reviewer-v1", ActorKind::Agent);
|
|
|
|
// the roster: the team's naming of known signers (a convention, not a trust root)
|
|
let mut roster = Roster::default();
|
|
roster.register(alice.principal());
|
|
roster.register(structural.principal());
|
|
roster.register(semantic.principal());
|
|
|
|
// an op's author key and two reviewer keys, as they'd appear in artifacts
|
|
println!("op authored by: {}", roster.describe(&alice.verifying_key()));
|
|
println!("spec-compliance: {}", roster.describe(&structural.verifying_key()));
|
|
println!("quality review: {}", roster.describe(&semantic.verifying_key()));
|
|
|
|
// a signer the roster doesn't name is still fully traced by its did:key
|
|
let stranger = Identity::from_seed([9; 32], "?", ActorKind::Agent);
|
|
println!("an unknown signer: {}", roster.describe(&stranger.verifying_key()));
|
|
println!(" (its trace is authoritative regardless: {})", did_key(&stranger.verifying_key()));
|
|
}
|