Skip to content

AxonFlow v9.11.0 — streaming prompt-DLP, seam-capability obligations & fleet-identity fixes

Choose a tag to compare

@saurabhjain1592 saurabhjain1592 released this 18 Jul 00:00
· 29 commits to main since this release
59bb4e5

[9.11.0] - 2026-07-17 (streaming prompt-DLP, seam-capability obligations & Path B fleet-identity fixes)

Makes inline prompt-DLP work on streaming LLM chat, moves the "what happens when a seam can't redact" decision from the enforcement point back into the platform behind an org-configurable posture, closes a class of governance-signal gaps where a matched PII policy could return a bare allow, and fixes the SSO/SCIM org-key and role-seeding defects that blocked fleet OIDC (Path B). Migrations core/144core/147 (existence-guarded, with down migrations). Three deliberate behavior changes — see Changed.

Added

  • Streaming-safe ext_proc request redaction for SSE completions (Enterprise). (Enterprise) The axonflow-gateway-adapters ext_proc seam now validates gateway body modes per direction instead of OR-ing them: requestBodyMode: buffered + responseBodyMode: none is accepted under a new adapter-side opt-in, AXONFLOW_EXTPROC_RESPONSE_GOVERNANCE=off (default buffered keeps today's fully-governed contract; any other value refuses to boot). On such a leg the prompt is still decided and engine-redacted in full before the provider sees it — deny blocks pre-stream, AXONFLOW_FAIL_MODE and the body-size bound unchanged — while the completion streams back as SSE with no adapter latency. The response body is not scanned on an opted-in none leg; the posture is logged at startup and once per stream. This is the seam for inline prompt-DLP on streaming LLM chat, which previously required disabling body inspection entirely.
  • Seam-capability–aware obligations + obligation_fallback posture (Enterprise). (Enterprise) POST /api/v1/decide now emits only the obligations the calling seam can fulfill: a PEP advertises its seam via DecideRequest.fulfillment_capabilities (vocabulary request_body_redaction, request_header_mutation; a capability-aware seam always advertises ≥1). A request-body redaction suppressed on a non-body-capable seam (e.g. Envoy ext_authz, headers-only) applies the org's new obligation_fallback detection-posture category — log (default: allow, no obligation, canonical audit row records the suppressed redaction + detected categories) or block (deny) — resolved server-side from the org, never from the request. Absent/empty capabilities = legacy caller, byte-identical pre-9.11.0 behavior (all SDKs unaffected). The gateway adapter's local allow → 403 conversion is deleted; a never-fires fail-closed backstop remains for platform-version skew. Advertised as capability seam_capability_decisioning. Portal: Settings → Governance → Detection Posture; migration core/144.
  • Per-org fleet system roles seeded + non-fleet SCIM role mappings rejected (Enterprise). (Enterprise) Every organization now has the six fleet system roles (admin, owner, policy_admin, developer, member, viewer) via an org-creation trigger + one-time backfill (core/146), so GET /api/v1/scim/roles returns a mappable set and Path B group→role mapping works on every org. Mapping a SCIM group to a non-fleet role name is rejected with 400 instead of silently dropping members to least privilege.
  • caller_name replaces the misnamed tool_type on the tool-call audit surface (Community). (Community) The audit_tool_call MCP tool and the orchestrator ToolCallAuditEntry gain a caller_name field identifying which client/integration made the call (e.g. claude_code, codex, cursor, openclaw). tool_type — which every real caller used to identify itself, never to classify a tool — is soft-deprecated: still accepted as a legacy input fallback, but no longer authoritative. The value is resolved centrally in the orchestrator through the chain caller_name → legacy tool_type → an "unknown" terminal default; an unidentified caller is no longer attributed to the specific client claude_code. New audit rows write policy_details.caller_name and no longer write policy_details.tool_type. SIEM impact: consumers keying on policy_details.tool_type for tool-call attribution must move to policy_details.caller_name; unattributed calls now read caller_name = "unknown" rather than tool_type = "claude_code". Historical rows are not backfilled, and the WCP/HITL plane still writes a genuine tool_type call-kind (function/mcp/api), which is unaffected. In the portal audit detail (Enterprise), a new-style row surfaces its client under a Client row while a WCP tool_type stays under Tool type — the two render as independent rows.
  • Response-plane two-field tool identity on check-output (Community). (Community) MCPCheckOutputRequest gains a tool field (mirroring the check-input server/tool split added in 9.10.0), threaded into the response-plane capability-scoping identity so it stays server.tool once the langgraph de-concatenation SDKs — which send bare server plus a tool key the platform previously ignored — ship. Without it those SDKs degrade response-plane scoping to server, re-running execution-class detectors on document-classified tool output and regressing the documentation false-positive hardening for LangGraph users.
  • Client support for caller_name (dual-send). The Claude Code, Cursor, Codex, and OpenClaw plugins add caller_name to their audit_tool_call payloads, dual-sent alongside the legacy tool_type for the deprecation window. Attribution is exact on a 9.11.0+ platform (where caller_name wins) and unchanged on any pre-9.11.0 platform (where the legacy tool_type still attributes the row), so the plugin minors can ship independently of a customer's platform upgrade without an attribution regression; tool_type is dropped in a later plugin release once the platform floor includes this change. Ships as Claude Code 1.11.0, Cursor 1.7.0, Codex 1.7.0, OpenClaw 2.8.0; /health recommendations advertise these plus the 9.0.0 SDK majors (go/python/typescript/java — langgraph de-concatenation; rust unchanged at 0.8.1; min floors unchanged).

Changed

  • Behavior change — ext_proc responseBodyMode: none now requires the adapter opt-in (Enterprise). (Enterprise) Earlier adapters accepted a none response advertisement silently (the response plane simply never ran), so a gateway-config edit alone could switch response governance off. A none leg is now rejected fail-closed unless the adapter runs with AXONFLOW_EXTPROC_RESPONSE_GOVERNANCE=off — deployments already running responseBodyMode: none must set the variable when upgrading the adapter. Partial modes (bufferedPartial, streamed, fullDuplexStreamed) remain rejected in both directions and both postures.
  • Behavior change — pii-indonesia is now evaluated on the proxy and OpenAI-compatible planes (Community). (Community) Those planes hand-listed their PII categories and omitted pii-indonesia; all request planes now converge on one canonical PII category set. Under the default redact posture a matched KTP/NIK is now redacted on those planes (previously forwarded untouched); under a block posture those planes now deny KTP/NIK traffic they previously forwarded — the largest-impact change in this release; review your Indonesian-PII posture before upgrading. Under warn/log these planes gain evaluation + telemetry parity only (no new redactions). Relatedly, warn/log PII postures no longer silently redact — they emit an advisory reason and leave content unmodified.
  • Behavior change — headers-only seams default to log, not deny, on an unmaskable redaction (Enterprise). (Enterprise) Where the gateway adapter previously converted an allow-with-redaction into a local 403 on a headers-only seam, the platform now applies the org's obligation_fallback posture, default log (allow + audited suppressed-redaction). Set obligation_fallback = block to restore deny-on-unmaskable.
  • Advertised plugin recommendations updated to the published v9.10.0-train versions — claude-code 1.10.0, cursor 1.6.0, codex 1.6.0, openclaw 2.7.0 (claude-desktop stays 0.3.1); min floors unchanged.

Fixed

  • Matched PII policy can no longer yield a bare allow (Community). (Community) /api/v1/decide returned allow with no obligation and no reason while evaluated_policies named a matched, block-configured Indonesian KTP policy: the obligation bridge classified PII with a duplicate agent-local category switch that omitted pii-indonesia and derived redaction from category rather than the resolved action. The duplicate predicate is deleted (converged on the shared prefix predicate), the verdict mapping is action-aware (redact ⇒ obligation, warn/log/other ⇒ advisory reason, block ⇒ deny), and a registry cross-check + class guard pin that a matched pii-* policy always produces a governance signal. Code-only.
  • In-VPC Path B / OIDC: SSO configuration org key decoupled from tenant id (Enterprise). (Enterprise) The portal wrote a deployment-collapsed tenant sentinel into sso_configurations.org_id (the RLS isolation key), so org-scoped readers missed the row and the fleet OIDC verifier rejected every in-VPC Path B token fail-closed. org_id now always carries the real org; migration core/145 repairs sentinel rows in place.
  • SCIM role_assignments.org_id keyed on the real org, not the portal tenant id (Enterprise). (Enterprise) The SCIM plane wrote role_assignments.org_id from the session tenant while the fleet role resolver reads by authenticated org — where the two diverge, Path B developers silently resolved to least privilege. Writes now key on the real org across both the session and bearer/IdP-sync paths (the bearer tenant→org lookup runs on the BYPASSRLS admin pool and fails closed on resolution errors), SyncUserRoles validates mapped roles under the org, and migration core/147 repairs historically mis-keyed rows (skipped rows are reported for operator re-sync).
  • Migration enterprise/117 made idempotent + migration-wait hardened (Community). (Community) Five CREATE POLICY + two CREATE TRIGGER statements had no drop-guards, so a container recreate mid-migration left objects created but the migration unrecorded — bricking every subsequent boot; the SDK-smoke workflow also polled /health, which the agent serves before migrations complete. Both layers fixed.

Full release notes: https://docs.getaxonflow.com/docs/releases/v9-11-0
Upgrade guidance: see the Upgrading section of the release notes. AxonFlow is source-available under BSL 1.1.