Skip to main content

Tenant Policy API

Use the tenant policy API to create per-tenant governance rules on /api/v1/dynamic-policies. These policies live on the Orchestrator and evaluate request-time context such as user attributes, estimated risk, cost, business rules, and media-governance conditions.

Overview

This is the public API path for what the platform historically called "dynamic policies." In public docs, the preferred term is tenant policies. The legacy endpoint name remains /api/v1/dynamic-policies.

Tenant policies differ from system policies in a few important ways:

FeatureSystem PoliciesTenant Policies
API Endpoint/api/v1/static-policies/api/v1/dynamic-policies
StructurePattern-based rulesConditions and actions
LocationAgentOrchestrator
Use CasePII, SQLi, redaction, fixed governance checksBusiness logic, risk, cost, user and workflow controls
ScopeRequest contentUser, context, cost, risk

Base URL:

http://localhost:8080

The Agent commonly proxies this to the Orchestrator. Direct Orchestrator access also works on 8081 if you expose it intentionally.

Authentication and tenant scope:

  • Authorization: Basic ...
  • Tenant context (derived from Basic auth credentials) preferred
  • X-Org-ID still accepted for backward compatibility on this handler
  • X-User-ID recommended on mutating requests for audit attribution

Verified Routes

MethodPathPurpose
GET/api/v1/dynamic-policiesList tenant policies
POST/api/v1/dynamic-policiesCreate a tenant policy
POST/api/v1/dynamic-policies/importImport policies
GET/api/v1/dynamic-policies/exportExport policies
GET/api/v1/dynamic-policies/effectiveGet effective policies for a tenant
GET/api/v1/dynamic-policies/{id}Get a single policy
PUT/api/v1/dynamic-policies/{id}Update a policy
DELETE/api/v1/dynamic-policies/{id}Delete a policy
POST/api/v1/dynamic-policies/{id}/testTest a policy
GET/api/v1/dynamic-policies/{id}/versionsList policy versions

Listing and Filtering

Verified query parameters handled by the list endpoint:

Query paramNotes
typeFree-form type filter used by the service
categoryMust start with dynamic- or media-
searchSearch term
sort_bySort field
sort_dirSort direction
pagePage number, default 1
limitPreferred page size, max 100
page_sizeDeprecated alias for backward compatibility
enabledtrue or false

The category behavior matters for real deployments:

  • use dynamic-* for general tenant governance
  • use media-* for media governance and analyzer-driven rules

Example:

curl "http://localhost:8080/api/v1/dynamic-policies?category=dynamic-risk&enabled=true&limit=20" \
-H "Authorization: Basic $(echo -n 'client-id:client-secret' | base64)" \

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

FieldNotes
idPolicy ID
nameDisplay name
descriptionOptional description
typecontent, user, risk, cost, or other supported policy types
categoryMust use a valid dynamic-* or media-* prefix
tiersystem, organization, or tenant
conditionsCondition list
actionsAction list
priorityEvaluation priority
enabledWhether the policy is active
versionCurrent version
tenant_idTenant scope
organization_idPresent for organization-tier policies
tagsOptional tags
created_at, updated_atTimestamps
created_by, updated_byAudit attribution
deleted_atPresent on soft-deleted records when included

Creating a Tenant Policy

The create handler requires a category and validates that it begins with dynamic- or media-.

Minimal example:

curl -X POST http://localhost:8080/api/v1/dynamic-policies \
-H "Content-Type: application/json" \
-H "Authorization: Basic $(echo -n 'client-id:client-secret' | base64)" \
-H "X-User-ID: [email protected]" \
-d '{
"name": "High-cost research requests",
"type": "cost",
"category": "dynamic-cost",
"conditions": [
{
"field": "cost_estimate",
"operator": "greater_than",
"value": 5
}
],
"actions": [
{
"type": "block",
"config": {
"message": "Request exceeds the tenant budget threshold"
}
}
]
}'

Successful creates return 201 Created with a policy object. Validation failures return a structured error with code VALIDATION_ERROR.

Example response:

{
"policy": {
"id": "550e8400-e29b-41d4-a716-446655440002",
"name": "High-cost research requests",
"type": "cost",
"category": "dynamic-cost",
"tier": "tenant",
"conditions": [
{
"field": "cost_estimate",
"operator": "greater_than",
"value": 5
}
],
"actions": [
{
"type": "block",
"config": {
"message": "Request exceeds the tenant budget threshold"
}
}
],
"priority": 0,
"enabled": true,
"version": 1,
"tenant_id": "tenant-123",
"created_by": "[email protected]",
"created_at": "2026-03-29T12:00:00Z",
"updated_at": "2026-03-29T12:00:00Z"
}
}

Test, Export, Import, and Version History

These are the routes teams use once tenant policy programs become operational rather than experimental:

MethodPathWhy it matters
POST/api/v1/dynamic-policies/{id}/testValidate a rule before enabling it
GET/api/v1/dynamic-policies/exportExport tenant policies for review or migration
POST/api/v1/dynamic-policies/importImport policy sets with overwrite control
GET/api/v1/dynamic-policies/{id}/versionsInspect policy history
GET/api/v1/dynamic-policies/effectiveSee the effective tenant policy set

Verified helper payload shapes:

{
"matched": true,
"blocked": true,
"actions": [
{
"type": "block",
"config": {
"message": "Request exceeds the tenant budget threshold"
}
}
],
"explanation": "The policy matched cost_estimate > 5",
"eval_time_ms": 0.42
}
{
"versions": [
{
"version": 1,
"snapshot": {
"name": "High-cost research requests"
},
"changed_by": "[email protected]",
"changed_at": "2026-03-29T12:00:00Z",
"change_type": "created",
"change_summary": "Initial policy creation"
}
]
}

What To Watch For

  • The public docs use tenant policy terminology, but the path remains /api/v1/dynamic-policies.
  • Category validation is strict. If you use an unsupported category prefix, the handler rejects the request.
  • For production governance programs, tenant policies are where you usually encode business-specific risk rules, escalation rules, cost thresholds, and media-governance conditions that go beyond built-in system policy coverage.