> 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/access-management/just-in-time-access/approving-access/auto-approve-on-call-access.md).

# Auto-approve access for on-call engineers

This guide shows you how to grant just-in-time access automatically to engineers who are currently on-call, using your PagerDuty escalation policies or Incident.io schedules. When an on-call responder requests a covered resource, P0 approves the request without waiting for a human approver, then expires the access after one hour.

Use this pattern for break-glass and incident-response workflows. Responders need fast access during an incident, but you still want every grant to be time-boxed, logged, and tied to an active on-call shift.

## Prerequisites

Before you begin, confirm the following:

* **P0 organization owner role** — You configure integrations and access policies as an organization owner.
* **An on-call provider** — Either a PagerDuty account where you are an admin, or an Incident.io account where you are an administrator with API key access.
* **A resource integration** — At least one resource integration (AWS, Google Cloud, Azure, SSH, Kubernetes, or another) installed, so there is something to grant access to. See [Resource integrations](/integrations/resource-integrations.md).
* **Matching identities** — The email addresses your engineers use in PagerDuty or Incident.io match the identities they use to sign in to P0.

{% hint style="warning" %}
Anyone who can place themselves on-call for an enabled schedule can grant themselves access without further approval. Restrict who can edit your on-call schedules and overrides accordingly.
{% endhint %}

## Step 1: Connect your on-call provider

Install the approval integration for the provider you use.

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

