Commit Graph

1 Commits

Author SHA1 Message Date
ruv 1c98cbee6e feat(security): P1 implementations for ADR-144, ADR-145, ADR-146
Three independent P1 components, each scoped to a single PR-sized change.
All three are off by default — flips become default in v4.0 — so existing
pipelines keep their exact behaviour.

ADR-144 P1 — AgentAuthorizationPropagator (#2248)
  v3/@claude-flow/security/src/authorization/propagator.ts (new)
  • AuthScope envelope (principal, granted tools/servers, delegation depth, expiry)
  • wrapOutbound: monotonically-reducing scope, depth-decrement, expiry check
  • checkToolCall: typed decisions (tool-not-in-scope / server-not-in-scope /
    scope-expired / delegation-depth-exhausted) — never throws, telemetry-friendly
  • verifyServerAuth: fail-closed on missing/empty credentials (P1 permissive
    accept for non-empty — P4 wires real validator)
  • Provenance buffer ring-bounded for P5 telemetry sink
  • makeLegacyPermissiveScope shim for legacy-mode migrations
  18 unit tests covering every invariant; all pass.

ADR-145 P1 — PluginIntegrityVerifier (#2254)
  v3/@claude-flow/security/src/plugins/integrity-verifier.ts (new)
  v3/@claude-flow/cli/src/plugins/trust/trust-anchors.json (new placeholder)
  • Canonical JSON serialisation (deterministic key order) + SHA-256 manifest hash
  • Ed25519 detached signature verification via @noble/ed25519 (probe-and-fall-
    back, mirrors verify.mjs #1880 pattern so untrusted environments skip
    rather than throw)
  • Trust-anchor allowlist with exact / wildcard scope matching + expiry
  • Structured VerificationStatus (pass / signature-missing / signature-invalid
    / manifest-hash-mismatch / unknown-signer / signer-expired)
  • Stage-2 semantic-intent scan (SCH defence) lands in P2
  13 unit tests including the round-trip sign→verify and tamper-flip cases.

ADR-146 P2 — guardrail call site in MCP dispatch (#2149 follow-up)
  v3/@claude-flow/cli/src/mcp-client.ts — patch callMCPTool
  • Lazy-resolves @claude-flow/security so cold-import cost doesn't hit
    every CLI invocation; falls back to no-op if module unavailable
  • Walks the result object one level deep (matches the flat-record shape
    of every existing tool — deeper traversal would change the p99 latency
    contract)
  • Rejected fields replaced with typed marker: '<rejected-by-guardrail
    tool="X" category=Y>' so callers can surface the rejection rather than
    silently dropping
  • Off by default. CLAUDE_FLOW_STRICT_GUARDRAIL=true turns it on; precedence
    documented inline so the env-var audit passes without an escape-hatch entry.
  4 wiring tests (legacy passthrough, strict-mode reject of known injection,
  strict-mode passthrough on safe content, non-object results pass through).

Security index exports updated for all three. Builds clean (tsc with no
errors). All 4 audits + 2 regression smokes pass locally.

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-06-02 05:44:29 -04:00