Skip to content

v9.7.0 — fail-closed hardening + SDK/plugin compat refresh

Choose a tag to compare

@saurabhjain1592 saurabhjain1592 released this 10 Jul 01:18
b6687a9

[9.7.0] - 2026-07-10 (fail-closed hardening sweep, per-client version telemetry, SDK/plugin compat refresh)

Additive minor. v9.7.0 ships the hardening found by an adversarial end-to-end sweep of the platform, portal, and all five SDKs. The policy engine's request plane now fails closed when policies cannot be loaded, the gateway pre-check no longer executes a query it has just blocked, MCP check-output now tells a policy-enforcement point whether redaction actually ran, and the portal session drill-down that v9.6.1 enabled at the API is now reachable from the UI and honored on export. Enterprise deployments gain per-client version-distribution telemetry, and the advertised SDK/plugin compatibility matrix is refreshed: SDKs 8.5.1 (Rust 0.8.1 joins the matrix), Claude Code plugin 1.9.1, and the Claude Desktop governance proxy joins at 0.3.1. No migration.

Added

  • Per-client version-distribution telemetry. (Enterprise) Self-hosted Enterprise deployments previously had no visibility into which client versions their fleet runs — how the Claude Code plugin's version drift went unnoticed, and a total blind spot for the Claude Desktop proxy. The agent now records the validated X-Axonflow-Client client id + version pair on the decide and MCP check-output planes into a new Prometheus counter, axonflow_client_version_requests_total{plane, client, client_version}, with an axonflow_client_version_dropped_total{reason} companion for absent/invalid/over-cap values. Values are shape-validated and series-capped so a hostile header cannot mint unbounded label series, and the capture is telemetry-only — it is never consulted for auth or a verdict. Community builds compile the capture to a no-op and register no series. Advertised as the client_version_telemetry capability. The Claude Desktop proxy v0.3.1 companion release identifies itself as mcp-proxy/<version> on both planes.
  • Rust SDK and the Claude Desktop proxy join the /health compatibility matrix. (Community) /health on both ports now advertises min/recommended versions for the Rust SDK (floor 0.7.0 — the first Rust release speaking the Decision Mode PEP contract — recommended 0.8.1) and for the Claude Desktop MCP governance proxy (floor 0.2.0 — the first release with engine-backed, unconditionally fail-closed response redaction — recommended 0.3.1), so both clients can run the same upgrade-warning gate the other SDKs and plugins already use.

Fixed

  • The request plane now fails closed when policies cannot be loaded. (Community) On a policy-load / database-unavailable error, the shared policy engine's request plane logged the failure and allowed the request through, silently disabling SQL-injection, dangerous-command, and PII-block enforcement on every request-plane gate (decide, MCP check-input, MCP resources/query and tools/execute, the gateway pre-check, and the OpenAI-compat gateway) for the duration of the outage. The request plane has no "return unprocessed content" middle ground — a request either proceeds ungoverned or is blocked — so it now blocks, symmetric with the response plane's v9.4.x fail-closed hardening, and the result carries an evaluation-error marker so an availability block is distinguishable from a policy verdict in the audit trail.
  • MCP check-output now reports whether redaction actually ran. (Enterprise) POST /api/v1/mcp/check-output never populated the redaction_evaluated response field the SDKs' PEP contract depends on ("fail closed when false — the redactor did not run, so absent redacted output cannot be trusted as nothing to mask"). The field was always false on the wire, forcing a strict response-phase PEP to either over-block every redaction or forward output it wrongly believed had been scanned. check-output now emits redaction_evaluated exactly as check-input already did, restoring the advertised two-touch redaction contract.
  • The gateway pre-check no longer returns connector data on a blocked or pending request. (Enterprise) The pre-check handler fetched connector data for requests it had already denied and attached the rows to the approved:false response — a blocked query still executed against the live connector, and a HITL-pending request surfaced data before a human approved it. The connector query now runs only for a clean-approved request; blocked, pending-approval, and approved-with-redaction outcomes return no pre-fetched data.
  • The portal session drill-down is now reachable, and exports honor the active filters. (Enterprise) v9.6.1 fixed the audit-search API's session_id filter, but the customer portal never exposed it: the Log Explorer had no session filter input, the detail panel's Session ID was inert text, and both the portal and orchestrator export paths silently dropped session_id (plus decision_id, policy_name, and override_id) — so a session-filtered "Export" returned the tenant's entire window. The Log Explorer now has a Session ID filter with a ?session_id= deep link, the detail-panel Session ID drills into that session, and CSV/JSON exports apply the same filter set the search does, with session_id as an export column.
  • Retired unavailable Anthropic model defaults. (Community) A retired model id that the Anthropic API now rejects was baked into roughly a dozen fallback surfaces — compose defaults, provider-config code fallbacks, the Anthropic provider's model constants (which the unified router's failover uses), Bedrock adapter defaults, CloudFormation templates, and demo/example routers — so any provider failover through Anthropic (or the equivalent non-region-prefixed Bedrock id) failed with "all providers failed" whenever the primary provider was unavailable. Fallback ids are now centralized in a shared llmdefaults package pinned to current catalog ids (claude-haiku-4-5-20251001, and the region-prefixed us.anthropic.claude-haiku-4-5-20251001-v1:0 on Bedrock), drift tests ban the retired ids from every named config surface, the pricing maps cover the new default ids, and both compose files now map ANTHROPIC_MODEL into the agent environment so the override actually reaches agent-side gateway calls.

Changed

  • Recommended SDK and plugin versions. (Community) /health now recommends SDK 8.5.1 for Python, TypeScript, Go, and Java (Go 8.5.1 fails closed on 4xx auth errors; Python 8.5.1 runs sync interceptors on a persistent event loop and detects AsyncOpenAI clients; TypeScript 8.5.1 authenticates getPlanStatus; Java was already 8.5.1) and Rust 0.8.1, plus Claude Code plugin 1.9.1 (correct on-wire version reporting) and Claude Desktop proxy 0.3.1. This also closes an agent/orchestrator drift — the orchestrator's /health still recommended claude-code 1.8.0 while the agent's advertised 1.9.0. Minimum-version floors are unchanged. All example projects and repo docs are swept to the 8.5.1 / 0.8.1 pins (including several stale doc pins predating 8.5.0).

Full notes: https://docs.getaxonflow.com/docs/releases/v9-7-0