> Call POST /v1/check before a tool that writes. DENY means do not invoke the tool. For clean Markdown of any page, append .md to the page URL. For the complete index, fetch https://docs.withwrit.com/llms.txt. # Policies > The three policy layers — tenant default, per-environment overrides, and per-principal overrides — how they resolve, and how to edit them. Every check evaluates the requested verb against your tenant's **policy**: a verb → mode map where each mode is `allow`, `deny`, `require_grant`, or `step_up`. The policy is layered. The most specific layer that names the verb decides: 1. **Per-principal override** — one [principal](/principals)'s sparse verb→mode map. Highest precedence. 2. **Per-environment override** — `dev`, `staging`, or `prod`. Applies when the check names that environment. 3. **Tenant default** — the complete map; every verb falls back here. Unnamed verbs inherit downward: a verb the principal's override doesn't set falls through to the environment override, then to the tenant default. An unknown environment name denies fail-closed without evaluating any policy. ## The tenant default `PUT /v1/policy` sets modes on the complete map; `GET /v1/policy` reads it. Unlisted verbs default to `require_grant` (fail closed). Every edit bumps the tenant default's own `version`. ```bash curl -X PUT https://api.withwrit.com/v1/policy \ -H "Authorization: Bearer writ_..." -H "Content-Type: application/json" \ -d '{"refund": "deny"}' ``` ## Environment overrides `PUT /v1/policies/environments/{dev|staging|prod}` sets a **sparse** override: only the verbs you send are stored; the rest keep inheriting the tenant default. Each environment has its own independent `version` starting at 1 on first write (`version: 0` means "no override yet"). ```bash curl -X PUT https://api.withwrit.com/v1/policies/environments/dev \ -H "Authorization: Bearer writ_..." -H "Content-Type: application/json" \ -d '{"refund": "allow"}' ``` `GET /v1/policies/environments/{env}` returns the sparse `policy` plus `effectivePolicy` (tenant default with the override applied) and `policyProvenance`, which names the winning layer per verb. ## Per-principal overrides `PUT /v1/policies/principals/{principalId}` sets the top layer: a sparse override for one principal. Only live principals can carry policy — setting an override on a tombstoned or disabled principal is `400` (`principal_inactive`), because an identity that can't authorize checks can't carry policy either. Each principal's override has its own independent `version`, untouched by environment or tenant edits. ```bash curl -X PUT https://api.withwrit.com/v1/policies/principals/prn_9d2f4a1b2c3d \ -H "Authorization: Bearer writ_..." -H "Content-Type: application/json" \ -d '{"refund": "step_up"}' ``` Send `{"verb": "inherit"}` to remove a verb from the override so it inherits downward again. `GET /v1/policies/principals/{principalId}` returns the sparse override, the fully-resolved `effectivePolicy`, and `policyProvenance` naming the winning layer per verb. Add `?environment=prod` to fold the `prod` override into the middle layer, exactly as a check naming `prod` would evaluate it. Tombstoned principals still return `200` — they stay resolvable forever — with `"inert": true`. `GET /v1/policies` lists every policy object: tenant default first, then configured environment overrides, then configured per-principal overrides. ## Inert overrides Disabling or deleting a principal makes its override **inert**: it never supplies a mode while the principal can't authorize checks — checks deny with `principal disabled` / `principal deleted` before policy is even evaluated. The override data is kept, not wiped: re-enabling the principal re-arms its override, and the audit record of what was configured survives. ## Receipts name the winner Every check receipt records `policyId` and `policyVersion` — the single policy object that supplied the verb's mode — alongside the principal snapshot (`principalId` / `principalName`). `policyId` is `null` only where no policy was evaluated (e.g. unknown-environment denials). > The three policy layers — tenant default, per-environment overrides, and per-principal overrides — how they resolve, and how to edit them.