Skip to main content

Managing Policies

In v11 an organization manages three things:

WhatWhereWhat you do with it
The shipped policiesThe platform's policy rootRead their actions; disable, re-enable or re-action each one for your organization
Your own policiesYour organization's typed policy documentWrite, validate, publish, activate and roll back
The policy rows you created in v10.xThe v10.x system-policy and tenant-policy tables, now read-onlyExport them, then re-author or import them

The v10.x system (static) and tenant (dynamic) policy families are closed to writes, and their rows no longer decide anything: the engines that read them author no verdict in v11. The field reference below remains so you can read what you exported.


Managing the shipped policies​

Every shipped policy, its category, its action on each plane and why is listed in Shipped Policy Posture.

For each shipped policy your organization can:

  • disable it, so it no longer decides for your organization;
  • re-enable it;
  • change its action to log, warn, redact or block, making it stricter or more lenient.

The change applies to your organization only. To change the platform's policies in a whole category at once, record a detection-posture override: pii reaches the 18 pii-* platform policies, sqli the 38 SQL-injection platform policies and dangerous_command the four indirect prompt-injection guards; dangerous_query changes no policy, and obligation_fallback sets what happens when a plane cannot carry out a redaction.

A category-wide override recorded for your organization, such as every platform PII policy to redact, reaches the engine on 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: there the platform's policies in that category decide with the recorded action for your organization. See Detection posture. It does not reach the 22 organization-editable policies, among them the dangerous-command, DROP TABLE, TRUNCATE and two SQL-injection blocks: your organization changes those in its own typed policy document.

Managing your organization's policies​

Policies your organization writes live in its typed policy document, authored through /api/v1/typed-policies on every edition, or the portal's Policy Authoring page on Enterprise:

MethodPathPurpose
GET/api/v1/typed-policies/editionThe vocabulary and your edition's limits
POST/api/v1/typed-policies/validateValidate a document
POST/api/v1/typed-policies/publishPublish a version with its test cases
POST/api/v1/typed-policies/activateActivate a published version by digest
GET/api/v1/typed-policies/activeThe document in force
GET/api/v1/typed-policies/systemThe platform's shipped policies, read-only: 116 compiled from the 85 shipped rows

Typed Policy Authoring walks through the lifecycle, and Policy Syntax documents the parts of a policy.

Managing policies in the portal​

On Enterprise the customer portal carries:

  • the Policy Authoring page, for your organization's typed policy document: edit, validate, compare with live, publish with test cases, activate, and roll back by digest;
  • the published-version history, with each version's signed source and every activation's actor and reason;
  • the Detection Posture settings, which re-action the platform's policies in a whole category for your organization.

The v10.x Policies page, which listed and edited system and tenant policy rows, is removed in v11.


The v10.x policy families, read-only​

v10.x had two families of policy, both of which you may still hold rows in after upgrading:

FamilyWhere it livedv10.x API pathTypical use
System policies (also called static policies)The Agent/api/v1/system-policiesPattern-based checks: PII detection, SQL-injection blocking, secret-leak detection
Tenant policies (also called dynamic policies)The Orchestrator/api/v1/tenant-policiesContext-aware rules built from conditions and actions: risk, cost, user, content, and media governance

/api/v1/static-policies and /api/v1/dynamic-policies are their deprecated aliases.

In v11:

  • Writes are refused. A create, update, delete, toggle or import on either family answers 409 LEGACY_POLICY_WRITE_FROZEN, and the error names /api/v1/typed-policies.
  • Reads remain, for export. The list, get, effective, versions and export routes still answer, so you can take what you had before you re-author it. Every response on these routes (reads, the 409 on writes, 401 and 503) carries Link: </api/v1/typed-policies>; rel="successor-version" and X-AxonFlow-Removed-In: v11.1, and from the v11.0.0 release a Deprecation header (RFC 9745) dated to the release; v11.1 removes the routes.
  • A row you created is not carried forward. Re-author it as a typed policy, or on Enterprise import it with the operator-run import command; the v10 → v11 Migration Guide covers both. The 85 system rows AxonFlow shipped, and the 22 it shipped at the tenant tier, are carried forward as the shipped set.

To export your tenant policies:

