Governance Rules
Budgets, rate ceilings, and model and provider access -- the half of a guardrail DevZero enforces on every request.
Governance Rules
The governance half of a guardrail is DevZero's end to end, and it binds every request, whoever's credential pays.
The control plane decides; the gateway does the arithmetic. The gate runs on the decided model, before any cache is consulted.
Governance ships in shadow mode. The enforcement mode is set per gateway
deployment (off, shadow or enforce) -- not per guardrail and not per
team -- and a hosted gateway defaults to shadow: every rule on this page
is evaluated and recorded, and nothing is denied. A self-hosted gateway
defaults to off, where the gate does not run at all. Confirm which mode
your gateway is in before relying on a rule to refuse traffic.
Budgets
| Setting | Meaning |
|---|---|
| Limit | A hard ceiling in USD. Unset or zero means no budget, not "no spending allowed". |
| Reset | daily, weekly, monthly, or unset for a lifetime budget anchored at the guardrail's creation. Windows are calendar UTC. |
| Counter scope | principal (the default) or team. |
A budget's ceiling is per cadence. A daily ceiling read against a month of spend looks like a team wildly over budget when it is not, which is why every surface that shows a budget also shows its reset cadence. Only a monthly ceiling is directly comparable to a month of spend.
A pooled budget -- counter scope team -- is counted against every principal
bound to the guardrail together, so one bucket exhausts for everyone it governs.
The guardrail's rate ceilings pool into the same bucket.
Money is carried as integer micro-USD everywhere -- on the wire and in every counter -- so there is no floating-point drift.
Validation on the amount: USD only, no finer than 100,000,000.
Soft-warn thresholds
Fractions of the budget at which a crossing is announced rather than refused. Each is crossed once per window.
Crossing a threshold changes no verdict. Enforcement never reads them -- they exist to tell you something before the ceiling does.
Each threshold is a fraction greater than zero and at most one. They are stored as a whole set, so if you drive the API yourself you must round-trip them or they are erased.
Rate ceilings
| Setting | Meaning |
|---|---|
| Requests per minute | 0 means unlimited. |
| Tokens per minute | 0 means unlimited. |
The control plane owns what these mean; the gateway owns the counting. Both
pool into the same bucket as the budget when the counter scope is team.
Avoid calling an upstream provider's own throttling a "rate limit" in the same breath as these. A provider throttle is the upstream refusing you; these are your own ceilings, and they are reported differently in the failure taxonomy.
Model and provider access
Four lists, and all of them take wildcard patterns: * matches any run of
characters, and everything without a * is byte-exact.
| List | Effect |
|---|---|
| Allowed models | Only these may be served. Empty means unrestricted. |
| Ignored models | A match denies, even when the allow list would permit it. |
| Allowed providers | Only these may serve. Empty means unrestricted. |
| Ignored providers | A match denies. |
Two rules govern how they combine:
- An exclusion beats a permission.
- An empty permit list means unrestricted, not "permit nothing".
A non-empty provider allow list fails closed on a provider the gate cannot recognise. That is deliberate: a request whose provider is unknown cannot be proved to satisfy a restriction, so it is refused rather than admitted.
A byte-exact entry must match what the gateway actually sends. One mismatch is a silent false deny, cached for a short window. Introduce access rules in shadow mode and read the would-deny decisions before enforcing.
On the keyed connector route
On that route the gate is handed a connector id rather than a catalog provider slug, because the serving endpoint is chosen upstream afterwards. So the decision defers: the control plane expands your wildcard patterns into literal provider slugs and hands the rules back, and the gateway enforces them.
If the catalog is unreadable while your rules contain a wildcard, the control plane refuses the decision rather than shipping a pattern that would never match anything. A wildcard that expands to no known provider is not a refusal: an allow list that matches nothing still denies everything, and a deny list that matches nothing denies nothing. That makes the model catalog a hard dependency of the governance decision on this route.
Auto mode
Auto splits the guarantee, because a delegated request has no decided model for an allowlist to bind. See Auto mode.
Deny reasons
A denial names one of a fixed set of sixteen:
| Reason | Meaning |
|---|---|
model_not_allowed | The decided model failed the model rules. |
provider_not_allowed | The provider failed the provider rules. |
policy_disabled | The guardrail is switched off. |
policy_expired | The guardrail's expiry has passed. |
unattributed_denied | Traffic with no resolvable identity, under a guardrail that denies it. |
budget_exhausted | Accrued spend reached the budget ceiling for the window. |
rate_limited | The requests-per-minute ceiling was exceeded. |
tpm_exceeded | The tokens-per-minute ceiling was exceeded. |
budget_unavailable | The spend counter could not be read and the fail mode is closed. |
policy_unavailable | The control plane could not be reached and the fail mode is closed. |
credential_unavailable | No forwardable credential resolved for a team-funded request. |
custody_unsupported_upstream | The requested custody arm does not exist on the decided upstream. |
key_invalid | The key is unknown, revoked, expired or disabled. |
key_policy_not_metered | A key's guardrail is seat-sourced or absent, so it has no team-funded credential. |
user_policy_not_metered | The same, for a signed-in DevZero account. |
token_invalid | The DevZero access token did not verify. |
Deny reasons have two authors that do not overlap: the control plane's verdict about the principal and the guardrail, and the gateway's own outcomes at forward time. Do not read the set as one enumeration owned by one side.
A refusal is collapsed into one shape where distinguishing it would tell a probing caller something they should not learn, and distinguished where the two cases name different remedies.
Unattributed traffic
Traffic with no resolvable identity is a real category, and a team-default guardrail decides what happens to it: govern it as the default does, drop the access rules for it, or deny it.
That setting is read only when the guardrail is resolved as the team default. And dropping the access rules is not a bare allow -- the guardrail still has to be active and unexpired, and the rate ceilings and budget still apply.
Reading spend against a guardrail
Two reads exist and they are not interchangeable:
| Read | Question it answers |
|---|---|
| Principal usage | What enforcement sees: spend inside the guardrail's own window, filtered the way enforcement filters. |
| Key spend | What has this key cost over the last N days, with no policy filter at all. |
Never sum key spend against a budget limit -- it would overstate consumption, because it counts traffic the budget does not. It also counts traffic on your own credentials, so it answers "what did this key's traffic cost", not "what does the team owe DevZero".
Two more honesty rules on the enforcement read:
- For a seat credential class, all the monetary and window fields are absent. Seat telemetry cost is an API-equivalent estimate, not money spent, and must never be presented as spend.
- A partial sum is disclosed rather than presented as complete. Historical rows can predate a column the figure depends on.
What "true allow" means for your credential
No request is ever forwarded on a DevZero-funded credential without a governance verdict that actually allowed it, produced fresh -- because a verdict replayed during an outage cannot see a key revoked since.
Failing that check strips the credential and forwards the request anyway, where the upstream rejects it. That is deliberate: it is not a DevZero denial, and it costs $0 rather than billing an account nobody authorised.
Guardrails Overview
A guardrail is one named bundle of rules -- budget, rate ceilings, model and provider access, content filters -- bound to a principal. They never stack.
Content Rules
Builtin detectors, custom patterns, the three actions, where each rule is actually enforced, and the coverage gaps stated plainly.