wif.tax

P0 Security

B P0 platform (Management, JIT access and inventory APIs)

P0's API accepts a short-lived Google Cloud service-account identity token in place of a key, but no other issuer; the legacy API key never expires and always carries the full Owner role. Into your clouds, Okta, Entra, Google Workspace, GitHub and Slack it is keyless, while Kubernetes, Cloudflare, Tailscale and the SIEM sinks still want a pasted token or secret.

Docs: docs.p0.dev · Checked 2026-10-13 · source YAML · dispute via PR

Inbound B

How a workload running anywhere authenticates to this product.

A Google-issued service-account OIDC identity token (audience = the P0 org URL, verified email claim, email must be a member of the P0 org with an RBAC role) is accepted directly as the bearer token. The only other machine path is a legacy, non-expiring, Owner-scoped API key.

Issuers
Google Cloud service-account identity tokens (accounts.google.com)

The docs name exactly three token sources: a Google service-account identity token, a P0 CLI token (a human's SSO session, not for automation), and the legacy API key. No configurable OIDC issuer, GitHub Actions, GitLab, AWS or Azure identity is documented, so this is an allowlist of one (Google). A workload outside GCP can still get there by using GCP Workload Identity Federation to impersonate a service account and mint the ID token, but Google remains the only issuer P0 trusts. Trust is constrained by audience (the org URL) and the service account's email, which must be an RBAC member, so the identity gets least-privilege roles such as Security Reviewer. The self-hosted SSH agent registers once with any of these tokens, then generates its own ECDSA key pair under /etc/p0-ssh-agent/keys and authenticates to P0 with JWTs; the docs advise deleting an API key after registration if one was used.

Outbound B

How this product reaches into your cloud, repos, or other SaaS.

AWS via sts:AssumeRoleWithWebIdentity with a Google-signed token into a P0 role; GCP by granting roles to P0's own service account; Azure via an app registration with a federated credential; Okta via an API Services app trusting a P0-generated public key; Entra (legacy), Google Workspace, GitHub and Slack via admin consent / app install. Kubernetes, Cloudflare, Tailscale, Datadog and Splunk integrations take a customer-created token or client secret.

Checked: AWS, GCP, Azure, Okta, Entra ID (new security-perimeter version and legacy), Google Workspace, GitHub (teams), GitHub Repositories, Slack, Kubernetes, SSH, Snowflake, Databricks, Cloudflare, Tailscale, Datadog and Splunk HEC SIEM sinks. Keyless: AWS, GCP, Azure, Okta (P0 generates the key pair and holds the private key; the customer only pastes P0's public key into an Okta API Services app, so no customer secret is handed over), Entra, Google Workspace, GitHub, Slack, Databricks (a connector in the customer's AWS account signs in with AWS outbound web identity federation), and GitHub Repositories (customer-owned GitHub App whose private key stays in the customer's AWS Secrets Manager; P0 says it never reads it). The new Entra perimeter and Snowflake run vendor-generated shell/SQL; neither page asks for a secret, but the generated commands are only visible after login. Static: Kubernetes (a long-lived service-account token from a p0-service-account-secret is pasted into P0, also in the Terraform path), Cloudflare (account API token), Tailscale (OAuth client ID and secret with the "all" scope), Datadog SIEM (API key) and Splunk (HEC token). Every cloud is keyless; B rather than A because Kubernetes and several SaaS connectors take static credentials.

Hygiene for any static credential the product still issues

✗ Expiry enforceable
The create-key request takes only a name; there is no expiry field or org policy.
  • docs.p0.dev checked 2026-10-13
    “A Google Cloud service-account token or a CLI token expires on its own; an API key does not.”
  • docs.p0.dev checked 2026-10-13
    “A legacy API key also works, but carries the full Owner role and doesn't expire on its own.”
✓ Rotation via API
  • docs.p0.dev checked 2026-10-13
    “The API Key Management API lets you create, list, and delete your organization's API keys programmatically. Use these endpoints to automate key provisioning and rotation in your infrastructure-as-code and CI/CD workflows.”
✗ Scoped keys
  • docs.p0.dev checked 2026-10-13
    “A P0 API key carries the full Owner role and cannot be scoped to a lesser role.”
  • docs.p0.dev checked 2026-10-13
    “Every API key is granted the Owner role, so any key can create, list, and delete other API keys. Treat each key as a full administrative credential, and store it securely.”
✗ Last-used visible
The documented ApiKeyMetadata object has only id, created, name and user; no last-used field is documented in the API or the dashboard docs. The delete docs tell you to "confirm the key is unused before you delete it" without saying how. Key creation and deletion are audit-logged.
  • docs.p0.dev checked 2026-10-13
    “Returns metadata for every API key in the organization, ordered by creation time. Never returns key material.”
✗ Leak revocation
P0 Security does not appear anywhere in GitHub's supported-patterns list, partner or otherwise.
  • docs.github.com checked 2026-10-13
    “Partner alerts: Reported directly to secret providers that are part of secret scanning's partner program.”

Notes

Docs are public (docs.p0.dev, with Markdown copies of every page). Inbound would move to A if P0 accepted tokens from a customer-configured OIDC issuer (GitHub Actions, AWS, Azure, any IdP) instead of Google only. The legacy API key fails four of five hygiene checks, but it is optional: a GCP-based or GCP-federated workload never needs one. P0's own outbound auth into AWS is itself federation from a Google identity, which is the pattern it asks customers to use inbound.

Badge

wif.tax grade B

[![wif.tax grade](https://wif.tax/badge/p0-security.svg)](https://wif.tax/p/p0-security/)