Skip to main content

Tenant Policy API

The legacy condition-based tenant-policy API on the Orchestrator, at /api/v1/tenant-policies, as it answers in v11.0.0.

Legacy and read-only in v11

In v11 the tenant policies this API manages (historically "dynamic policies") are read-only, and they decide nothing: one policy decision engine decides every request, from the shipped policy set and your organization's own typed policy documents. Every write on this API answers 409 LEGACY_POLICY_WRITE_FROZEN and names the route to use instead. The reads stay, so you can export what you had before you re-author it, and are removed in a later release. If you are upgrading, read the v10 → v11 Migration Guide.

/api/v1/dynamic-policies is the deprecated spelling of the same routes, served by the same handlers; both spellings carry the headers described under Reading for export. The related cross-tier /api/v1/policies family on the Orchestrator is legacy and read-only in the same way.

Generated reference

Request and response schemas live in the Policy API reference, starting at listTenantPolicies. The /api/v1/policies family is in the Orchestrator API reference.

What replaces it​

A condition-based rule of your own (on user attributes, risk, cost, workflow context) is authored in v11 as a typed policy document: through /api/v1/typed-policies or the portal's Policy Authoring page, validated against your deployment's vocabulary, published, and activated by digest. See Typed Policy Authoring. The condition-based policies AxonFlow ships are part of the shipped policy set; Shipped Policy Posture lists them with their actions.

Base URL and authentication​

The Agent proxies this family to the Orchestrator:

http://localhost:8080
  • Via the Agent (port 8080): Authorization: Basic base64(clientId:clientSecret). The Agent injects the derived X-Tenant-ID / X-Org-ID / X-Client-ID headers before proxying, overwriting any client-supplied values.
  • Direct Orchestrator access (port 8081): the handler reads tenant scope from X-Tenant-ID, falling back to X-Org-ID. Requests with neither return 401 with code UNAUTHORIZED.

Errors use the shape {"error": {"code": "<STRING_CODE>", "message": "..."}}.

Routes​

MethodPathIn v11
GET/api/v1/tenant-policiesRead: list, for export
GET/api/v1/tenant-policies/{id}Read: one policy
GET/api/v1/tenant-policies/exportRead: export the tenant's policies
GET/api/v1/tenant-policies/effectiveRead: the enabled rows as v10.x ordered them
GET/api/v1/tenant-policies/{id}/versionsRead: version history
POST/api/v1/tenant-policies/{id}/testRemoved in v11; see Testing a stored row
POST/api/v1/tenant-policiesWrite: 409
PUT/api/v1/tenant-policies/{id}Write: 409
DELETE/api/v1/tenant-policies/{id}Write: 409
POST/api/v1/tenant-policies/importWrite: 409

Writes answer 409​

Create, update, delete and import write the legacy policy table, which v11 makes read-only to the application database role. Each answers 409 Conflict:

{
"error": {
"code": "LEGACY_POLICY_WRITE_FROZEN",
"message": "The legacy policy tables are read-only in v11: migrations/core/172 revoked write access from the application role, and this endpoint writes them. Author policies through the typed authoring route at /api/v1/typed-policies instead. Reads on this endpoint are unaffected."
}
}

No licence, edition or upgrade changes this answer. Branch on error.code; the message names the replacement route. A deployment that connects to its database as the owner (AXONFLOW_DB_USE_APP_ROLE=false) is not bound by the revoke, but nothing the v11 engine decides reads the row a write there creates.

Reading for export​

These read routes are a deprecated export surface in v11. 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 path or method these routes do not serve (404, 405) carries none of them.

The read routes answer as they did in v10.x, so an integration can export the rows it had before re-authoring them.

Export​

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

200 with {"policies": [...], "exported_at": "...", "tenant_id": "..."}, filtered to dynamic-* and media-* policies. Keep this file: it is the record of what your tenant enforced in v10.x.

List and filter​

Query paramNotes
typeFree-form type filter
categoryMust start with dynamic- or media-; any other prefix is 400 (VALIDATION_ERROR)
searchSearch term
sort_by, sort_dirSort field and direction
pagePage number, default 1
limitPage size, max 100 (page_size is the deprecated alias)
enabledtrue or false

List responses return a policies array plus pagination. Each policy resource carries:

FieldNotes
idPolicy ID
name, descriptionDisplay name and optional description
typecontent, user, risk, cost, context_aware, media, rate-limit, budget, time-access, role-access, mcp or connector
categoryA dynamic-* or media-* category
tiersystem, organization, or tenant. tenant and organization are the rows your organization authored
conditionsCondition list: each a field, an operator and a value
actionsAction list: each a type (alert, block, log, modify_risk, redact, require_approval, route, warn) and an optional config
priorityEvaluation priority in v10.x
enabledWhether the row was active in v10.x
versionCurrent version
tenant_id, organization_idScope
tagsOptional tags
created_at, updated_at, created_by, updated_by, deleted_atTimestamps and attribution

A stored JSON null conditions value, used by platform-seeded rows, means the row applied to everything in v10.x; an explicitly empty list means v10.x excluded the row from evaluation.

Version history​

GET /api/v1/tenant-policies/{id}/versions returns versions, each with the complete policy resource at that version in snapshot, plus change_type (create, update, enable, disable, delete), change_summary, changed_by and changed_at.

Testing a stored row​

POST /api/v1/tenant-policies/{id}/test is removed in v11: it evaluated a legacy row through the legacy engine, and v11 has no legacy engine to answer for. To check what a policy decides, use policy simulation and policy testing, which answer with the engine that enforces.