Policy Analyzer is the GCP tool that lets you ask "who can do what to which resource?" in plain English.
Let’s see it in action. Imagine you want to know which principals (users, service accounts, groups) have storage.objects.list permission on any bucket in your my-project-id project. You’d use the gcloud asset search-all-iam-policies command.
gcloud asset search-all-iam-policies \
--scope=projects/my-project-id \
--query="policy.bindings.members:group:data-analysts@example.com" \
--flatten="policy.bindings[].members" \
--format="json"
This command searches all IAM policies within my-project-id. The --query flag filters for policies where a specific member (group:data-analysts@example.com) is listed. --flatten helps unnest the members array so we can filter on individual members. The output, in JSON, will show you the resource (projects/my-project-id/buckets/my-bucket-name) and the specific role (roles/storage.objectViewer) that grants the permission.
The core problem Policy Analyzer solves is the inherent complexity of IAM. As your GCP environment grows, understanding who has access to what becomes a massive challenge. IAM policies are hierarchical: permissions granted at a project level cascade down to all resources within that project. Furthermore, policies can be granted directly to resources, via folders, or at the organization level. Policy Analyzer provides a unified way to query this distributed and layered system.
Internally, Policy Analyzer leverages GCP’s Asset Inventory service. Asset Inventory continuously collects metadata about your GCP resources, including their IAM policies. Policy Analyzer then queries this inventory data. When you run a command like the one above, you’re not querying live IAM policies directly; you’re querying a snapshot of the metadata that Asset Inventory has collected. This makes the queries fast and scalable, but it also means there’s a slight delay between a policy change and when it’s reflected in Policy Analyzer’s results.
The key levers you control are the --scope and the --query parameters. The --scope can be a project, a folder, or an organization. The --query uses a powerful expression language that allows you to filter based on resource type, resource name, principal identity, role, and permissions. You can construct queries like:
- "Show me all service accounts that can
compute.instances.starton any VM infolder-id." - "List all users who have the
editorrole on any resource withinorganization-id." - "Find all buckets in
my-project-idwhere theallUsersprincipal has any permission."
The "least privilege" principle is often discussed in the context of IAM, but Policy Analyzer shows its practical application by allowing you to audit and enforce it. You can proactively identify overly permissive roles and then use the gcloud iam roles update or gcloud projects remove-iam-policy-binding commands to tighten access. For instance, if you find a service account with broad storage.admin permissions on a project, you can refine it to only allow storage.objects.create on a specific bucket.
The real power of Policy Analyzer comes when you start combining its capabilities with other GCP services. You can export the results of your IAM queries to BigQuery for more complex analysis and long-term trend monitoring. Imagine building dashboards that track the reduction of overly permissive roles over time, or setting up alerts when new broad permissions are detected. This transforms IAM auditing from a reactive, manual task into a proactive, automated security practice.
When you’re debugging a policy that seems to be granting access when it shouldn’t, remember that IAM policy evaluation is additive. A principal can gain a permission through multiple roles, and if any of those roles grant the permission on the resource in question (or an ancestor), the access is allowed. This means you can’t just look at one policy binding; you need to consider all effective policies from the resource up to the organization.