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.

  • An API key β€” You have generated a key and stored it securely. The key must belong to a user with the Owner role. See Generating an API key.

  • 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.

API keys carry the Owner role, which can create, approve, deny, and revoke requests. In production, route approvals through your access policies rather than approving every request with the same automation key.

Set your base URL and authentication

Every endpoint lives under your organization's base URL and authenticates with a bearer token:

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

Include the key in the Authorization header on every request:

curl -H "Authorization: Bearer ${P0_API_KEY}" "${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 includes its request ID. 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:

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 or invalid API key

Confirm the Authorization: Bearer header is set and the key has not been deleted. Generate a new key if needed.

403 Forbidden

The key's user lacks permission for the action

Use a key belonging to a user with the Owner role. See Role-based access control.

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 access policy.

Last updated