curl "http://localhost:8080/api/v1/tenant-policies/export" \
-H "Authorization: Basic $(echo -n 'CLIENT_ID:CLIENT_SECRET' | base64)"

Policy Field Reference​

The tables below describe the fields of a v10.x policy row, as the read routes and an export return them.

System (static) policy fields​

FieldTypeMeaningValues
namestringHuman-readable policy nameUp to 255 characters
descriptionstringPlain-English explanation of what the policy detects and why it existsFree text
categorystringClassification that groups the policy (see Policy Syntax → Categories)One of the thirteen system-policy categories, e.g. security-sqli, pii-global, pii-us, code-secrets, sensitive-data
patternstringRegular expression matched against request contentGo (RE2) regular expression
actionstringWhat the Agent did when the pattern matchedblock, redact, warn, log or require_approval
severitystringHow serious a match islow, medium, high, critical, or empty on a row created without one
priorityintegerEvaluation order - higher values were evaluated firstInteger; 50 when created without one
enabledbooleanWhether the policy was activetrue / false
tagsarray of stringsFree-form labels for grouping (for example compliance:hipaa)Optional
tierstringWhich tier the policy belonged tosystem, organization or tenant
risk_levelstringRisk classification used by the session-override contract, seeded from the categorylow, medium, high, critical
allow_overridebooleanWhether an administrator could relax this policy with a session override; false whenever risk_level is criticaltrue / false
idstring (UUID)Internal unique identifierAssigned by AxonFlow
policy_idstringStable string identifier (slug)custom_ followed by 12 hex characters for a policy you created
tenant_idstringTenant the policy belongs toFrom the credentials that created it
org_idstringOrganization the policy belongs toThe creating caller's organization
segment_idstringGovernance segment a policy is scoped toPresent only on effective reads of a segment-scoped policy
versionintegerIncrements on every changeAssigned by AxonFlow
created_at / updated_atstring (ISO 8601)Creation and last-modified timestampsAssigned by AxonFlow
created_by / updated_bystringWho created or last changed the policyFrom the X-User-ID header
deleted_atstring (ISO 8601)Set when a policy is soft-deletedAssigned by AxonFlow
metadataobjectStructured metadata attached by AxonFlowAssigned by AxonFlow

A read through /api/v1/system-policies/effective also carries the override information that applied in v10.x:

FieldTypeMeaning
has_overridebooleanWhether an override was in effect for this policy
override_actionstringThe action the override enforced in place of action
override_enabledbooleanThe enabled state the override enforced in place of enabled
override_expires_atstring (ISO 8601)When a temporary override reverts
override_reasonstringWhy the override was created

Tenant (dynamic) policy fields​

FieldTypeMeaningValues
namestringHuman-readable policy name3-100 characters
descriptionstringPlain-English explanation of the ruleUp to 500 characters
typestringThe kind of policyOne of content, user, risk, cost, context_aware, media, rate-limit, budget, time-access, role-access, mcp, connector
categorystringClassification for filtering and reportingStarts with dynamic- (for example dynamic-risk) or media- (for example media-pii)
conditionsarrayThe rules that decided whether the policy matched (see Conditions)At least one condition
actionsarrayWhat happened when all conditions matched (see Actions)At least one action
priorityintegerEvaluation order - higher values were evaluated first0-1000
enabledbooleanWhether the policy was activetrue / false
tagsarray of stringsFree-form labels for groupingOptional
tierstringWhich tier the policy belonged toorganization or tenant
idstring (UUID)Internal unique identifierAssigned by AxonFlow
tenant_idstringTenant the policy belongs toFrom the credentials that created it
organization_idstringOrganization scope for organization-tier policiesAssigned by AxonFlow
versionintegerIncrements on every changeAssigned by AxonFlow
created_at / updated_atstring (ISO 8601)Creation and last-modified timestampsAssigned by AxonFlow
created_by / updated_bystringWho created or last changed the policyFrom the X-User-ID header
deleted_atstring (ISO 8601)Set when a policy is soft-deletedAssigned by AxonFlow

Conditions​

A condition is an object with three keys. All conditions in a policy had to match for the policy to trigger.

{ "field": "risk_score", "operator": "greater_than", "value": 0.8 }
KeyMeaning
fieldThe request attribute to inspect
operatorHow to compare the field to value
valueThe value (or list of values) to compare against

