For the complete documentation index, see llms.txt. This page is also available as Markdown.

πŸ€–Automate access requests with the API

Request, approve, deny, and revoke just-in-time access programmatically with the P0 Command and Access Requests APIs. Drive access from bots, CI/CD pipelines, and internal tooling instead of the P0 da

This guide shows you how to drive P0 just-in-time access from your own code. You use the Command API to create an access request, check its status, and then use the Access Requests API to approve, deny, or revoke it.

Automating these steps lets you wire P0 into bots, CI/CD pipelines, and internal security tooling β€” for example, requesting a short-lived role during a deployment, or auto-approving access when an alert fires. Every request still runs through your organization's access policies, guardrails, and audit trail, exactly as it does in the dashboard.

Prerequisites

Before you begin, confirm the following:

  • A P0 organization β€” You know your organization slug (orgId), shown in the P0 dashboard URL and in the CLI as your org name.

  • A P0 API token β€” You have a token, stored securely, belonging to an identity in your P0 organization. Approving and denying also require that identity to be an approver under your access policies. See Authenticating with the P0 API for how to get a token.

  • A configured resource integration β€” At least one integration (AWS, Google Cloud, Azure, SSH, and so on) is installed, so there is something to request. See Resource integrations.

  • A JSON tool β€” The examples use curl and jq to send requests and read responses.

A token carries the P0 role of the identity behind it. An Owner can revoke any grant, but approving and denying requests follow the rules configured in Policy Studio rather than the Owner role, and any member of your organization can create a request. In production, route approvals through Policy Studio rather than approving every request with the same automation identity.

Set your base URL and authentication

Every endpoint lives under your organization's base URL and authenticates with a bearer token. To get a token, see Authenticating with the P0 API.

export P0_ORG="your-org-slug"
export P0_API_TOKEN="your-token"
export P0_BASE_URL="https://api.p0.app/o/${P0_ORG}"

Include the token in the Authorization header on every request:

curl -H "Authorization: Bearer ${P0_API_TOKEN}" "${P0_BASE_URL}/..."

Create an access request

Send a POST request to the Command API at /o/{orgId}/command. The body has two fields:

Field
Type
Description

argv

array of strings

The request arguments, matching the p0 request CLI command with the leading p0 removed.

scriptName

string

The client name to record. Use "p0".

The argv array mirrors the CLI exactly. The command p0 request aws role MyReadOnlyRole --account 123456789012 --reason "..." becomes the array below:

The response confirms that P0 created the request and returns its ID in the id field. Capture the ID for the next steps:

To find the right argv for any resource, run the equivalent CLI command with --help β€” for example p0 request gcloud --help. See p0 request for the full list of providers and subcommands. For the complete request and response schema, see the Command API reference.

Check the request status

To read the current state of a request from a script, send a GET request to /o/{orgId}/permission-requests/{requestId}. It returns the full request document as plain JSON:

Poll this endpoint to wait for a decision β€” for example, until the status moves from pending to approved and provisioned.

The /command/{requestId}/poll endpoint streams live updates over Server-Sent Events for interactive clients such as the CLI and web app. For one-shot status checks in automation, use the GET /permission-requests/{requestId} endpoint shown above.

Approve, deny, or revoke the request

The Access Requests API acts on an existing request by ID. Each action is a POST to /o/{orgId}/permission-requests/{requestId}/{action}, where {action} is approve, deny, or revoke.

Approve a request:

Each action returns a success confirmation:

When you approve a request, you can override the grant duration with an optional body. Set expirationLength to a P0 duration such as 30m, 2h, or 1d, and set isCustomExpiry to true:

Deny a pending request, or revoke an active grant before it expires, by changing the action. To deny a pending request:

To revoke an active grant:

Verify it worked

Confirm the full lifecycle end to end:

  1. Check the status. Send a GET to /permission-requests/{requestId} and confirm the state reflects your action (approved, denied, or revoked).

  2. Confirm provisioning. For an approved request, verify the underlying grant exists β€” for example, assume the AWS role with p0 aws role assume, or check the resource directly.

  3. Review the audit trail. Each action writes an audit event (api.jit.permission-requests.approved, .denied, or .revoked). Find it in the P0 dashboard or in your SIEM integration.

Troubleshooting

Symptom
Cause
Fix

401 Unauthorized

Missing, invalid, or expired token

Confirm the Authorization: Bearer header is set and the token is valid. The recommended Google Cloud and CLI tokens are short-lived, so mint a fresh one if it may have expired.

403 Forbidden

The token's identity lacks permission for this action

Confirm the identity is a member of your P0 organization. For approve and deny, it must also be an approver under the matching rule in Policy Studio. Owners can revoke any grant.

404 Not Found on an action

Wrong requestId or orgId, or the request no longer exists

Recheck the ID returned when you created the request and confirm P0_ORG matches your organization slug.

argv is not an array of strings

The argv field is missing or malformed

Send argv as a JSON array of strings, and put each flag and its value as separate elements.

Request stays pending

An approval policy requires a human approver

Approve it with the Access Requests API, or adjust the matching rule in Policy Studio.

Last updated