GCP IAM Policy Analyzer

Read a Google Cloud IAM allow policy: which bindings are public, which roles are the enormous basic ones, and which grant impersonation and therefore reach further than they appear to.

Paste below, or drop a file anywhere on this panel

Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.

The answer appears here

Paste on the left and press Analyze the policy. Nothing leaves this tab.

Wanted a different tool?

Examples

Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.

Public, wearing an internal-sounding name

allAuthenticatedUsers is any Google account in existence, not everyone in your organisation. Bound to a storage role it is a data exposure.

{
  "version": 3,
  "bindings": [
    { "role": "roles/storage.objectViewer", "members": ["allAuthenticatedUsers"] }
  ],
  "etag": "BwXhtQ=="
}

roles/editor as a default

A basic role covering thousands of permissions, including creating service accounts and their keys, which reaches anything any service account in the project can reach.

{
  "version": 1,
  "bindings": [
    { "role": "roles/editor", "members": ["user:alice@example.com", "group:devs@example.com"] }
  ],
  "etag": "BwXhtQ=="
}

Impersonation at the project level

Token creator on the whole project mints tokens for every service account in it, so the holder's effective access is whatever the most privileged of those has.

{
  "version": 1,
  "bindings": [
    { "role": "roles/iam.serviceAccountTokenCreator", "members": ["group:platform@example.com"] }
  ],
  "etag": "BwXhtQ=="
}

A member with no type prefix

Every member is type:identifier. A bare email is rejected by the API, and the error rarely points at which binding.

{
  "version": 1,
  "bindings": [
    { "role": "roles/storage.objectViewer", "members": ["someone@example.com"] }
  ],
  "etag": "BwXhtQ=="
}

Common mistakes

These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.

  1. Reading `allAuthenticatedUsers` as everyone in your organisation

    It is any Google account in existence, including one created seconds ago. It is public access that merely requires a Google login.

    Instead:Use `domain:yourdomain.com` or a group. `allAuthenticatedUsers` is almost never what was meant.

  2. Auditing a resource's own IAM policy and calling it done

    Bindings at the organisation, folder and project level are inherited and cannot be revoked lower down, so the resource's policy shows what was granted there rather than who can reach it.

    Instead:Use Policy Troubleshooter for effective access. Deny policies are the only mechanism that subtracts, and they are configured separately.

  3. Granting `roles/editor` as a convenient default

    It covers thousands of permissions and can create service accounts and their keys, so it reaches anything any service account in the project can reach.

    Instead:Predefined roles. Policy Analyzer shows which permissions were actually used in the last 90 days, which is the practical way to narrow it.

  4. Granting `roles/iam.serviceAccountTokenCreator` at the project level

    It mints tokens for every service account in the project, so the holder's effective access is whatever the most privileged of those accounts has.

    Instead:Grant it on the one specific service account that is meant to be impersonated.

  5. Writing a member as a bare email address

    Every member is `type:identifier`. A bare address is rejected, and `serviceaccount` in lower case is not a member type: the capital A matters.

    Instead:`user:`, `serviceAccount:`, `group:` or `domain:`, spelled exactly.

allAuthenticatedUsers is not your organisation

It is any Google account in existence, including one created a moment ago. It reads like an internal audience and it is public access with an extra step, which is why it survives review so often.

Inheritance is additive and a child cannot revoke it

A binding at the organisation, folder or project level applies to every resource beneath it, and setting a policy on the resource does not remove it. So auditing a bucket's own policy tells you who was granted access HERE, not who can reach it. Deny policies are the only mechanism that subtracts, they are configured separately from allow policies, and most projects have none.

organisation   roles/viewer to group:everyone@corp.com
  folder
    project
      bucket     policy grants nobody

Everyone in that group can still read the bucket.
The bucket's own policy cannot take it away.

The basic roles are enormous, and roles/editor is an escalation path

Owner, editor and viewer predate predefined roles and cover thousands of permissions, so nobody holding one can tell you what they can do. Editor is the one that matters most: it can create service accounts and their keys, which reaches anything any service account in the project can reach. Google's own guidance is not to use basic roles in production.

Impersonation roles make the rest of the grant a floor

serviceAccountTokenCreator mints tokens for a service account, taking its permissions. serviceAccountUser attaches an account to a new resource and runs code as it. Either one means the effective access is whatever the target identity has, so a carefully minimal set of other roles is not the ceiling it looks like. Grant these on a specific service account rather than at the project level.

Member syntax is exact, and serviceAccount has a capital A

Every member is type:identifier. A bare email address is not a valid member. serviceaccount in lower case is not a member type and the policy is rejected. A deleted: member keeps the original unique id, grants nothing while the principal is gone, and becomes live again if a service account is undeleted.

A condition can quietly expire

A conditional binding grants the role only while its CEL expression is true. That narrows a role usefully, and it also means a binding with a timestamp in the past grants nothing while looking entirely active in the policy document.

What this cannot see

It reads one allow policy. Everything inherited from above is absent from that document by definition, and inherited bindings are the ones you cannot revoke here, so this cannot answer who can reach a resource. It does not evaluate conditions, expand a predefined role into its permissions, or know about deny policies. For effective access use Policy Troubleshooter, and for which permissions are actually being used use Policy Analyzer, which is the practical route from a basic role to a narrow one.