Reason codes
Every policy decision records exactly one reason code — the branch of the decision chain that produced it. The Policy page shows the label; hovering shows the raw code, which is what you'll see in exports, the API and alert rules. Each code always carries the same effect.
Codes marked Did not hold record a control that was reached and didn't hold — machinery failing open, timing out or being unreachable. The app highlights them, the Control Library counts them as Degraded, and the default alert rules fire on them.
Denials
Checked first, most containing first. See Approvals and risk appetite for the order.
| Code | Label | Meaning |
|---|---|---|
denied_scope_contained | Scope contained | The organisation's gateway access is contained, so nothing under it may run. |
denied_killswitched | Kill switch active | A kill switch is active for this subject; running servers were terminated. |
denied_unknown_identity | Unknown identity | The calling agent identity isn't registered with the gateway. |
denied_identity_contained | Identity contained | This agent identity is quarantined or killed. |
denied_server_unknown | Unknown server | The MCP server isn't one this project has registered. |
denied_no_entitlement | No entitlement | The identity hasn't been granted this server or tool. |
denied_surface_unreviewed | Surface unreviewed | The server changed the tools it advertises and the change hasn't been acknowledged. |
denied_not_allowlisted | Not allowlisted | The tool isn't on the allowlist for this caller. |
denied_rbac | Insufficient role | The caller's role doesn't permit this. |
denied_builtin_disabled | Built-in disabled | The organisation's policy disables this built-in tool. |
denied_subagent_not_granted | Sub-agent not granted | The agent may not invoke this sub-agent. |
denied_untrusted_context | Untrusted context | Untrusted content had entered the context, and this tool must not run after that. |
denied_model_not_entitled | Denied model not entitled | The organisation isn't entitled to use this model. |
denied_route_classification | Denied route classification | The data classification isn't allowed on this model's route. |
denied_model_killswitched | Denied model killswitched | A kill switch is active for this model. |
Approval posture
Decided when a tool is attached to an agent.
| Code | Effect | Label | Meaning |
|---|---|---|---|
require_approval_pinned | Approval required | Approval pinned on | Someone set this resource to always require approval. |
require_approval_critical_guard | Approval required | Critical-risk guard | Critical-risk resources always require a person. |
require_approval_appetite_gate | Approval required | Above risk appetite | The risk is at or above the tier this project tolerates without approval. |
require_approval_unclassified | Approval required | Unclassified resource | The resource carries no risk classification, so approval is required until it does. |
allowed_pinned | Allowed | Approval pinned off | Someone set this resource to never require approval. |
allowed_below_appetite | Allowed | Within risk appetite | The risk is below the tier requiring approval. |
allowed_bypass_all | Allowed | Appetite bypasses all | The project's risk appetite requires approval for nothing. |
At call time
| Code | Effect | Label | Meaning |
|---|---|---|---|
allowed | Allowed | Allowed | The call was permitted. |
allowed_internal_caller | Allowed | Internal caller | The caller is the platform itself rather than an agent. |
allowed_approval_discharged | Allowed | Approval discharged | Approval was required and the caller carries the approval. |
require_approval_undischarged | Approval required | Approval not discharged | Approval is required and nothing has discharged it. |
allowed_builtin_enabled | Allowed | Built-in enabled | The organisation's policy enables this built-in tool. |
allowed_builtin_default | Allowed | Built-in default | The organisation hasn't configured this built-in, and the default is to allow it. |
When no decision could be obtained
Recorded by an enforcement point that couldn't get a decision, so a refusal for that reason is never mistaken for a policy that said no.
| Code | Effect | Label | Did not hold |
|---|---|---|---|
denied_pdp_unavailable | Denied | Policy engine unavailable | Yes |
denied_no_caller_context | Denied | No caller context | Yes |
How an approval was resolved
Recorded when a person was (or couldn't be) asked to approve a call. Each links to the oversight record holding who decided and when.
| Code | Effect | Label | Meaning | Did not hold |
|---|---|---|---|---|
discharged_human_approved | Allowed | Approved by a person | A person was asked and approved. | |
discharged_human_rejected | Denied | Rejected by a person | A person was asked and refused. | |
discharged_timed_out | Denied | Approval timed out | A person was asked and didn't answer in time. | Yes |
discharged_autonomous_refused | Denied | Refused, no human | The run had no person to ask, so it refused rather than proceeding. | |
discharged_no_channel | Denied | No approval channel | Nobody could be asked: the run had no channel to a person at all. | Yes |
discharged_auto_approved_fail_open | Allowed | Auto-approved (fail-open) | The enforcement point approved on its own because the machinery it needed was unavailable. | Yes |
Codes without a label
If a decision carries a code the app has no label for — including the three model codes above — the app shows the raw code turned into words (for example, denied_model_not_entitled reads "Denied model not entitled") rather than leaving it blank.