1. Navigate to **Integrations** on [p0.app](https://p0.app), then select **PagerDuty**.
2. Click **Install integration**. P0 redirects you to PagerDuty's consent screen.
3. Approve the installation to return to P0.

For full details, see [PagerDuty](/integrations/approval-integrations/pagerduty.md).
{% endtab %}

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

1. Navigate to **Integrations** on [p0.app](https://p0.app), then select **Incident.io**.
2. Create an API key in your Incident.io account with permissions to view data, create and edit incidents, manage organization settings, view catalog types and entries, and read schedules. See the [Incident.io API documentation](https://docs.incident.io/integrations/api-overview#where-can-i-find-the-api-keys).
3. Enter the API key in P0 and click **Install integration**. P0 validates the key and creates a custom field in your Incident.io account.

For full details, see [Incident.io](/integrations/approval-integrations/incidentio.md).
{% endtab %}
{% endtabs %}

## Step 2: Select the schedules that grant access

Tell P0 which on-call rotations qualify a requestor for automatic approval.

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

1. On the **PagerDuty** integration page, find the escalation policy selector.
2. Select one or more escalation policies whose active on-call members receive automatic approval.
3. Save your changes.

P0 approves a request when the requestor is currently on-call for one of the selected escalation policies.
{% endtab %}

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

1. On the **Incident.io** integration page, open the auto-approval settings.
2. Select one or more schedules from the dropdown. P0 fetches available schedules from your Incident.io account.
3. Save your changes.

P0 approves a request when the requestor is currently on-call for one of the selected schedules.
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
For Incident.io, you must select at least one schedule. If you select none, auto-approval denies every request.
{% endhint %}

## Step 3: Add an auto-approval rule to your access policy

The integration tells P0 *who* is on-call. An access policy tells P0 *which requests* to auto-approve. Add an `auto` approval rule to your policy configuration.

1. Navigate to **Policy Studio** on [p0.app](https://p0.app).
2. Add a rule with the requestor, resource, and approval sections shown in the following example.
3. Save the policy configuration.

The following policy auto-approves any AWS request from an on-call engineer and requires a reason on every request:

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

```yaml
- requestor:
    type: any
  resource:
    type: integration
    service: aws
  approval:
    - type: auto
      integration: pagerduty
      options: { requireReason: true }
```

{% endtab %}

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

```yaml
- requestor:
    type: any
  resource:
    type: integration
    service: aws
  approval:
    - type: auto
      integration: incidentio
      options: { requireReason: true }
```

{% endtab %}
{% endtabs %}

A matching request is approved automatically for one hour when the requestor is on-call. The `requireReason` option records why each grant was necessary — useful for incident review. Set it to `false` to skip the reason prompt.

{% hint style="info" %}
Change `service: aws` to the integration you want to cover (`gcloud`, `azure`, `ssh`, `k8s`, and others), or use `resource: { type: any }` to cover every resource. To narrow the rule to specific resources, add [filters](/access-management/just-in-time-access/request-routing.md#integration). For the full policy format, see [Access Policies](/access-management/just-in-time-access/request-routing.md).
{% endhint %}

## Step 4 (optional): Fall back to manual approval

On-call auto-approval pairs well with a manual approver for everyone else. List both approval types in the same rule — P0 combines them so that an on-call requestor is auto-approved, while anyone off-call routes to your security reviewers.

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

```yaml
- requestor:
    type: any
  resource:
    type: integration
    service: aws
  approval:
    - type: auto
      integration: pagerduty
      options: { requireReason: true }
    - type: p0
```

{% endtab %}

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

```yaml
- requestor:
    type: any
  resource:
    type: integration
    service: aws
  approval:
    - type: auto
      integration: incidentio
      options: { requireReason: true }
    - type: p0
```

{% endtab %}
{% endtabs %}

The `p0` approval type routes to the security reviewers configured on your **Access control** settings. See [Approving access](/access-management/just-in-time-access/approving-access.md#configuring-approvals).

## Verify it worked

Confirm the rule before you rely on it during an incident:

1. Make sure a test user is on-call for one of the selected schedules (add a temporary override in PagerDuty or Incident.io if needed).
2. As that user, request a covered resource — for example, run `p0 request aws role MyReadOnlyRole --account 123456789012 --reason "Testing on-call auto-approval"`.
3. Confirm the request is approved automatically, without a human approver acting on it.
4. Open **Access management > History** at `https://p0.app/o/<your-org>/access-management/history` and confirm the request shows automatic approval and the reason you supplied.
5. As a user who isn't on-call, request the same resource and confirm the request routes to manual approval (if you added the Step 4 fallback) or the system denies it (if you didn't).

## Troubleshooting

| Symptom                                                     | Cause                                                                   | Fix                                                                                                                                                                                            |
| ----------------------------------------------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| On-call user's request is denied                            | The user's P0 email doesn't match their PagerDuty or Incident.io email  | Align the email addresses across both systems                                                                                                                                                  |
| Every request is denied (Incident.io)                       | No schedules selected in auto-approval settings                         | Select at least one schedule on the Incident.io integration page                                                                                                                               |
| Request routes to manual approval instead of auto-approving | The requestor isn't currently on-call, or their schedule isn't selected | Confirm the user's active on-call shift and select their escalation policy or schedule in Step 2                                                                                               |
| Rule has no effect                                          | The resource or requestor in the policy doesn't match the request       | Check the `service` value and requestor type against the request; see [Evaluation of access policies](/access-management/just-in-time-access/request-routing.md#evaluation-of-access-policies) |
| Access expires too soon                                     | Auto-approval grants last one hour by design                            | For longer standing access, use [pre-approvals](/access-management/just-in-time-access/approving-access/pre-approving-access.md) instead                                                       |

## What's next

* [Escalate stuck requests to on-call approvers](/access-management/just-in-time-access/request-routing.md#escalation) with the `escalation` approval type, so on-call users can approve *others'* requests during an incident.
* [Pre-approve access](/access-management/just-in-time-access/approving-access/pre-approving-access.md) for planned work that's not tied to an on-call shift.
* [Configure access policies](/access-management/just-in-time-access/request-routing.md) to route different resources to different approvers.
* [PagerDuty](/integrations/approval-integrations/pagerduty.md) and [Incident.io](/integrations/approval-integrations/incidentio.md) integration reference.