field values: query, response, user.email, user.role, user.department, user.tenant_id, risk_score, request_type, connector, cost_estimate, the media-governance fields (media.has_faces, media.face_count, media.has_biometric_data, media.nsfw_score, media.violence_score, media.content_safe, media.document_type, media.is_sensitive_document, media.has_pii, media.pii_types, media.has_extracted_text, media.extracted_text_length), and the retry-aware workflow fields (step.gate_count, step.completion_count, step.prior_completion_status, step.prior_output_available, step.last_decision, step.first_attempt_age_seconds, step.idempotency_key).

operator values: equals, not_equals, contains, not_contains, contains_any, regex, greater_than, less_than, in, not_in.

When you re-author a tenant policy as a typed policy, its conditions become the policy's where clause over the deployment's vocabulary; see Policy Parameters Explained → Conditions.

Operator semantics​

How the v10.x tenant-policy engine compared each operator, from platform v9.19.0 on, when every engine that evaluated a tenant policy ran the same matcher:

OperatorBehavior
contains, not_containsCase-insensitive everywhere.
contains_anyEvery item in the value list is compared as text, whatever its JSON type.
greater_than, less_thanA numeric string parses and compares. An operand that is neither a number nor a parseable numeric string is not comparable, and the condition is false.
regexThe value must be a string. A non-string value is rejected at write time and does not match at evaluation time.
All ten operatorsImplemented at every call site.

These rules are what an exported row meant when it was enforced, which is what to preserve when you re-author it.

A policy with no conditions​

Two different "no conditions" shapes exist in stored v10.x rows and they do not mean the same thing:

Stored shapeWhat it meant in v10.x
conditions is JSON null, or the key is absentApplied to everything, the way an empty WHERE clause matches every row. This was the platform's own shape for a condition-less system policy.
conditions is an explicitly empty array []Excluded from evaluation entirely from platform v9.19.0, and counted on axonflow_policy_condition_unevaluable_total{reason="empty_conditions",plane}. A released gap in the update API let a PUT clear a row's conditions to []; such rows are residue, not policy.

An exported row with [] conditions enforced nothing in v10.x from v9.19.0 on, and has nothing to re-author.

Actions​

An action is an object with a type and an optional config:

{ "type": "redact", "config": { "fields": ["ssn", "salary"] } }
typeWhat it didTypical config
blockRejected the request{ "reason": "…" }
redactMasked the listed fields in the response{ "fields": ["field1", "field2"] }
require_approvalPaused for human approval (HITL)-
warnAllowed the request and recorded a warning-
logAllowed the request and recorded an audit entry-
alertSent an alert to your monitoring systemVaries by alerting integration
routeApplied an LLM routing ruleVaries by routing rule
modify_riskAdjusted the computed risk score{ "modifier": 1.5 }

In v11 a shipped policy's action is one of block, redact, warn or log, and a policy you write expresses its action as its authority and obligations; see Policy Syntax → How a shipped action maps to a policy.

How risk is expressed​

v10.x modeled risk in three distinct ways, none of them a free-form numeric field set on a policy:

  • risk_score was a request attribute computed at evaluation time (a value from 0.0 to 1.0), referenced in a condition.
  • modify_risk was an action that nudged that computed score for downstream policies.
  • risk_level was a system-assigned classification on system policies that drove the session-override contract.

In v11 a policy you write reads the computed risk score in its condition, on Evaluation and Enterprise (a policy your organization writes cannot read signal.* facts on Community; the organization-editable policies AxonFlow ships read them on every edition) , as the shipped anomalous-access policy does; see Policy Parameters Explained → Risk thresholds.


Editions and limits​

  • The shipped policies are enabled on every edition, and every organization controls each one for itself.
  • Your own typed policies are available on every edition, within the limit GET /api/v1/typed-policies/edition reports (20 policies on Community, 50 on Evaluation, unlimited on Enterprise): through the API on Community and Evaluation, and on Enterprise through the portal editor, where a publication names its approvers.
  • Group scope and human approval requirements are Enterprise constructs, and conditions on signal.* facts in policies your organization writes need Evaluation or Enterprise.
  • Separation of duties on activation applies on Enterprise: a version's author cannot activate it, unless the organization has enabled self-approval.

Compare what each edition unlocks in Community vs Evaluation vs Enterprise.