Skip to main content

Policy and Identity Control Plane

AxonFlow decides a governed request with one policy decision engine. In v11.0.0 that engine is the whole system on the enforcement planes listed below: it decides there for every organization, on every deployment and edition, from the first request after the upgrade.

It gives every governed operation the same answer to four questions:

  1. Who or what is acting?
  2. What exact action and resource are involved?
  3. Is the action permitted in the current context?
  4. Which safeguards must be completed before execution?
New in v11.0.0

Before v11 this page described a target architecture that ran beside the legacy system-policy and tenant-policy engines. v11 replaces those engines. If you are upgrading, read the v10 → v11 Migration Guide first: behaviour can differ from v10.x where the two engines disagreed, and that is intended rather than reconciled. For the model explained from end to end, start with The v11 policy and identity model.

What decides a request​

The same engine decides on each enforcement plane in the table below. Each plane is the point where a request reaches AxonFlow:

PlaneWhere a request reaches it
decideDecision Mode: POST /api/v1/decide from your gateway
gateway_requestGateway Mode's pre-check
proxy_requestProxy Mode's POST /api/request: one request check. proxy_tier, the tier check that followed it in v10.x, is retired as an enforcement plane
mcp (request and response)MCP governance: tool input and tool output
openai_compatiblethe OpenAI-compatible gateway
orchestrator_responsethe Orchestrator's response governance on /api/v1/process
orchestrator_requestthe Orchestrator's request routes: POST /api/v1/process and POST /api/v1/plan/execute. Before v11.1.0 these decided under wcp
wcpthe Workflow Control Plane's step gate
mapMulti-Agent Planning

The Agent's POST /api/policies/test previews what Proxy Mode's request check would decide, with the same engine.

There is no decision mode. Nothing selects between an old engine and a new one: there is no off, shadow or enforce, no per-organization opt-in or opt-out, and no process flag. The legacy verdict engines (the system-policy action column, the tier engine and the tenant-policy engine) author no verdict in v11. The detectors they shared with this engine stay, because the engine consumes what they find: PII detection, SQL injection scanning, dangerous-command detection and the country-specific validators.

Two record-and-compare modes from v10.x are gone with it: the decision shadow mode and the identity compatibility mode. Neither engine is compared against the other in v11, because they are different models and no parity between them is promised. A deployment that still sets AXONFLOW_DECISION_SHADOW_MODE, AXONFLOW_IDENTITY_COMPAT_MODE or one of their companion variables refuses to start and names the variable, rather than running with a setting that no longer means anything.

What ships enabled​

AxonFlow ships a set of policies, and in v11 they are enabled from the first boot. The 85 policies that v10.x carried as system policies are compiled into the engine's own policy format and ship with their actions already set.

The actions observe rather than intervene by default:

  • warn or log for most policies, so a match is recorded and visible without changing what the caller receives;
  • redact for sensitive content, chiefly PII in a response and instructions injected into content a model or tool returns;
  • block for a shorter list: dangerous commands and access (among them destructive file-system and shell commands, and credential-file, cloud-metadata and internal-network access), DROP TABLE and TRUNCATE, two SQL-injection patterns, prompt-injection attempts in a request, administrative-table access on the proxy request path, and a few condition-based, country-specific and media policies.

The shipped set also carries the policies v10.x shipped as tenant policies: seeded by AxonFlow and editable by your organization, including the dangerous-command blocks and the DROP TABLE and TRUNCATE guards. They ship on your organization's own policy root, decide from the first boot alongside the platform's, and a policy document your organization publishes starts from them.

Every shipped policy, its category, the planes it applies on and its action is listed in one table, Shipped Policy Posture, so nobody discovers a shipped action by being blocked by it.

