Get started

OpenSourceOM Team ·

GCP Principal Access Boundaries Explained

Principal Access Boundary policies cap which resources a principal can touch: PAB vs IAM deny vs org policy, a contractor example, and how to test before binding.

  • GCP
  • Principal Access Boundary
  • IAM
  • CIEM
  • workforce identity

A principal with roles/editor on a folder can still be over-scoped if that folder was the wrong one. Principal Access Boundary (PAB) policies answer a different question than roles: regardless of what IAM grants, which resource names is this principal allowed to see at all?

PAB does not replace removing wide roles. It is a ceiling you put on people and pools you do not fully trust—contractors, acquired-company IdPs, break-glass that should only open one folder. General IAM mechanics remain in GCP IAM security hardening. Docs: principal access boundary.

Ceiling on principals

Think of three layers:

Allow bindings     →  what APIs you may call, on which resources they name
Deny policies      →  APIs you may not call even if allowed
PAB                →  resource names you may never be authorized on

If PAB’s resource list is folders/SANDBOX (and descendants), then resourcemanager.projects.get on folders/PROD fails for that principal even when an allow binding says Editor at org. The org IAM page will still look frightening; the live token cannot use it.

gcloud iam principal-access-boundary-policies list --organization="${ORG_ID}"

gcloud iam principal-access-boundary-policies describe "${PAB_ID}" \
  --organization="${ORG_ID}"

Bindings attach the policy to principals (users, groups, workforce principal sets, some service accounts—confirm current supported types in the doc for your org). A PAB that exists but is not bound does nothing.

Failure mode: PAB lists the sandbox project but contractors need the Shared VPC host project to attach a NIC. Every GCE insert fails. The ceiling must include every resource the job honestly needs, or the job will demand org-wide Editor again.

Failure mode: you bound PAB to user:ada@vendor.com and the vendor signs in as a workforce subject principal://iam.googleapis.com/.../subject/ada. Different principal strings; PAB never applied.

PAB vs IAM deny vs org policy

Control Stops Does not stop
IAM allow (roles) Nothing by itself; it grants Over-grant if you bind at the wrong folder
IAM deny Listed permissions (key create, setIamPolicy) Access to resources using other permissions
PAB Access outside the resource boundary A permission that is in-boundary (Editor inside sandbox is still Editor)
Org policy (managed or custom) Resource configuration (no public IPs, no keys) Who the principal is

Use org policy so sandbox cannot create public IPs. Use deny so nobody creates SA keys. Use PAB so the contractor principal set cannot leave folders/contractors. Use allow so they can actually deploy in that folder.

PAB is a poor substitute for CIEM reviews: a contractor with Editor inside a folder that contains a production replica is still a production admin. Boundary first, then least privilege inside it.

Example for contractors

Goal: workforce-federated vendor engineers can administer folders/vendors-acme only.

# pab-acme.yaml (illustrative fields — match current API schema)
displayName: acme-vendor-ceiling
details:
  rules:
    - description: Acme may only touch the vendor folder
      resources:
        - "//cloudresourcemanager.googleapis.com/folders/${ACME_FOLDER_ID}"
gcloud iam principal-access-boundary-policies create acme-vendor-ceiling \
  --organization="${ORG_ID}" \
  --policy-file=pab-acme.yaml

gcloud iam principal-access-boundary-policy-bindings create acme-binding \
  --organization="${ORG_ID}" \
  --policy="${PAB_RESOURCE_NAME}" \
  --target-principal="principalSet://iam.googleapis.com/locations/global/workforcePools/${POOL}/group/${ACME_GROUP}"

IAM inside the folder can stay roles/compute.instanceAdmin.v1 + roles/storage.objectAdmin on a named bucket. If someone later adds roles/editor on the org to that same group, PAB should still keep them out of prod folders.

Include in the resource list (or a parent that contains them):

  • The vendor folder
  • Any Artifact Registry / Cloud Build project they must push to, if it lives outside the folder (better: move it in)
  • Not: folders/prod, org, billing accounts they should not see

Failure mode: group claim from the IdP is Acme-Admins and you bound acme-admins. Workforce attribute mapping has to produce the same group string PAB uses. Test with one user before the whole vendor cohort.

Testing

  1. Create a throwaway project under the vendor folder; as the test workforce user, gcloud projects describe it—should work with the intended role.
  2. gcloud projects describe a prod project—should fail with a PAB / authorization error, even if you temporarily bind Editor at org on that user (do this only in a drill, then remove the Editor).
  3. Run Policy Simulator / IAM troubleshooter on a prod resource for that principal; confirm the PAB explanation appears (product UI names vary; if simulator ignores PAB in your release, the live API call is authoritative).
  4. Terraform as the automation SA (not under the contractor PAB) against prod—must keep working. If platform automation was accidentally included in the principal set, you will see it here.
# Who is bound?
gcloud iam principal-access-boundary-policy-bindings list --organization="${ORG_ID}"

Roll out: bind PAB to a pilot group → 48 hours of tickets → expand. Do not bind principalSet://goog/public:all to a PAB that only lists one folder; you will freeze the org.

When PAB and deny disagree with a public workload still reaching BigQuery, that pairing is a toxic combination inside the boundary. PAB did its job; the allow bindings inside the folder did not.

Checklist

  • PAB policy resource list is the intended folder (plus honestly required shared projects), not the org
  • Binding principal string matches how users actually show up (workforce vs Cloud Identity vs SA)
  • Deny policies still cover key creation / setIamPolicy; PAB is not a permission deny
  • Org policies still constrain public IPs and keys inside the sandbox
  • Live deny test: contractor can describe sandbox project, cannot describe prod
  • Automation SAs used by platform Terraform are not under the contractor PAB
  • Exception process documented (who can widen the resource list)

Related: GCP IAM security hardening · CIEM explained