Problem
Epic B (fn-145) introduced a second, disconnected trusted-root store. There are now two pin mechanisms that don't talk to each other:
auths trust pin --did … --key … writes to PinnedIdentityStore (PinnedIdentityStore::default_path(), per-machine, global) — records {did, public_key_hex, curve, kel_tip_said, trust_level}.
crates/auths-cli/src/commands/trust.rs:181 (handle_pin)
auths verify reads trusted roots from <git-toplevel>/.auths/roots — a plain newline-delimited did:keri: list, seeded by auths init.
crates/auths-cli/src/commands/verify_commit.rs (load_project_pinned_roots) → auths_sdk::workflows::roots::load_pinned_roots
- seeded in
crates/auths-cli/src/commands/init/mod.rs (add_pinned_root)
Consequence: auths trust pin <did> does not make auths verify trust that root — verify only consults .auths/roots. A user who pins via the documented auths trust command and then runs auths verify gets RootNotPinned. This is a footgun (hit while testing Epic B: had to echo … >> .auths/roots by hand because auths trust pin had no effect on verification).
Why it's split
The two stores have legitimately different scopes:
PinnedIdentityStore = per-machine TOFU trust (global, carries key + curve + kel tip).
.auths/roots = per-repo committed trust declaration (travels with the repo; just the DID).
But verify consulting only one of them is incoherent.
Proposed directions (pick one)
auths verify consults both — union of .auths/roots (repo layer) and PinnedIdentityStore (machine layer). Probably the right model: a repo can declare roots and a machine can pin roots it trusts.
auths trust pin also writes .auths/roots when run inside a repo (and auths trust list/remove reflect it).
- Unify on one store and migrate the other.
At minimum there should be a CLI path to add a root to .auths/roots (today only auths init seeds it — there's no auths command to pin a root for an existing identity in a new repo; see the related KEL-validation issue).
Context
Surfaced during Epic B (#200, KEL-native verification). .auths/roots is the Option-B successor to allowed_signers.
Problem
Epic B (fn-145) introduced a second, disconnected trusted-root store. There are now two pin mechanisms that don't talk to each other:
auths trust pin --did … --key …writes toPinnedIdentityStore(PinnedIdentityStore::default_path(), per-machine, global) — records{did, public_key_hex, curve, kel_tip_said, trust_level}.crates/auths-cli/src/commands/trust.rs:181(handle_pin)auths verifyreads trusted roots from<git-toplevel>/.auths/roots— a plain newline-delimiteddid:keri:list, seeded byauths init.crates/auths-cli/src/commands/verify_commit.rs(load_project_pinned_roots) →auths_sdk::workflows::roots::load_pinned_rootscrates/auths-cli/src/commands/init/mod.rs(add_pinned_root)Consequence:
auths trust pin <did>does not makeauths verifytrust that root — verify only consults.auths/roots. A user who pins via the documentedauths trustcommand and then runsauths verifygetsRootNotPinned. This is a footgun (hit while testing Epic B: had toecho … >> .auths/rootsby hand becauseauths trust pinhad no effect on verification).Why it's split
The two stores have legitimately different scopes:
PinnedIdentityStore= per-machine TOFU trust (global, carries key + curve + kel tip)..auths/roots= per-repo committed trust declaration (travels with the repo; just the DID).But verify consulting only one of them is incoherent.
Proposed directions (pick one)
auths verifyconsults both — union of.auths/roots(repo layer) andPinnedIdentityStore(machine layer). Probably the right model: a repo can declare roots and a machine can pin roots it trusts.auths trust pinalso writes.auths/rootswhen run inside a repo (andauths trust list/removereflect it).At minimum there should be a CLI path to add a root to
.auths/roots(today onlyauths initseeds it — there's noauthscommand to pin a root for an existing identity in a new repo; see the related KEL-validation issue).Context
Surfaced during Epic B (#200, KEL-native verification).
.auths/rootsis the Option-B successor toallowed_signers.