Skip to content

security: close RT-002 and harden the verify path (#263)#264

Merged
bordumb merged 2 commits into
mainfrom
dev-security
Jun 11, 2026
Merged

security: close RT-002 and harden the verify path (#263)#264
bordumb merged 2 commits into
mainfrom
dev-security

Conversation

@bordumb

@bordumb bordumb commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes the red-team audit's systemic CRITICAL RT-002 (stateless verify paths replayed KELs by structure only, never checking event signatures) plus the surrounding findings, and hardens the verify path at the type level (#263).

RT-002 — authenticate KEL signatures at every untrusted boundary

  • Storage: all RegistryBackend impls (Git/Fake/Postgres/Arc) persist + expose CESR signature attachments; the lossy trait defaults that silently dropped them (the root cause) are removed.
  • CI --identity-bundle: IdentityBundle carries kel_attachments; load_bundle_trust authenticates via validate_signed_kel (+ stripped/forged-signature negative e2e).
  • Org air-gapped bundle: offline_verify authenticates the org KEL + each delegated member KEL.
  • WASM validateKelJson: takes attachments, routes through validate_signed_kel, fails closed.
  • A.0 lint: xtask check-verify-path-completeness (CI-wired) gates structural replay on the verify surfaces.

#263 — type-level hardening

  • P1: validate_kel* are pub(crate); the only cross-crate structural-replay surface is auths_keri::TrustedKel. Bare-&[Event] structural replay outside auths-keri is now a compile error.
  • P2: KelSealIndex replaces three duplicate DelegatorKelLookup impls.
  • P3: IdentityBundle.kel is Vec<Event> (not Vec<serde_json::Value>); named BundleKel.

Other findings

A.2 (i==d on replay), A.3/A.4/A.5, B.1 (SCIM allowlist), B.2, C.1/C.3/C.4, D.1, E.1/E.2, F.3/F.4.

Tooling

E.2's fips/cnsa compile_error! makes --all-features uncompilable, so the clippy hook + CI clippy/nextest now lint/test the bulk workspace --all-features minus the 5 dual-provider crypto crates, then exercise those 5 under each provider (fips, cnsa) separately.

Merge note

The merge of main (0.1.3) resolved a verify_commit.rs trust-precedence conflict in favor of the RT-005/A.4 fix: a --identity-bundle is evidence-only and must match an independent pin; it never self-pins its own root (main's side had reverted to the self-pinning vuln — intentionally not taken).

Residuals tracked in #262 (remote/oobi/WASM signature-carrying transports) and #263 (P1 design follow-ups).

bordumb added 2 commits June 11, 2026 11:26
Close the red-team audit's systemic CRITICAL (RT-002: stateless verify paths
replayed KELs by structure only and never checked event signatures) plus the
surrounding findings, then harden the verify path at the type level so the
class cannot recur.

RT-002 — authenticate KEL signatures at every untrusted boundary:
- Storage: all RegistryBackend impls (Git/Fake/Postgres/Arc) persist + expose
  CESR signature attachments; the lossy trait defaults that silently dropped
  them (the root cause) are removed and the methods are now required.
- CI --identity-bundle: IdentityBundle carries kel_attachments; load_bundle_trust
  authenticates via validate_signed_kel before use (+ stripped/forged-signature
  negative e2e).
- Org air-gapped bundle: offline_verify authenticates the org KEL and each
  delegated member KEL (+ forged-signature negative test).
- WASM validateKelJson: takes a parallel attachments arg, routes through
  validate_signed_kel, fails closed on absent/short attachments.
- A.0 lint: xtask check-verify-path-completeness (CI-wired) gates structural
  replay on the verifier + CLI-verify surfaces.

#263 — architectural hardening:
- P1 (type level): validate_kel/_with_lookup/_with_receipts/_with_policy are
  pub(crate) and the replay_kel alias is removed; the only cross-crate
  structural-replay surface is auths_keri::TrustedKel (minted via
  from_trusted_source for trusted-local reads, or implied by validate_signed_kel).
  Bare-&[Event] structural replay outside auths-keri is now a compile error.
  auths-id mints TrustedKel at its registry-read boundary; the lint gates the
  from_trusted_source assertion on verify paths.
- P2: KelSealIndex (one O(1) index) replaces three duplicate DelegatorKelLookup
  impls (commit / presentation / offline-org verify).
- P3: IdentityBundle.kel is Vec<Event>, not Vec<serde_json::Value>, which moves
  trusted_root_from_bundle onto typed accessors; the threaded (String, Vec<Event>)
  becomes a named BundleKel.

Other findings closed: A.2 (i==d on replay), A.3/A.4/A.5, B.1 (SCIM capability
allowlist, empty=deny), B.2, C.1/C.3/C.4, D.1, E.1/E.2, F.3/F.4.

Tooling: E.2's fips/cnsa compile_error! makes --all-features uncompilable, so the
clippy pre-commit hook + CI clippy/nextest now lint/test the bulk workspace with
--all-features minus the five dual-provider crypto crates, then exercise those
five under each provider (fips, cnsa) separately.

Residuals tracked in #262 (remote/oobi/WASM signature-carrying transports) and
#263 P3.3.
Resolved the verify_commit.rs trust-precedence conflict in favor of the
RT-005 / A.4 security fix: a `--identity-bundle` is EVIDENCE ONLY and must
match an independent pin (`.auths/roots` or the verifier's own self-trust);
it never self-pins its own root. main's side had reverted to
`pinned_roots.push(bundle_root)` (the RT-005 self-pinning vuln) — that is
intentionally NOT taken. All other main 0.1.3 changes are adopted (FIPS
error contract, release/CI workflow bumps, status snapshot, lockfiles).

verify_identity_bundle e2e: 5/5 pass; workspace builds; RT-002 lint green.
@vercel

vercel Bot commented Jun 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
auths Ready Ready Preview, Comment Jun 11, 2026 10:45am

@github-actions

Copy link
Copy Markdown

Auths Commit Verification

Commit Status Details
59779b27 ❌ Failed Commit carries no Auths-Id/Auths-Device trailer. The prepare-commit-msg hook installed by auths init adds these on every commit — if this repo sets its own core.hooksPath (e.g. husky), the hook is bypassed; run auths doctor to check. Backfill existing commits with auths sign <ref> (rewrites the commit).
427cdc40 Skipped merge commit

Result: ❌ 0/2 commits verified (1 skipped)


How to fix

Commit 59779b27 has no Auths signature (no Auths-Id/Auths-Device trailer).

1. Install auths

macOS: brew install auths
Linux: Download from releases

2. One-time setup (creates your identity and configures Git)

auths init

3. Sign this branch and push

auths sign origin/main..HEAD
git push --force-with-lease

For CI to verify the signer, commit an identity bundle:

auths id export-bundle --alias main --output .auths/ci-bundle.json --max-age-secs 31536000

Quickstart →

@bordumb bordumb merged commit 427cdc4 into main Jun 11, 2026
18 of 20 checks passed
@bordumb bordumb deleted the dev-security branch June 11, 2026 12:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant