Appearance
Policy File
policy.yaml holds every policy, budget and routing rule in one human-edited file. It is validated strictly: a typo in a field name is an error that names the exact path, never a silently ignored setting. The file is re-read when it changes.
Sections
| Section | Purpose |
|---|---|
default | Policy applied to every request. |
domains | {name: policy + budget}. A team belongs to a domain. |
teams | {team alias: policy + budget + user_budget}. |
keys | {key alias: policy + budget}. |
policies | Named, reusable policies (optionally with guardrails). |
policy_attachments | Where each named policy applies: scope, teams, keys or models, with * wildcards. |
routing | Rules that decide what model: "auto" resolves to. |
templates | Ready-made guardrail templates to switch on. |
Policy fields
| Field | Type | Meaning |
|---|---|---|
allowed_models | list | Only these model aliases may be used. |
allowed_providers | list | Only these providers (for example azure, openai, bedrock). |
allowed_regions | list | Only deployments whose region label is listed. |
max_tokens | int | Upper limit for max_tokens on a request. |
allow_external | bool | false allows only models marked model_info: {internal: true}. |
cache_ttl | int (seconds) | Response-cache ceiling. 0 turns caching off. |
Budget fields
| Field | Type | Default | Meaning |
|---|---|---|---|
limit_usd | float | required | Spend limit for the period. |
period | daily or monthly | monthly | Reset period. |
action | block or downgrade | block | What happens at 100%. |
downgrade_to | {alias: alias} | {} | Cheaper replacement for each model when action: downgrade. |
alert_at | list of percentages | [50, 80, 100] | Thresholds that raise an alert. |
Example
yaml
default:
max_tokens: 4096 # nobody can ask for more than this per answer
domains:
claims-phi:
allow_external: false # only models marked internal may be used
marketing:
allowed_providers: [azure, openai]
teams:
claims-team:
allowed_models: [azure-openai, bedrock]
budget: {limit_usd: 200, period: monthly, action: block}
research-team:
allowed_models: [azure-openai]
user_budget: {limit_usd: 5, period: daily} # default per-user budget for this team
keys:
alice:
max_tokens: 1000
policies:
phi-strict:
max_tokens: 2000
guardrails: {add: [pii-strict, claims-phi]}
cost-capped:
max_tokens: 1000
policy_attachments:
- {policy: phi-strict, teams: ["claims-*"]}
- {policy: cost-capped, keys: ["trial-*"]}
routing:
rules:
- {name: images, priority: 10, has_images: true, target: azure-openai}
- {name: simple, priority: 20, complexity: [SIMPLE], target: azure-openai}
- {name: demanding, priority: 30, min_complexity: MEDIUM, target: bedrock}
- {name: otherwise, priority: 1000, target: azure-openai}
templates:
- {use: pii-baseline, scope: all}
- {use: prompt-injection, scope: all}
- {use: secrets-block, scope: all}How scopes combine
Policies from default, domain, organisation, team and key are merged, and the most restrictive result applies:
- allow-lists (
allowed_models,allowed_providers,allowed_regions) intersect, - limits (
max_tokens,cache_ttl) take the minimum, - external providers are allowed only if every scope allows them.