Why this matters
Google Cloud IAM is additive. A permission granted at the organization, folder or project level flows down to every resource below it, and nothing subtracts from it. One Editor grant on a folder quietly hands out thousands of permissions on every project inside it. Most teams find a handful of these grants after a year of fast growth, often on a shared service account that three systems depend on.
The damage from a stolen identity is bounded by what that identity can do. Basic roles such as Owner, Editor and Viewer were built for convenience, not for production. Editor alone covers most write actions across Compute, Storage and Pub/Sub. A leaked service account key with Editor can delete buckets, rewrite firewall rules and start up miners before anyone reads the alert.
Least privilege in Google Cloud is not about removing all access. It is about replacing broad grants with the smallest predefined or custom role, scoped to the resource that needs it, with a condition on time or request attributes where that helps. Do it in small steps and you keep systems running while the blast radius shrinks.
Before you start
Get read access first. You need roles/iam.securityReviewer on the organization or the projects you care about, plus roles/cloudasset.viewer if you plan to use Cloud Asset Inventory to search policies across many projects. To read role recommendations you need roles/recommender.iamViewer. Ask for those instead of Owner.
Decide who owns the outcome. Pick one person who can say yes to a permission change and one engineer who runs the commands. Least privilege work stalls when it is nobody's job, or when every grant needs a meeting.
Run a quick baseline. List every principal with Owner or Editor at the organization, folder and project levels. List every service account with a user-managed key. List every service account that has not authenticated in 90 days. That gives you the first work items and a rough sense of scale.
Pick a pilot project. A dev or staging project with real traffic but low stakes is a good place to learn what breaks. Do not start with the billing export or the shared VPC host project.
How to do it
Work top down to understand the problem, then fix one project at a time. Google Cloud gives you tools to do this without guessing: IAM Recommender watches actual usage and suggests narrower roles, Policy Analyzer answers questions about who can do what, and Policy Troubleshooter explains why a principal got or did not get access.
Save the old policy before each change. Run gcloud projects get-iam-policy and write the JSON to a file, or use the export in the console. You can restore it in seconds if a deployment fails. Do the same for folder and organization policies.
Treat service accounts as production code. They are identities with credentials, and they are a common path for lateral movement in Google Cloud. Give each workload its own service account. Grant roles to the service account, not to the people who deploy it. Where you can, use Workload Identity Federation or attached service accounts instead of exported keys.
- Export every IAM policy you have. Pull the organization, folder and project policies with gcloud asset or the console export. Store the JSON files in version control so you can diff and roll back.
- Find the basic role grants. Search the exported policies for roles/owner, roles/editor and roles/viewer. Note which principal holds each one and at what level in the resource hierarchy.
- Pull role recommendations. Open IAM Recommender for each project and review the suggested replacements. Look at the usage window and the sample permissions before you accept anything.
- Replace basic roles with predefined roles. Grant the narrowest predefined role that covers the workload, then remove the broad binding in the same change. Test the workload right after the change, not a week later.
- Add IAM Conditions for time and resource scope. Use a condition when access is temporary or tied to a specific resource name. Set an expiry date on break-glass and contractor access so it disappears without a ticket.
- Give every workload its own service account. Create one service account per application or job, and grant roles to that account only. Remove roles/iam.serviceAccountUser from people who do not deploy.
- Retire service account keys. List keys with gcloud iam service-accounts keys list, then move workloads to Workload Identity Federation or attached service accounts. Disable a key before you delete it so you can catch stragglers.
- Add a deny policy for hard limits. Use a deny policy to block actions no principal should ever take, such as disabling audit logs or deleting a production bucket. Deny policies override allow bindings, so test them in a sandbox project first.
- Set a review cadence. Schedule a monthly check of new Owner and Editor grants, open recommendations and unused service accounts. Assign each finding an owner and a due date.
How to check it worked
Use Policy Analyzer to ask the question directly. Query by permission, principal or resource. A query like who can delete this bucket should return a short list, and every name on it should be explainable. Run the same check for roles/iam.serviceAccountTokenCreator, roles/iam.serviceAccountUser, roles/editor and roles/owner.
Check that IAM Recommender recommendations moved from active to applied or accepted. Each recommendation shows the current role, the suggested role and the usage it was based on. A recommendation that stays open for weeks usually means nobody owns it.
Read the audit logs. Cloud Audit Logs Admin Activity entries show every policy change, including who made it and the old and new bindings. Set a log-based alert on SetIamPolicy events outside your change window. That one alert catches most accidental broad grants.
Test a denial. Pick a principal you have narrowed and have them try an action they used to have. The error should be a clear permission denied, and Policy Troubleshooter should tell you which binding is missing. If the action still works, something upstream is still granting it.
Mistakes to avoid
Leaving Editor on a folder because a pipeline needs it. Fix the pipeline instead. Find the exact API calls it makes, grant the matching predefined roles on the specific project or resource, and add a condition if the job only runs at night.
Custom roles are a trap when used too early. They are hard to maintain as Google adds new permissions, and a custom role built from an old permission list can quietly block a new feature. Prefer predefined roles first. Build a custom role only when no predefined role fits and you can name the exact permissions you need.
Ignoring inherited grants. A principal with no project-level binding can still have access through a folder or organization binding. Policy Analyzer and the inherited policy view in the console show the full chain. Clear the top-level grant first or you will chase your tail at the project level.
Treating it as a one-time cleanup. New services, new hires and new integrations add grants every week. Put a monthly review on the calendar, turn on Recommender, and require a ticket and an expiry for any new Editor grant. If you want an outside read before you start, the Cloud security review from Cloudverg is a fixed price $6,500 package that runs 2 to 3 weeks and includes an identity and access review with unused and over-broad permissions. It is one option among others, and it is read-only.
Frequently asked questions
What is least privilege in Google Cloud?
It means each identity gets only the permissions it needs for the task, on the resource it needs them for, for as long as it needs them. In Google Cloud that usually means predefined roles on a specific project or resource, plus conditions for temporary access. Basic roles such as Editor are avoided for production workloads.
Do I have to remove every basic role?
No. Keep Owner and Editor for a small break-glass group and for the organization admin accounts you truly need. Remove them from service accounts, pipelines and day-to-day user accounts. The goal is a short, explainable list, not zero.
Can IAM Conditions break my application?
Yes, if the condition is wrong or the workload depends on access outside the allowed window. Test conditions in a staging project and watch the audit logs for permission denied errors. Keep the previous policy saved so you can roll back fast.