Skip to main content

The v11 policy and identity model

AxonFlow decides a governed request with one policy engine, under a signed set of policies your organization controls, for a caller the platform has identified. This page explains that model and the reasons behind it, for someone evaluating AxonFlow and for someone about to run it. Each section links the reference page that holds the detail.

New in v11.0.0

This model is new in v11.0.0. If you are upgrading from v10.x, read What changed from v10 below and the v10 → v11 Migration Guide.

What it is, in one screen

One engine decides. An enforcement plane is a point where a request enters AxonFlow and is checked before it goes further. Each plane the engine governs asks it one question, whether this caller may take this action given these facts, and gets back one kind of answer. In v11.0.0 those planes are:

  • the Decision API, POST /api/v1/decide, which your gateway calls in Decision Mode;
  • Gateway Mode's pre-check;
  • Proxy Mode's POST /api/request;
  • the OpenAI-compatible gateway;
  • MCP tool calls, on the request going in and on the result coming back;
  • the Orchestrator's response governance on POST /api/v1/process, which decides a model's response before it is released.
  • the Orchestrator's workflow step gate, which decides each step of a workflow before it runs;
  • the multi-agent plane's per-step check, which decides each step of a plan.

A shipped policy set, on from the first boot. AxonFlow ships its policies enabled, in two halves: the platform's own policies, which your organization can switch off or re-action but not edit, and an organization template of policies your organization edits directly, among them the blocks on destructive shell and SQL commands. Their actions observe rather than intervene: most warn or log, sensitive content is redacted, and a shorter list is blocked, among them destructive shell and SQL commands and prompt-injection attempts. Shipped Policy Posture lists each one with its action and where it runs.

Policy is a document your organization writes. Your organization writes its own policies as a typed policy document: a structured document in which every policy names registered actions and typed conditions, so it can be checked before it is used. A published document becomes a signed, immutable policy bundle, activated by its digest, a content hash that names that exact set of policies. On Enterprise, by default, the person who activates a version is not its author.

