> For the complete documentation index, see [llms.txt](https://docs.openiam.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.openiam.com/administration-guide/pbac/trace-a-decision.md).

# Trace a decision

Find why one request was allowed or refused, read which policy determined it, and get at the per-policy participation detail the decision screen does not show.

## What this is, and when you need it

Somebody was refused and wants to know why, or a shadow rollout needs reviewing before it is enforced. The **Decision Log** shows every PBAC decision the engine has served, newest first, and names the policies that determined each one.

Simulation runs are not shown here — they govern no real access.

## At a glance

|                          |                                                                                                           |
| ------------------------ | --------------------------------------------------------------------------------------------------------- |
| **You will end up with** | The decision for a specific request, and the policy that caused it                                        |
| **Where**                | **Administration → PBAC Policies** → **Decision Log**; the same events in **Administration → Log Viewer** |
| **You need first**       | The principal id or resource id, and roughly when the request happened                                    |
| **Takes**                | Minutes                                                                                                   |
| **Reversible**           | Read-only                                                                                                 |

## The decision log is a view over the audit log

This is the fact that makes the rest useful: PBAC decisions are **not a separate store**. They are recorded in the OpenIAM audit log as `PBAC_REQUEST` events, and this screen is that log narrowed to policy decisions.

So everything true of audit events is true of these: they appear in the [Log viewer](/administration-guide/operations/find-audit-evidence.md), they can be forwarded to syslog like any other event, and they age out under the same retention rules — see [Audit actions and retention](/administration-guide/reference/audit-actions-and-retention.md).

## Find the decision

Filter by principal id, resource id, decision (`ALLOW` or `DENY`) and a from/to time range, then click **Search**. Filters apply on search rather than as you type.

From 2026.10.2 the decisions the MCP server asks for can also be filtered by **Invoking system**, **Agent**, **Tool** and **Gate mode**, an **MCP** column shows the agent behind a call, and the **Policy impact** card counts, for one policy ID, the calls its shadow decision would have changed; see [Read the decision log and the impact view](/administration-guide/federation/mcp-server/mcp-policies.md#read-the-decision-log-and-the-impact-view).

| Field                             | What it records                                                                                                                                                                                                                                                                                                                                                 |
| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **When**                          | The decision timestamp                                                                                                                                                                                                                                                                                                                                          |
| **Principal / Resource / Action** | The fully-qualified Cedar identities — `Openiam::User::Human::"3000"`                                                                                                                                                                                                                                                                                           |
| **Requested by**                  | The caller that asked for the decision                                                                                                                                                                                                                                                                                                                          |
| **Decision**                      | `ALLOW` or `DENY` — the decision that was **served**. A tool call on the MCP server can also be served as `NO_POLICY_ALLOW`, `NO_POLICY_DENY` or `UNAVAILABLE`, when no policy applied or the service could not be reached                                                                                                                                      |
| **Determining policies**          | The determining policies, so a refusal traces to the rule that caused it. For a tool call on the MCP server the column shows the call's `MCP_POLICY_IDS` instead: every policy that applied to the call, not only the one that decided it, so a refusal by default deny lists policies that did not forbid it. The tool error's message names a forbid that did |

## What the screen does not show

Each audit entry records more than the columns display. Per applicable policy, it records **how that policy participated** — applied, observed as shadow, or skipped as outside a partial rollout — together with the enforcement mode in force at the time, including the percentage for a `PARTIAL` policy.

Shadow policies additionally record what they *would have* decided.

To read any of that, open the underlying audit entry in the Log viewer. It is the difference between "this request was denied" and "this request was denied, and the policy you are about to enforce would have allowed it".

{% hint style="info" %}
**The audit result records whether the evaluation succeeded, not whether it allowed.** A `DENY` is a perfectly successful decision — it is the engine working. A *failure* means the engine could not evaluate the request at all, which is a different problem with a different cause, usually an unguarded attribute.

Do not read failures as denials when counting refusals, and do not read denials as errors when hunting for faults.
{% endhint %}

## Verification

| What to check                                    | How                                                                                                                                                                                                      |
| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| You are looking at the served decision           | The **Decision** column is always what was served, never what a shadow policy would have decided                                                                                                         |
| Which rule refused a request                     | The **Determining policies** column names the determining statements; for an MCP tool call, read the message of the tool error, `forbidden by policy` with the policy ID or `no policy permits the call` |
| Whether a shadow policy would have differed      | Open the audit entry; the shadow outcome is recorded as informational text                                                                                                                               |
| A decision is genuinely absent, not filtered out | Widen the time range and clear the decision filter before concluding nothing was recorded                                                                                                                |
| The same events from the audit side              | Search `PBAC_REQUEST` in **Administration → Log Viewer**                                                                                                                                                 |

## When it goes wrong

| Symptom                                         | Cause                                                                                        | Fix                                                                                                                            |
| ----------------------------------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| A request you expected is not in the log        | The time range or a filter excludes it, or no policy was applicable so nothing was evaluated | Widen the range first. If it is genuinely absent, the request never reached the engine                                         |
| A decision names no determining policy          | The request matched nothing and was denied by default                                        | Expected. Cedar denies by default; add a policy that permits it if it should be allowed                                        |
| The log shows failures rather than decisions    | The engine could not evaluate — typically an unguarded optional attribute                    | [The policy model](/administration-guide/pbac/policy-model.md#the-attribute-rule-that-causes-most-errors)                      |
| A shadow policy's outcome is not in the columns | Only the served decision is columnar                                                         | Open the audit entry for the per-policy participation detail                                                                   |
| Decision entries stopped appearing              | Retention aged them out, or the audit pipeline is not running                                | [Audit actions and retention](/administration-guide/reference/audit-actions-and-retention.md); confirm the audit service is up |
| Simulation results are missing from the log     | Simulations are never logged here, by design                                                 | Read them on the [Simulation](/administration-guide/pbac/simulate-a-policy.md) tab                                             |

## Related

* [Roll a policy out safely](/administration-guide/pbac/roll-out-a-policy.md) — divergence review, which is read here
* [Find audit evidence](/administration-guide/operations/find-audit-evidence.md) — the general audit search these events sit in
* [Audit actions and retention](/administration-guide/reference/audit-actions-and-retention.md) — how long `PBAC_REQUEST` survives
* [The policy model](/administration-guide/pbac/policy-model.md) — why a failure is not a denial
* [Decide MCP tool calls with policies](/administration-guide/federation/mcp-server/mcp-policies.md) — the no-policy outcomes and the impact view

*Applies to OpenIAM 2026.8.1. Last reviewed 22 October 2026.*


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.openiam.com/administration-guide/pbac/trace-a-decision.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
