> For the complete documentation index, see [llms.txt](https://docs.p0.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.p0.dev/posture/create-a-custom-monitor.md).

# Create a custom monitor

P0 runs its built-in monitors against your environment on every scan to surface common access vulnerabilities. When you need to enforce a policy that's specific to your organization—for example, flagging unused privileged grants or credentials that violate your rotation policy—you create a custom monitor.

A custom monitor turns an [inventory query](/inventory/query-search.md) into a recurring check. P0 re-runs the query on every scan and reports matches as findings in [Monitor Results](/posture/monitor-results.md), alongside your built-in monitors.

## Prerequisites

Before you start, make sure you have:

* A P0 account with the **Owner** or **Admin** role. See [Role-Based Access Control](/p0-management/role-based-access-control.md).
* At least one [resource integration](/integrations/resource-integrations.md) connected to an [environment](/environments/creating-an-environment.md).
* A completed access scan. If you haven't run one yet, follow [Getting Started with Inventory & Posture](https://github.com/p0-security/p0-docs/blob/main/user-guides/getting-started-with-inventory-and-posture.md).
* Familiarity with P0 [query expressions](/inventory/query-search.md). This guide uses them to define what the monitor detects.

## Build and save the monitor

You create custom monitors from the **Inventory** page, where you can write and test a query before promoting it to a monitor.

1. Select **Inventory** in the P0 app sidebar.
2. Select what the monitor evaluates from the **show** control—`credentials`, `identities`, `entitlements`, or `resources`. For example, select `entitlements` to monitor grants.
3. Enter a query in the **where** field that isolates the vulnerability you want to detect. To find entitlements that grant critical-risk privileges that no one has used, enter:

   ```
   usage:type:"unused"->risk:CRITICAL
   ```

   This matches entitlements connected to an unused privilege that carries a `CRITICAL` risk in the [IAM Privilege Catalog](https://catalog.p0.dev/risks).
4. Review the results. Adjust the query until only the grants you want to flag appear. Select **view** on any result to see an **Explanation** of why it matched.
5. Select **Save Search**.
6. Enable the **Create a monitor for this search?** toggle.
7. Enter a **title**, **description**, and **severity** for the monitor. Write the description so a finding's assignee understands the risk and how to resolve it.
8. Save the monitor.

{% hint style="info" %}
To model a new monitor on an existing one, open a built-in monitor in [Monitor Results](/posture/monitor-results.md) and reuse its query as a starting point. For example, the built-in unused service-account key monitor uses `show = credential` with:

```
credential=enabledKey:"true"
credential=last40:"unused"
principal=type:"service-account"
principal=status:"active"
```

{% endhint %}

## Verify the monitor

Confirm the monitor is active and reporting:

1. Select **Posture** in the sidebar.
2. Find your monitor by its title in the monitor list. It appears with the severity you assigned.
3. Select the monitor to open its [Monitor Results](/posture/monitor-results.md) page and review the findings from the most recent scan.

P0 re-evaluates the monitor on every scan. New matches appear as open findings, and P0 resolves findings automatically once a grant no longer matches the query.

From the results, you can [assign, ignore, or review fixes](/posture/finding-details.md) for findings, and route them to your [ticketing system](/integrations/tracker-integrations.md).

## Troubleshooting

| Problem                                    | Cause                                               | Fix                                                                                                                                                  |
| ------------------------------------------ | --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| The monitor returns no findings            | The query is too narrow, or no current data matches | Re-run the query on the Inventory page and confirm it returns the expected results before saving                                                     |
| The monitor returns too many findings      | The query is too broad                              | Add [type, attribute, or via matches](/inventory/query-search.md) to narrow scope—for example, scope to one provider with `entitlement:provider:aws` |
| The monitor isn't in the Posture list      | Findings appear after the next scan completes       | Wait for the next scan, or trigger a scan from the [environment settings](/environments/settings.md)                                                 |
| Results changed unexpectedly between scans | The underlying access data changed                  | Open a finding and review its **Explanation** to see why it now matches                                                                              |

## What's next

* Tune detection with the full [query expression reference](/inventory/query-search/search-reference.md).
* [Analyze and resolve findings](/posture/finding-details.md) the monitor produces.
* Connect a [tracker integration](/integrations/tracker-integrations.md) to assign findings automatically.
