> 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/getting-started/configuring-access-policies.md).

# Configure Access Policies

Access policies give you fine-grained control over your organization's just-in-time access workflow. With access policies, you define who can request access to specific resources, and who approves those requests.

This guide walks you through creating your first access policies in Policy Studio, covering three common scenarios:

1. [Route requests by team to the correct approver](#scenario-1-route-requests-by-team)
2. [Restrict access to production resources](#scenario-2-restrict-access-to-production-resources)
3. [Auto-approve requests for on-call engineers](#scenario-3-auto-approve-on-call-engineers)

{% hint style="info" %}
Access policies require a Pro-tier P0 subscription. If you are on the free tier, your organization uses [default approvals](/access-management/just-in-time-access/approving-access.md#configuring-approvals) instead.
{% endhint %}

## Prerequisites

Before you begin, confirm the following:

* You have a P0 account with the **Owner** or **Security Reviewer** role.
* You have completed the [Getting Started with Just-in-Time Access](/getting-started/getting-started-with-just-in-time-access.md) guide, including installing at least one resource integration.
* You have a [directory integration](/integrations/directory-integrations.md) connected (Google Workspace, Okta, or Microsoft Entra ID) if you plan to route by group.
* *(Optional)* You have a [PagerDuty](/integrations/approval-integrations/pagerduty.md) or [Incident.io](/integrations/approval-integrations/incidentio.md) integration installed if you plan to use on-call auto-approvals.

## Open Policy Studio

1. Sign in to [p0.app](https://p0.app).
2. Navigate to **Policy Studio** in the left sidebar, or go directly to `https://p0.app/o/<your-organization>/policies`.

Policy Studio displays your current access policies as a YAML workflow. If this is your first time, the editor is empty — your organization is using default approvals.

{% hint style="info" %}
Saving any policy configuration in Policy Studio switches your organization from default approvals to policy-based approvals. All access requests are then evaluated against your access policies.
{% endhint %}

## Scenario 1: Route requests by team

Route your engineering team's requests to the SRE team for approval, and your data team's requests to the Data Ops team.

1. In Policy Studio, enter the following access policies:

```yaml
- requestor:
    type: group
    id: engineering@yourcompany.com
    label: Engineering
    directory: workspace
  resource:
    type: any
  approval:
    - type: group
      id: sre@yourcompany.com
      label: SRE Team
      directory: workspace
      options: {allowOneParty: false}
- requestor:
    type: group
    id: data-team@yourcompany.com
    label: Data Team
    directory: workspace
  resource:
    type: integration
    service: snowflake
  approval:
    - type: group
      id: data-ops@yourcompany.com
      label: Data Ops
      directory: workspace
      options: {allowOneParty: false}
```

2. Replace the group email addresses with your organization's actual directory groups.
3. Click **Save** to activate the access policies.

**What this does:**

* Any engineer who requests access to any resource gets routed to the SRE team for approval.
* Any data team member who requests Snowflake access gets routed to Data Ops for approval.
* `allowOneParty: false` prevents requestors from approving their own requests.

{% hint style="warning" %}
If a request does not match any access policy, P0 rejects it with the message: "This resource doesn't exist, or your organization doesn't allow this principal to access this resource." Add a catch-all policy at the end of your workflow if you want unmatched requests to fall through to default approvers.
{% endhint %}

### Add a catch-all policy

To ensure unmatched requests still reach your security reviewers, add this policy at the end of your workflow:

```yaml
- requestor:
    type: any
  resource:
    type: any
  approval:
    - type: p0
```

The `type: p0` approval routes requests to the approvers configured on your Settings page.

## Scenario 2: Restrict access to production resources

Block requests to production AWS accounts while allowing development and staging access with different approval requirements.

1. In Policy Studio, add the following policies. Replace the AWS account IDs and Okta group IDs with your own values:

```yaml
# Development — one-party approval (engineers can self-approve)
- requestor:
    type: group
    id: 00g5j4jojlGZMzfhM69
    label: Engineers
    directory: okta
  resource:
    type: integration
    service: aws
    filters:
      policy: {effect: keep, key: arn, pattern: "^arn:aws:iam::111111111111:policy/"}
  approval:
    - type: group
      id: 00g5j4jojlGZMzfhM69
      label: Engineers
      directory: okta
      options: {allowOneParty: true}

# Staging — peer approval required, reason mandatory
- requestor:
    type: group
    id: 00g5j4jojlGZMzfhM69
    label: Engineers
    directory: okta
  resource:
    type: integration
    service: aws
    filters:
      policy: {effect: keep, key: arn, pattern: "^arn:aws:iam::222222222222:policy/"}
  approval:
    - type: group
      id: 00g5j4jojlGZMzfhM69
      label: Engineers
      directory: okta
      options: {allowOneParty: false, requireReason: true}

# Production — deny all access
- requestor:
    type: any
  resource:
    type: integration
    service: aws
    filters:
      policy: {effect: keep, key: arn, pattern: "^arn:aws:iam::333333333333:policy/"}
  approval:
    - type: deny
```

2. Click **Save**.

**What this does:**

* **Development** (account `111111111111`): Engineers can self-approve their own requests.
* **Staging** (account `222222222222`): Engineers need a peer to approve, and must provide a reason.
* **Production** (account `333333333333`): P0 denies all requests. No one can request access through P0.

{% hint style="info" %}
Deny policies always take precedence. If any matching policy specifies `type: deny`, the request is denied immediately, regardless of other matching policies.
{% endhint %}

### Exclude dangerous permissions

To further restrict which AWS permissions engineers can request, add filters that remove overly broad policies:

```yaml
resource:
  type: integration
  service: aws
  accessType: policy
  filters:
    policy: {effect: remove, key: arn, pattern: FullAccess}
    tag: {effect: keep, key: P0Grantable, pattern: "^true$"}
```

This removes any policy containing "FullAccess" in its ARN, and only keeps policies tagged with `P0Grantable: true`.

## Scenario 3: Auto-approve on-call engineers

Automatically approve requests from engineers who are currently on-call in PagerDuty or Incident.io, while routing all other requests to the SRE team.

1. Confirm that your [PagerDuty](/integrations/approval-integrations/pagerduty.md) or [Incident.io](/integrations/approval-integrations/incidentio.md) integration is installed.
2. In Policy Studio, add the following policies:

{% tabs %}
{% tab title="PagerDuty" %}

```yaml
# On-call engineers get auto-approved
- requestor:
    type: any
  resource:
    type: integration
    service: aws
  approval:
    - type: auto
      integration: pagerduty
      options: {requireReason: true}
    - type: group
      id: sre@yourcompany.com
      label: SRE Team
      directory: workspace
      options: {allowOneParty: false}
```

{% endtab %}

{% tab title="Incident.io" %}

```yaml
# On-call engineers get auto-approved
- requestor:
    type: any
  resource:
    type: integration
    service: aws
  approval:
    - type: auto
      integration: incidentio
      options: {requireReason: true}
    - type: group
      id: sre@yourcompany.com
      label: SRE Team
      directory: workspace
      options: {allowOneParty: false}
```

{% endtab %}
{% endtabs %}

3. Click **Save**.

**What this does:**

* If the requestor is currently on-call (as determined by PagerDuty escalation policies or Incident.io schedules), P0 automatically approves their request for one hour.
* If the requestor is not on-call, P0 routes the request to the SRE team for manual approval.
* `requireReason: true` ensures all requests include a justification in the audit log, even auto-approved ones.

### Add escalation for urgent requests

You can also configure on-call users as escalation approvers. When a request is pending, the requestor can escalate it to the on-call engineer:

```yaml
approval:
  - type: p0
    options: {requireReason: true, allowOneParty: false}
  - type: escalation
    integration: pagerduty
    options: {requireReason: true, allowOneParty: false}
    services: [PSJXXXG]
```

Replace `PSJXXXG` with your PagerDuty service ID. When the requestor escalates, PagerDuty creates an incident against the specified service, and the on-call engineer receives both a PagerDuty alert and a P0 approval notification.

## Verify your access policies

After saving your access policies, verify that they work as expected:

1. Open Slack and use `/p0 request` (or the [web request modal](/access-management/just-in-time-access/requesting-access/web-request-modal.md)) to create a test access request that matches one of your policies.
2. Confirm that the correct approver receives the approval notification.
3. If you configured deny policies, submit a request that matches a denied resource and confirm that P0 blocks it.
4. Check the **Activity** page at `https://p0.app/o/<your-organization>/jit/activity` to view the request and verify the policy decision.

{% hint style="info" %}
When multiple policies with different manual approvers match the same request, P0 notifies all matching approvers. Approval from any one of them is sufficient.
{% endhint %}

## Troubleshooting

| Symptom                                                | Cause                                                                                    | Solution                                                                                                                                                                                  |
| ------------------------------------------------------ | ---------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Request rejected with "This resource doesn't exist..." | No access policy matches the request.                                                    | Add a catch-all policy or verify that your requestor and resource filters match the request.                                                                                              |
| Wrong approver notified                                | A broader policy matches before the specific one.                                        | Reorder policies so more specific policies come first. Deny policies always take precedence regardless of order.                                                                          |
| Auto-approval not working                              | The requestor is not on-call, or the PagerDuty/Incident.io integration is not installed. | Verify the requestor's on-call status in your incident management tool, and confirm the integration is active in **Integrations**.                                                        |
| Filter not matching                                    | Regex pattern mismatch.                                                                  | Patterns are unanchored by default. Use `^` and `$` to anchor. P0 uses the [JavaScript regex dialect](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions). |

## What's next

Now that you have access policies configured, you can:

* Set up [pre-approvals](/access-management/just-in-time-access/approving-access/pre-approving-access.md) for standing access during projects or maintenance windows.
* Add [resource filters](/access-management/just-in-time-access/request-routing.md) for fine-grained control over which resources are requestable per service.
* Connect a [SIEM integration](/integrations/siem-integrations.md) to send access request audit logs to Datadog or Splunk.
* Review the full [request routing reference](/access-management/just-in-time-access/request-routing.md) for all available requestor, resource, and approval types.


---

# 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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.p0.dev/getting-started/configuring-access-policies.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
