> 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/p0-api/authenticating-with-the-p0-api.md).

# Authenticating with the P0 API

Get a bearer token to authenticate with the P0 Management API and the P0 Terraform provider, using a Google Cloud service-account token, the P0 CLI, or an API key.

P0's programmatic surfaces all authenticate the same way: with a bearer token. This includes the [Management API](/p0-management/management-api.md), the [just-in-time access API](/access-management/access-management/just-in-time-access/just-in-time-api.md), the [inventory export API](/inventory/inventory-export-api.md), and the [Manage integrations as code with the P0 Terraform provider](/getting-started/get-started-with-the-p0-terraform-provider.md).

You supply the token in one of two ways:

* **API and direct HTTP calls** — pass it in the `Authorization` header: `Authorization: Bearer <token>`.
* **Terraform provider** — set the `P0_API_TOKEN` environment variable or the provider's `api_token` attribute.

This page explains how to get a token and which method to use.

## Choose an authentication method

| Method                                                                                | Best for                              | Notes                                                              |
| ------------------------------------------------------------------------------------- | ------------------------------------- | ------------------------------------------------------------------ |
| [Google Cloud service-account token](#google-cloud-service-account-token-recommended) | CI/CD and automation                  | Recommended. Short-lived, no stored secret. Requires Google Cloud. |
| [P0 CLI token](#p0-cli-token)                                                         | Local development and interactive use | Tied to your P0 login. Short-lived.                                |
| [API key](#api-key-legacy)                                                            | Existing integrations                 | Legacy. Being phased out in favor of a service-account token.      |

The token's privileges come from the P0 role of the identity behind it, so grant each identity the least privilege it needs. See [Role-based access control](/p0-management/role-based-access-control.md).

## Google Cloud service-account token (recommended)

A workload running on Google Cloud can authenticate as a service account with a short-lived identity token, so no long-lived secret needs to live in your CI system. P0 accepts a Google-issued service-account identity token as a bearer token.

1. **Choose a service account** for the workload to run as.
2. **Grant it a P0 role.** In the P0 dashboard, open **P0 Management** → **Role-Based Access Control** and add the service account's email as a member. The role you assign governs what the identity can do: add it as a **Security Reviewer** for read-only access, or as an **Owner** for a pipeline that creates or modifies integrations, policies, or settings. The service account's email must be a member of your P0 organization, or P0 rejects the token.
3. **Mint a short-lived identity token** and use it as your bearer token. The audience must be your P0 organization URL, `https://p0.app/o/<your-org>`, and the token must include a verified email:

   ```bash
   export P0_API_TOKEN="$(gcloud auth print-identity-token \
     --impersonate-service-account="p0-ci@my-project.iam.gserviceaccount.com" \
     --audiences="https://p0.app/o/my-org" \
     --include-email)"
   ```
4. **Use the token.** With `P0_API_TOKEN` set, the Terraform provider and any API call authenticate as the service account.

{% hint style="info" %}
The token is short-lived (about one hour), so mint it in the same job that uses it. The audience must match your organization URL exactly, and the token must carry a verified email (`--include-email`)—without it, the minted token omits the email claim and P0 rejects it.
{% endhint %}

## P0 CLI token

For local development, authenticate with your own P0 login through the [P0 CLI](/getting-started/getting-started-with-the-p0-cli.md).

1. Log in to your organization:

   ```bash
   p0 login <your-org>
   ```

   The CLI completes a browser single sign-on flow and stores your session in `~/.p0/identity.json`.
2. Use the session:
   * **With the Terraform provider** — you don't need a token. When `api_token` and `P0_API_TOKEN` are both unset, the provider automatically uses your CLI session.
   * **With the API** — print a bearer token from your session and pass it in the `Authorization` header:

     ```bash
     curl -H "Authorization: Bearer $(p0 print-bearer-token)" \
       https://api.p0.app/o/<your-org>/...
     ```

These tokens are short-lived and tied to your login, so use them for local development rather than durable automation. The token acts as you, with your P0 role.

## API key (legacy)

{% hint style="warning" %}
API keys are legacy and are being phased out in favor of [Google Cloud service-account tokens](#google-cloud-service-account-token-recommended). They still work, but prefer a service-account token for new integrations. A P0 API key carries the full **Owner** role and cannot be scoped to a lesser role.
{% endhint %}

An API key is a long-lived secret you generate in the P0 dashboard. To create one, see [Generating an API key](/p0-management/generating-an-api-key.md). Use it as your bearer token or export it as `P0_API_TOKEN`.

## Use your token

The token you obtained works the same way regardless of how you got it.

### With the P0 APIs

Pass the token in the `Authorization` header. The base URL includes your organization identifier:

```bash
curl -H "Authorization: Bearer <token>" \
  https://api.p0.app/o/<your-org>/...
```

### With the Terraform provider

Set the token in the `P0_API_TOKEN` environment variable, or pass it as the provider's `api_token` attribute:

```hcl
provider "p0" {
  org       = "my-org"
  api_token = var.p0_api_token
}
```

The provider resolves the token in this order: the `api_token` attribute, then the `P0_API_TOKEN` environment variable, then your P0 CLI session. Prefer the environment variable or a secrets manager over hardcoding the token in configuration.

## Best practices

* **Prefer short-lived tokens.** A Google Cloud service-account token or a CLI token expires on its own; an API key does not.
* **Grant least privilege.** The token inherits the P0 role of its identity. Use a read-only role such as Security Reviewer where write access is not required.
* **Never commit tokens.** Use an environment variable or a secrets manager, and rotate any long-lived secret regularly.

## Related

* [Generating an API key](/p0-management/generating-an-api-key.md)
* [P0 API overview](/p0-api/p0-api-overview.md)
* [Manage integrations as code with the P0 Terraform provider](/getting-started/get-started-with-the-p0-terraform-provider.md)
