v3.10.34 β Security ADR P1 (ADR-144 / ADR-145 / ADR-146)
v3.10.34 β Security ADR P1 implementations (ADR-144, ADR-145, ADR-146)
Three independent P1 components landing the first concrete code from the three security ADRs filed earlier today (ADR-144 / ADR-145 / ADR-146). Each is OFF by default β strict mode becomes default in v4.0 β so existing pipelines keep their exact behaviour.
ADR-144 P1 β AgentAuthorizationPropagator (closes #2248 P1)
Action-layer security. New module: @claude-flow/security/authorization/propagator.
AuthScopeenvelope (principal, granted tools/servers, delegation depth, expiry)wrapOutbound: monotonically-reducing scope β newly granted tools must be a subset of the holder's; depth decrements by β₯1; expiry checkedcheckToolCall: typed decisions (tool-not-in-scope/server-not-in-scope/scope-expired/delegation-depth-exhausted) β never throws, telemetry-friendlyverifyServerAuth: fail-closed on missing / empty credentials (P1 permissive accept for non-empty; P4 wires the real validator)- Provenance buffer ring-bounded, ready for the P5 telemetry sink
makeLegacyPermissiveScopemigration shim for legacy callers
18 unit tests covering every invariant. Verified against published 3.10.34:
granted reduced from 3 to 1 β depth 2
escalation refused: scope-cannot-grow
ADR-145 P1 β PluginIntegrityVerifier (closes #2254 P1)
Install-layer security. New module: @claude-flow/security/plugins/integrity-verifier. Plus a placeholder v3/@claude-flow/cli/src/plugins/trust/trust-anchors.json for the official-plugin signing key (to be filled in P1.1 when the publish flow is wired).
- Canonical JSON serialisation (deterministic key order) + SHA-256 manifest hash
- Ed25519 detached signature verification via
@noble/ed25519(probe-and-fall-back β mirrorsverify.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. Verified end-to-end:
canonicalize a-then-b == b-then-a: true
hashManifest deterministic: true
unsigned manifest β signature-missing
ADR-146 P2 β Guardrail call site in MCP dispatch (closes #2149 follow-up P2)
Content-layer security. Wires the ADR-131 ToolOutputGuardrail class into the single MCP dispatch chokepoint at mcp-client.ts::callMCPTool.
- Lazy-resolves
@claude-flow/securityso the cold-import cost doesn't hit every CLI invocation; falls back to no-op if the module isn't installed (third-party consumers of@claude-flow/cli) - 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 a typed marker:
<rejected-by-guardrail tool="X" category=Y>so callers can surface the rejection rather than silently dropping content - Off by default.
CLAUDE_FLOW_STRICT_GUARDRAIL=trueturns it on; precedence is 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). Verified end-to-end:
$ CLAUDE_FLOW_STRICT_GUARDRAIL=true npx ruflo β¦
action: reject (on known indirect-injection payload)
Layering β three orthogonal boundaries
Install boundary ADR-145 β Is the code trustworthy enough to load?
Memory-write ADR-145 β Is this agent allowed to write here? (P3+)
Action boundary ADR-144 β Is this agent allowed to act, on this server, now?
Content boundary ADR-131 / ADR-146 β Does this content contain hijack instructions?
Each ADR has its own phased rollout (P1 here; P2-P5 follow). All three flip to default-on in v4.0.
Install
npx ruflo@latest --version # β ruflo v3.10.34 (33 ms β #2256 fast path intact)All 9 dist-tag pointers (latest / alpha / v3alpha across @claude-flow/cli, claude-flow, ruflo) at 3.10.34. @claude-flow/security published as 3.0.0-alpha.9 with all three dist-tags repointed.
What didn't change
--versioncold-start: still 33 ms (the #2256 fast path inbin/cli.jsandruflo/bin/ruflo.jsis unaffected)- MCP stdio cleanliness: still pure JSON-RPC on stdout (ADR-146 P2 deliberately doesn't touch stderr routing)
- All 4 audits + 2 regression smokes still pass locally β guards added in 3.10.33 (YAML lint + router regex) continue to cover their cases