Each decision names who it was for and what decided it. The principal is who a decision is evaluated for: a user verified through an identity provider or, where no user is verified, the client credential, the application's own key, that made the call. The Decision API's answer carries the verdict, the engine that authored it (anchored, the v11 engine's name on the record), the bundle digest, the kind of principal and the policies that matched, and the decision's audit row records the same facts.

Why we built it this way

One engine, so a verdict does not depend on where you ask. Before v11 each plane had its own engine and its own copy of the rules, so the same request could be judged differently by a gateway pre-check and by the proxy, and nobody could say which answer was the policy. In v11 the planes above are decided by one engine from one signed bundle, each running the part of it that applies there, so a difference between two answers never comes from a second engine or a second copy of the rules.

A shipped set that observes, so evaluating AxonFlow holds no surprise. Comparable products (managed web-application firewall rulesets, container security baselines, code-scanning default rules, model safety filters) ship their defaults enabled in a non-blocking action, with blocking as a per-rule choice. We made the same call. A governance product whose first request is ungoverned proves nothing when you evaluate it, and a shipped rule that blocks your first day's traffic is a failure an evaluator should not have to diagnose. The answer to surprise is the action, not the absence of rules, and per-policy control is what makes observing or blocking yours to choose.

A document, so policy is reviewed and tested before it is in force. A document is validated, tested and signed before it can be activated, and on Enterprise, by default, a second person activates it. Publishing, activating and rolling back each land on an audit trail that names who did it.

One record, so a decision names exactly which policy made it, permanently. A bundle is signed and immutable, and each decision records its digest. "Which policy produced this decision" is answered from the record and survives every later edit, and a rollback is the activation of an earlier digest rather than an edit to live rules in a database.

Identity established, not trusted. Identity is an input the platform establishes, not a header it trusts. Who is asking is worked out from the credential that authenticated the call and, where a deployment verifies users, from a token issued by a trust realm: an identity provider the deployment has declared it trusts. A fact the platform could not establish is treated as unknown, and an unknown fact that could change the outcome does not produce an allow.

Nothing switches the engine off. No setting selects a different engine, and no organization can opt out of this one. A switch is a setting that can be left in the wrong place, and an opt-out would bring back a state in which your policy documents decide nothing.

How a decision is made

  1. A request reaches a plane. The plane authenticates the caller and establishes the principal.
  2. The plane asks the question. It names the action being attempted and presents the facts the policies read: the content, and what each detector that ran found in it. A detector is a scanner for one kind of risk, such as PII, SQL injection or a destructive command; the engine reads its findings, and a detector decides nothing by itself.
  3. The engine evaluates the active bundle. For an organization that has published nothing, that bundle is the shipped set together with the deployment's baseline permissions, the grants the deployment ships so that ordinary requests are allowed without a document of your own. It is composed and signed in memory by the running service; the bundle itself is never written to your database. Once your organization activates a document, the document takes the place of the organization template, by digest, and the platform's policies and the baseline permissions stay in force beside it.
  4. The verdict comes back with what decided it. A policy whose action is block refuses the request, and the Decision API's answer names that policy first. A redact policy allows it with an obligation, a step that must be carried out before anything proceeds: here, masking the matched content. An enforcement point that cannot carry the obligation out is refused instead, so the content is never released unmasked. A warn or log policy allows it and records the match. A policy that needs a person's approval is refused, with a reason beginning approval_required, on a plane that cannot hold the request for one, so a missing approval is distinguishable from a policy refusal. On a plane that can hold it — the workflow step gate and the multi-agent plane — the request is held for the approval instead of refused. An approval that has expired cannot be granted on either of those planes: the step is withheld and the expiry is named, because a timeout is always a refusal.
  5. The plane enforces the verdict, and the audit row records it.

Only an allow lets an operation proceed. A decision that could not be made is a fail-closed refusal, not a verdict; Known, absent, and unknown are different explains why an identity source that did not answer never becomes an allow.

Two decisions show the shape. On a Community deployment, a clean request to the Decision API with no user token is allowed: the answer says the engine was anchored, names the bundle digest, gives subject_type, the kind of principal, as Client because the client credential was the principal, and names the baseline permission that allowed it. On an Enterprise deployment, a request is allowed until the organization activates a document with a ceiling, a policy that denies, on that action; after that, the same request is refused, and the answer names the organization's own policy, with the version it was published at, as the one that decided. Decision Mode documents each field.

How policy is authored

A typed document is made of grants, which allow an action when they match, and ceilings, which deny or narrow what something else allowed; a ceiling overrides every grant. It can also attach requirements, such as a redaction, to an action it allows. Typed Policy Authoring explains each kind.

  • A draft starts from the organization template. In the portal, a new document begins as the organization template, so removing a shipped control is a visible edit, and publishing and activating each report which template policies your document leaves out.
  • The platform's policies are tuned in the same document. A per-policy section disables, re-enables or re-actions a platform policy for your organization, and it goes through the same publish, activate and rollback path as the rest. A condition-based platform policy can be disabled but not re-actioned.
  • Validation runs against your deployment's vocabulary. A policy can name only actions the deployment registers and groups from the trust realms it declares, and every finding comes back at once.
  • Publishing needs tests. It compiles the document, runs the tests you wrote for it against the compiled bundle, and signs it. Publishing puts nothing in force.
  • Activation is by digest, and it builds before it switches. The platform builds the engine that would enforce the version and refuses the activation if it cannot, so a document that cannot be enforced is never activated.
  • Roll back and withdraw, on Enterprise. A rollback activates a digest that was active before, with a reason. Withdrawing your document returns your organization to the shipped set without deleting its history.

Separation of duties applies on Enterprise. The person who activates a version is never its author, unless the organization has fewer than two eligible approvers and has enabled self-approval, which the audit row records with a reason. Enterprise publishes, compares and rolls back in the portal's Policy Authoring page. On Community and Evaluation the authoring API validates, publishes and activates, one administrator may do all three, and each activation is still attributed. Typed Policy Authoring walks the lifecycle, and Typed Policies on a New Installation walks it on a fresh deployment.

Identity

A decision is evaluated for a principal inside an organization, the hard isolation boundary: a policy and a bundle each belong to exactly one organization.

  • A verified user. Enterprise and Evaluation deployments verify users. A user token must come from a declared trust realm, and a token that fails verification is refused; it is never replaced by the client credential.
  • The client credential. Community deployments, Community SaaS included, verify no user: a presented user token is ignored and the client credential is the principal. On every edition, a request that carries no user token is decided for its credential.

subject_type on the answer and on the audit row records which kind of principal it was, so a decision made for a credential is never mistaken for one made for a person. Identifiers are realm-qualified, so two identity providers that both issue the name admin produce two different principals. An identity a caller writes into a request does not override the one it authenticated as: on Enterprise and Evaluation, the Decision API refuses a request body that names a different organization, and audits the attempt.

Who the decision is for gives the status codes and the admission rules, and the same page covers trust realms, canonical identities and actor chains. An existing deployment moving from the v10.x compatibility switches should read Identity Compatibility Mode, and Identity Plane APIs covers the per-organization identity settings.

What changed from v10, and why it is safe

The old engines no longer decide on these planes. On the planes this page lists, the v10.x system-policy, tier and tenant-policy engines no longer decide. The detectors they shared with the new engine stay, because the engine reads what they find.

The shipped policies are enabled when you upgrade. They decide with their shipped actions, and some act differently from v10.x; the migration guide lists where.

Your own v10.x policies do not carry over. Policies your organization wrote in the v10.x policy tables stop deciding at the upgrade until you bring them into the typed model, with the operator import on Enterprise or by re-authoring them on Community. Per-policy overrides you recorded are imported once, into an unpublished draft. Overrides recorded for a single tenant within your organization are not imported and stop applying at the upgrade; the upgrade preflight warns about them beforehand and counts them.

The legacy write routes are closed. A write to an existing v10.x policy answers 409 LEGACY_POLICY_WRITE_FROZEN and names /api/v1/typed-policies, the route to use instead; the migration guide covers the one exception, a deployment that connects to its database as the owner.

The legacy read routes are deprecated. They stay in v11.0.0 as a read-only export surface, so legacy rows can still be read and exported after the upgrade. Each response carries a Deprecation header and names its successor, and the routes are scheduled for removal in v11.1.

The retired switches refuse boot. A deployment that still sets a v10.x decision-mode or identity-compatibility variable, or a value that would narrow what the detectors scan, refuses to start and names the variable; see Variables and licences that refuse boot.

What protects you during the upgrade.

  • Your own v10.x policies are the one thing that does not carry over: import or re-author them before you rely on v11 to enforce them.
  • The shipped set mostly observes, so the first request after the upgrade is governed without being blocked by surprise, and every shipped action is published before you upgrade.
  • The detection settings that would narrow what the engine decides refuse boot rather than leaving policies unable to fire.
  • A document is built into an engine before it becomes active, and on Enterprise a rollback returns to a version that has already been through that pipeline and withdrawing returns to the shipped set.
  • On the Decision API, failures are refusals you can tell apart: an unverifiable caller, a missing approval and a policy denial each say which they are.

The v10 → v11 Migration Guide is the step-by-step, and the v11.0.0 release notes list what the release contains.

Where to go next