An organization that has published nothing runs the shipped set. With no policy document of its own, the engine activates the shipped policies (the platform's and the organization-editable ones) together with the deployment's baseline permissions, composed and signed in the process itself: nothing is written to your database, and no organization key is created. Every request is decided under the shipped actions from the first boot, including on Community. There is no state in which a request is refused because an organization has not written a policy yet.

Each plane runs the policies it can evaluate​

The shipped set is the union of the policies every plane enforces, and a plane activates the subset whose inputs it actually produces. A plane with no media pipeline does not run the media policies; a plane that does not see a response does not run response-phase policies. A few policies carried a different action on different planes in v10.x, and those ship as one policy per action, each bound to the planes that enforced it. The subset is derived from the platform's own declarations when a policy bundle is activated, not configured, and nothing an operator sets can widen or narrow it.

What your organization controls​

Every shipped policy, individually. An organization can disable a shipped policy, re-enable it, and change its action: log, warn, redact or block. The change applies to that organization only. This per-policy control is the product's core control surface: the shipped actions are a default, not a ceiling you have to work around.

A category-wide action override recorded for an organization (for example, pii=redact) also reaches the engine, on the planes that apply organization overrides (the Decision API, Gateway Mode's pre-check, MCP, the OpenAI-compatible route, Proxy Mode's request, the orchestrator's response filter and the policy test surface): the platform's policies in that category decide with the recorded action for that organization. pii reaches the 18 platform pii-* policies, sqli the 38 SQL-injection platform policies, and dangerous_command the four platform policies in security-dangerous, which are the indirect prompt-injection guards. It does not reach the 22 organization-editable policies, among them the dangerous-command, DROP TABLE, TRUNCATE and two SQL-injection blocks; the organization changes those in its own typed policy document.

Policies of its own. An organization authors its own policies as a typed policy document through /api/v1/typed-policies or the portal's Policy Authoring page; see Typed Policy Authoring. Activating a published document replaces the implicit shipped-set bundle for that organization, by digest: the platform policies and the deployment's baseline permissions keep composing beside it, and the document's own content takes the place of the 22 organization-editable policies.

The v10.x write APIs are closed. The legacy system-policy and tenant-policy write routes answer 409 LEGACY_POLICY_WRITE_FROZEN, and the error names the typed route to use instead. The v10.x per-policy override routes (/api/v1/system-policies/{id}/override, /api/v1/system-policies/overrides and their /api/v1/policy-overrides alias) are deprecated with the rest of the legacy system-policy family: the engine does not read what they write, so an override recorded there changes no v11 decision.

No process flag narrows what the engine decides. The detection-scope variables MCP_STATIC_POLICIES_ENABLED, GATEWAY_STATIC_POLICIES_ENABLED, *_STATIC_POLICIES_SKIP_CATEGORIES and MCP_STATIC_POLICIES_CONNECTORS once ran the detectors on fewer categories or connectors. A narrowed detector would leave the engine unable to decide the policies that read it, on every request, so in v11 a narrowing value refuses boot and names the variable. Their default values boot. The controls that remain are per organization: the per-policy switches above and the recorded overrides.

Who the decision is for​

Every decision is evaluated for a principal:

  • A verified user. When a request carries a user token that verifies, the decision is evaluated for that user, through the identity model below.
  • The client credential. When a deployment can verify no per-user identity (Community and Community SaaS), or a request carries none (the OpenAI-compatible route), the authenticated client credential is itself the principal the decision is evaluated for.

On a deployment that verifies user identity, a user token that fails verification is still refused: the credential is admitted as a principal only when there is no user identity, never in place of a bad one. On Community and Community SaaS a presented user token is ignored, and the request is decided for its credential.

Every request's subject is admitted through the identity plane on a deployment that verifies user identity. Authentication runs first: a bad credential or a token whose signature fails is refused 401. Then a user token must come from a declared trust realm, its claims must bind to the credential that authenticated it, and it must be current; a token from an undeclared issuer, or with no issuer, is denied with the reason unknown_realm. When admission cannot reach an answer, for example because a revocation source is unavailable, the request fails closed with a 503 whose message says the identity plane could not establish the request's subject, and the audit row records the cause as subject_unverifiable. This is what the v10.x identity compatibility mode did at enforce, and in v11 it always runs; Identity Compatibility Mode lists what changed.

A licence that names no organization, carrying neither a deployment_id (V3) nor an org_id (V2), refuses boot: requests under it would belong to no organization, so there would be nothing for the engine to decide for.

What is recorded​

Every decision says, on the wire and on its audit row, what produced it:

FieldMeaning
enginethe engine that authored the verdict: anchored, the v11 decision engine
policy_bundlethe digest of the policy bundle that decided: the organization's activated document, or the implicit shipped-set bundle when it has published none
subject_typethe kind of principal the decision was evaluated for: a user, or Client for the client credential
decision_reasonthe engine's machine reason for the verdict, such as explicit_constraint; on the wire it is carried in reasons

The Agent's /health lists the planes it decides on, under decision.enforcing_planes. So "which engine and which policy decided this request" is answered by the record alone, and "which engine decides on this deployment" by the deployment itself.

One request model​

Every authorization request is reduced to four parts:

PartQuestionExample
SubjectWho is asking?Sarah, acting through a finance agent and Jira connector
ActionWhat are they trying to do?Update a Jira issue
ResourceWhat are they acting on?FIN-17 in the Finance project
ContextUnder what circumstances?Corporate network, confidential attachment, current policy version

This follows the Subject-Action-Resource-Context model used by OpenID AuthZEN and standard attribute-based access control. Request context is not a separate category of policy. Time, network, data classification, tool arguments, cost, agent depth and detector findings are typed facts available to the same decision.

That gives an organization one decision meaning across gateways, MCP tools, workflows, connectors and other enforcement points.

Identity means more than a token​

An AI operation often involves several identities:

Sarah
-> Finance Assistant Agent
-> Jira Connector Workload

The control plane models this as an ordered actor chain. The first identity is the person or service on whose behalf access is requested. Each later identity is an intermediary that acted for the previous one.

Adding an intermediary can never increase authority. The effective authority is limited by every actor in the chain, which prevents a low-privilege user from inheriting the power of a high-privilege agent or connector.

Trust realms​

A trust realm describes an organization-scoped identity authority such as Okta, Microsoft Entra ID, a workload identity system, or an AxonFlow-managed agent realm.

It defines more than an issuer URL. It also defines accepted audiences, credential and subject types, signing algorithms and keys, claim mappings, assurance levels, time limits, revocation, and directory capabilities.

A validly signed token from an undeclared or disabled realm is not enough to establish an identity.

Canonical identities​

Users, agents, services, workloads, clients and groups receive immutable, realm-qualified identifiers. An email address or display name remains an alias and is never the security identifier.

This prevents two identity providers from accidentally producing a user or group name that AxonFlow treats as the same authority.

Organization and application identity​

The customer organization and the calling application remain separate concepts:

  • org_id is the hard customer isolation boundary.
  • client_id identifies the application or credential making the call.

An application identifier never becomes a human identity and cannot choose the customer organization through policy input. Where the credential is the principal (see Who the decision is for), it is recorded as a credential principal, not as a user.

For the authentication and provisioning surfaces, see Identity and Access Management and SCIM 2.0 Provisioning.

Four policy authorities​

Policies are separated by what they are allowed to do.

Permission​

A permission can open a door:

Finance members may update issues in the Finance project.

No matching permission means deny.

Constraint​

A constraint can close or narrow a door, but cannot grant access:

Confidential customer data may leave only through an approved connector.

An explicit constraint denial wins over every permission. The policy editor calls permissions grants and constraints ceilings. A shipped policy whose action is block is a constraint.

Requirement​

A requirement attaches a mandatory safeguard to an otherwise permitted operation:

  • redact selected fields;
  • obtain human approval;
  • require stronger authentication;
  • use an approved route;
  • reserve quota or budget;
  • create enhanced audit evidence.

If the enforcement point cannot perform a mandatory safeguard, it does not execute the operation. A shipped policy whose action is redact is a mandatory requirement; one whose action is warn or log attaches a notification or an audit record and changes nothing the caller receives.

Inspection​

Inspection selects content and risk controls such as PII detection, prompt-injection detection or risk scoring. Inspection may restrict an operation but cannot grant authorization by itself.

Known, absent, and unknown are different​

Authorization fails when missing information is treated as if a condition did not apply. AxonFlow distinguishes three states:

StateMeaning
KnownThe authoritative source established a value
AbsentThe authoritative source established that an optional value has no value
UnknownThe source could not establish the fact

For example, "Sarah is not a member of Finance" is different from "the directory could not answer whether Sarah is a member of Finance."

The second result cannot silently bypass a Finance-related constraint. If an unknown fact could change the authorization result or a mandatory requirement, the operation remains non-executable.

Mandatory safeguards compose predictably​

Different safeguards need different composition rules:

  • Field transforms move toward less disclosure. An unsupported or incomparable combination denies rather than choosing one arbitrarily.
  • Approval requirements remain a conjunction of threshold clauses.
  • Allowed routes are intersected.
  • Authentication requirements select the strongest assurance and compatible methods.
  • Every applicable budget and quota rule must be satisfied atomically.
  • Audit and notification requirements are combined and deduplicated.

There is no global ranking such as "block beats redact beats warn." Each safeguard family has one defined rule.

Approval example​

An operation might require:

2 of {Security, Platform}
AND
1 of {Data Owners}

These clauses are not merged into a single pool. AxonFlow also checks whether enough distinct, interactive approvers can satisfy every clause after excluding the requester and the actor chain.

A known impossible clause is denied immediately instead of waiting for an approval timeout. If directory reachability is temporarily unknown, the challenge remains non-executable and bounded by its expiry. Timeout never means approval.

Four operational results​

The engine produces one of four results:

ResultMeaning
ALLOWThe exact operation may execute with the listed safeguards
DENYPolicy or a mandatory safeguard prevents execution
CHALLENGEApproval or stronger authentication is required
ERRORA safe decision could not be produced

Only ALLOW permits execution. A directory outage, invalid policy bundle, unsupported obligation, expired approval, unavailable budget reservation or mismatched proof never becomes an implicit allow. Each plane renders these results in its own wire format: POST /api/v1/decide, for example, answers allow or deny, refuses a result that needs an approval because approval execution is not wired on that plane, and answers a failure to decide with a fail-closed refusal rather than a verdict.

Signed decision proofs​

The design binds an allowed operation that crosses a process boundary to a signed decision proof. The proof binds the authorization to the exact:

  • organization, principal, client, session and actor chain;
  • action, tool, resource and normalized argument digest;
  • policy, identity, registry, resource and schema versions;
  • obligations, approval evidence and budget reservations;
  • target enforcement point, audience, expiry and replay protection.

The connector or other enforcement point verifies the proof immediately before execution. Changing the actor, attachment, destination, arguments, policy version, approval or target invalidates the proof, which closes the time-of-check gap between "AxonFlow allowed this" and "the connector executed something." The proof primitives ship in the platform; which enforcement points verify a proof is documented with each enforcement point.

Worked example: a finance agent updates Jira​

The walkthrough below is illustrative: it shows how the pieces above compose, so that teams building enforcement points know the contract they are building against.

Sarah asks an AI agent:

Update Jira issue FIN-17 and attach this customer export.

The control plane processes the request as follows:

  1. Sarah is authenticated through Acme's Okta trust realm.
  2. AxonFlow establishes Sarah -> Finance Agent -> Jira Connector.
  3. The tool registry maps the operation to a canonical Jira update action and hashes the normalized arguments.
  4. Identity and resource data show that Sarah belongs to Finance, FIN-17 belongs to the Finance project, and the attachment contains confidential customer information.
  5. A permission allows Finance members to update Finance project issues.
  6. Constraints require an approved connector, an allowed delegation depth and an approved confidential-data route.
  7. Requirements demand SSN redaction, one Data Owner approval, one Security approval, budget admission and enhanced audit.
  8. The initial result is CHALLENGE. Jira is not called.
  9. After approval, AxonFlow rechecks eligibility, reserves budget, verifies redaction capability and issues a signed proof.
  10. The Jira enforcement point verifies the proof and executes the exact approved operation once.

If Sarah's group lookup is unknown, the result is not allow. If the connector cannot enforce redaction, the operation is denied. If the attachment changes after approval, proof verification fails.

Integration model​

AxonFlow separates central management from local decisions:

Policy decisions run locally in the enforcing service using signed, immutable bundles, so the hot path does not depend on a remote policy service. Central systems own authoring, testing, signing, activation, audit and rollback. An activation names a bundle by digest, and a rollback activates an earlier digest, so "which policy produced this decision" survives every later edit.

What this means for architecture teams​

For staff engineers, the integration contract is one canonical authorization request and one set of results, on the planes the engine governs.

For engineering managers, identity, policy, approval, inspection and audit have explicit owners and failure contracts instead of route-specific behaviour.

For directors and security leaders, the model provides:

  • one decision engine on the enforcement planes it governs, with no mode to leave on the wrong setting;
  • a shipped policy set that observes from the first boot, with every policy individually switchable per organization;
  • default-deny authorization, and explicit delegated-agent identity;
  • deterministic, replayable decisions, with the engine and the policy bundle recorded on each one;
  • mandatory safeguards that a connector cannot ignore.