> 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/simulate-a-policy.md).

# Simulate a policy

Evaluate a policy version against real users and resources without touching live access, read the per-subject results, and stress-test a policy for throughput and latency.

## What this is, and when you need it

Simulation evaluates a policy version against **real principals and real resources without affecting any access**. It is how you find out what a policy would decide before it decides anything, and it is the step between authoring and activating.

It has a second use: run in stress mode to measure what a policy costs, before that cost lands on live decisions.

Simulation runs are **not written to the decision log and are not billed** — they govern nothing.

## At a glance

|                          |                                                                                          |
| ------------------------ | ---------------------------------------------------------------------------------------- |
| **You will end up with** | A per-subject table of what the policy would decide, plus latency and throughput figures |
| **Where**                | **Administration → PBAC Policies** → **Simulation**                                      |
| **You need first**       | A saved policy with at least one version, and users and resources worth testing against  |
| **Takes**                | Seconds to minutes, depending on subject count and mode                                  |
| **Reversible**           | Nothing to reverse — no live access is touched and no decision is recorded               |

## Set up a run

{% stepper %}
{% step %}

### Pick the policy and the version

The version in force is selected by default, and any other version can be chosen.

The selected version's Cedar text is loaded into an editor **and it is editable**. The run evaluates exactly the text shown — so you can try a change here and see its effect before committing it as a version. This is the fastest authoring loop available, and nothing you do in this box is saved.
{% endstep %}

{% step %}

### Choose the mode

**Simulation** runs one evaluation per subject; the decisions are the point. **Stress test** replays the subject set in loops at a requested concurrency; the timing is the point.

Stress test exposes three more controls: loops (up to 1,000), concurrency (up to 256), and an optional target TPS.
{% endstep %}

{% step %}

### Choose the principals

Either a **random sample** of users drawn from the directory — up to 1,000 per run — or an explicit list of **specific users**.

Use specific users while you are still checking correctness: a random sample tells you the shape of the outcome, a named list tells you whether the person you are worried about is allowed.
{% endstep %}

{% step %}

### Choose the resources

The candidate resources each principal is matched against, drawn at random per evaluation.

The picker is **type-scoped** — choose a type, then search within it. That is not a UI quirk: resources, groups, roles, organizations and users have separate search endpoints behind it.
{% endstep %}

{% step %}

### Run it, and let it poll

**Run Simulation** starts the run. Runs execute asynchronously and the results panel polls until it finishes, moving `PENDING` → `RUNNING` → `COMPLETED`, or `FAILED`.

A run cancelled mid-flight becomes `CANCELLED` and **keeps the results for the subjects it reached**, so cancelling a long stress test does not throw away what it already measured.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
**A tool call on the MCP server can be simulated from 2026.10.2, through the API.** This screen offers no MCP action type yet; a run launched through the simulation REST API may carry `actionType` `MCP_TOOL`, a tool as the action and an `mcp` context record. See [Simulate a tool call](/administration-guide/federation/mcp-server/mcp-policies.md#simulate-a-tool-call).
{% endhint %}

## Read the results

The header aggregates the run: subjects resolved against subjects requested, total evaluations, allowed / denied / error counts, actual throughput, and latency as average, 95th percentile and maximum. The policy text that was evaluated is shown beneath it — worth checking, because it may be the edited text rather than the saved version.

| Column                   | What it tells you                                                                                                                        |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
| **User / Resource**      | The principal and the resource it was matched against                                                                                    |
| **Decision**             | `ALLOW` or `DENY`. A subject whose evaluations all failed shows an **error** instead of a decision — that is not a deny                  |
| **Evaluations**          | How many times the pair was evaluated. Loops fold into one row: a 1,000-subject × 1,000-loop stress run leaves 1,000 rows, not a million |
| **Latency**              | Average and maximum for that row                                                                                                         |
| **Determining policies** | Which statements determined the decision — the answer to *"why did this user get denied?"*                                               |

{% hint style="info" %}
**Expect `DENY` rows for subjects the policy simply does not match.** Cedar denies by default, so a subject no policy permits is denied. A wall of denies in a simulation of one `permit` policy usually means the policy is working and the sample is mostly people it was never about — not that it is broken.

Read the **Determining policies** column before concluding anything from a deny.
{% endhint %}

## Verification

| What to check                    | How                                                                                                                                                                                                   |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| The run evaluated what you think | The policy text shown with the results is the text that ran — including any unsaved edit                                                                                                              |
| Known cases decide correctly     | Use **specific users** with a known expected outcome rather than a random sample                                                                                                                      |
| An error is not a deny           | The Decision column shows an error explicitly. Errors usually mean an unguarded attribute — [The policy model](/administration-guide/pbac/policy-model.md#the-attribute-rule-that-causes-most-errors) |
| Throughput is representative     | Stress-test evaluations travel the production path — the queue, the caches, the engine — so the numbers reflect what live callers would see                                                           |
| Nothing leaked into production   | Simulation runs never appear in the decision log and are never billed                                                                                                                                 |

## When it goes wrong

| Symptom                                            | Cause                                                                         | Fix                                                                                                                                                                   |
| -------------------------------------------------- | ----------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Every subject denies                               | Usually correct: default-deny for subjects the policy does not match          | Check **Determining policies**. If it names nothing, the policy did not apply to them                                                                                 |
| A subject shows an error rather than a decision    | The evaluation failed — most often an attribute read without a `has` guard    | Guard the attribute, then re-run                                                                                                                                      |
| Fewer subjects resolved than requested             | Some principals could not be resolved into Cedar entities                     | Compare *resolved* against *requested* in the header; the shortfall is the count                                                                                      |
| Results look nothing like live behaviour           | The editable text box was edited and the run used that, not the saved version | Re-select the version to reload its saved text                                                                                                                        |
| A simulation ignored the policy's enforcement mode | Expected — simulation evaluates the policy whatever its mode                  | Shadow and partial staging apply to live traffic only                                                                                                                 |
| The run is slow, and live decisions slowed too     | Simulation traffic shares the path but has its own queue                      | Confirm on [PBAC reference](/administration-guide/pbac/pbac-reference.md#infrastructure-dependencies); decision traffic is isolated from simulation traffic by design |

## Related

* [Create a policy](/administration-guide/pbac/create-a-policy.md) — where the version being simulated comes from
* [Roll a policy out safely](/administration-guide/pbac/roll-out-a-policy.md) — the next step, once it decides correctly
* [The policy model](/administration-guide/pbac/policy-model.md) — why an unguarded attribute errors instead of returning false
* [PBAC reference](/administration-guide/pbac/pbac-reference.md) — the simulation REST API, for driving runs from a pipeline
* [Decide MCP tool calls with policies](/administration-guide/federation/mcp-server/mcp-policies.md) — simulating a tool call

*Applies to OpenIAM 2026.8.1. Last reviewed 20 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/simulate-a-policy.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.
