Org provider policy
An organization owner can decide which providers and models the organization's product may call. Every ModelRig SDK in the organization reads that policy and refuses to dispatch a call that breaks it, in your process, before the request leaves for the provider.
Needsmodelrig0.15.0 or newer. Older SDKs ignore the policy. Setting it over MCP needsmodelrig-oracle0.7.0 or newer (the MCP oracle).
The policy
// GET /v1/orgs/:org/settings → provider_policy (null = no policy)
{
"version": 1,
"deny_providers": ["deepseek"], // registry provider ids the org refuses
"allow_providers": null, // null = any provider not denied; a list = ONLY these
"deny_models": ["grok-4"], // bare model ids, exact match (see below)
"require_zero_retention": false, // only endpoints the registry designates zero-retention
"note": "Vendor review 2026-10: no PRC-hosted providers" // ≤ 280 chars, quoted in the fix hint
}
| Rule | What it refuses |
|---|---|
deny_providers | Any call to a listed provider. |
allow_providers | Any call to a provider that is not listed. null means no allow-list; a list must not be empty. |
deny_models | Any call to a listed model id, on any provider. |
require_zero_retention | Any call to an endpoint the registry does not designate zero-retention (the same flag as a route's require: zero_retention). |
The rules are checked in that order, and the first rule that refuses a call is the one reported.
deny_models is an exact match on the bare model id
The SDK compares the model id exactly as it is recorded on the call (the bare id, for example grok-4, not grok/grok-4). There is no prefix or family matching: grok-4 does not refuse grok-4-0709. List every id you want refused.
When you save the policy, model ids are checked against the registry. An id the registry does not know is accepted with a warning (you may be refusing a model ahead of time). A full provider/model key is accepted too, with a warning to use the bare id.
Who can set it
- An org owner, on the console Security page, or
- a key with the
org-settingsscope, throughPATCH /v1/orgs/:org/settingswith aprovider_policybody, or - a coding agent over MCP:
set_org_settings({ provider_policy: { … } }).
Admins and members see the policy read-only. Every save goes through the same server validation: an unknown provider id is refused with 422 and the list of known ids. Every change is recorded in the audit log with who made it and the policy before and after.
What the SDK does
- Narrows, never widens. The policy intersects with a route's
require, a per-callproviders: { only, ignore }filter and any step pin. A call cannot override it. - Routed calls (
rig.run,rig.runBundle,rig.runStream): candidates the policy refuses are dropped before the ladder runs. If no candidate survives, the call fails without dispatching anything. - Raw calls (
rig.runRaw, buffered and streaming): checked after a step pin resolves (a pin can change the provider) and before the adapter is built. - The failure. A refused call fails with the existing class
invariant_violation,reason: "org_provider_policy", and a fix hint that names the rule, quotes the policynote, and says who can change the policy and where. There is no new failure class to handle. - Refusals are recorded. Each refused attempt is written as an inference with outcome
invariant_violationandmeta.policy_blocked = { rule, provider, model }, so it shows in the AI inventory as Blocked.
Your org's provider policy refuses this call: provider "deepseek" is on the deny
list (deny_providers). Policy note: "Vendor review 2026-10: no PRC-hosted
providers". Choose a provider/model the policy allows, or ask an org owner to
change the policy (console Security page, or set_org_settings over MCP).
Freshness: fail open to the last-known policy
The policy travels on the org settings read the SDK already makes (refreshed about every 10 seconds). On its first dispatch the SDK waits up to 2 seconds for the first read when an API key is configured; after that it uses the last policy it fetched. If ModelRig is unreachable, the SDK keeps using that last-known policy. If no read has ever succeeded, the call dispatches.
This is deliberate: a monitoring vendor must not take your product down. To keep it visible, every inference is stamped meta.policy_state:
policy_state | Meaning |
|---|---|
enforced | A policy was read and applied to this call. |
none | The org has no policy. |
unknown | No settings read had succeeded yet, or the stored policy has a version this SDK does not understand (it is ignored, never half-applied). |
The inventory counts unknown calls per model as Policy unknown.
The boundary
Stated plainly, so nobody over-reads it:
- The SDK enforces the policy in your process. It applies to calls made through the ModelRig SDK (0.15.0 or newer) on
destination: direct. - Managed serving (
destination: modelrig-served, managed serving) is refused if the route lists any model the policy denies. - The hosted gateway endpoints do not apply the org provider policy yet. Calls sent to
/v1/chat/completionsor the hosted route-bundle mirror are not checked against it. - Recorded calls are flagged, not refused. A call your code makes directly and reports with
rig.recordCall()has already happened when ModelRig hears about it. The inventory marks it Outside policy; nothing can refuse it. - Older SDKs ignore the policy. A process running
modelrigolder than 0.15.0 dispatches as before.
The AI inventory
The console Security page lists every provider and model the organization used over the last 7, 30 or 90 days, read from your own telemetry (GET /v1/console/inventory?days=30, member session). Each row shows calls, cost, first and last seen in the window, up to ten routes and steps, which lanes made the calls (route, raw, recorded), and badges:
| Badge | Meaning |
|---|---|
| New | First seen in the last 7 days, with no call before the window. |
| Outside policy | The current policy would refuse this provider/model, but calls ran (for example, recorded calls or an older SDK). |
| Blocked | The SDK refused calls to it (policy_blocked attempts). |
| Policy unknown | Calls ran while the SDK's policy_state was unknown. |
The inventory is evaluated against the current policy when you open the page. Nothing is pushed to you: you see a new or outside-policy model the next time you look, for example the next morning.