Say a 10-person marketing agency has one Google Cloud project. Two people set it up, one left in March, and everyone who ever had to deploy in a hurry got added as Owner, because the site was down and that was the fastest box to tick. There are four service accounts, three with a JSON key file somewhere, and one of those files is in a chat thread from last year.
Nothing in that story is careless. It is what happens when a team grows and nobody owns access as a job. The risk is not someone going rogue, it is that one borrowed laptop, one leaked key file or one contractor account nobody closed reaches everything, because everything was granted in one move. Below is the audit we run on a small Google Cloud estate, and the roles we actually grant when we are done. Every claim comes from Google's IAM documentation, checked 13 October 2026.
Why the basic roles are the whole problem
Google Cloud has three basic roles: Owner (roles/owner), Editor (roles/editor) and Viewer (roles/viewer). They predate IAM, and they are coarse by design. Google's guidance on using IAM securely states that basic roles include thousands of permissions across all services, and that production environments should avoid them unless there is no alternative. The recommended replacement is the most limited predefined role that meets the need, or a custom role when no predefined role fits.
Editor is the one that slips through, handed out as "not Owner, so it is fine". It belongs to the same family Google tells you to keep out of production, and in a 10-person company it usually means every engineer can change every resource in the project.
We reach for predefined roles before custom ones. Google's note on choosing a role type is the reason: custom roles are not maintained by Google, so they do not pick up new permissions automatically when a service adds a feature. A custom role you wrote in 2024 can quietly stop covering what it was written for.
The audit we run first
Before changing anything, we write down what is actually granted. Six questions, in this order:
- Who holds a basic role, and at which level. A grant at the organization or folder level is inherited by everything beneath it, so an Owner at the top is an Owner in every project, including ones created next year.
- Which of those principals are service accounts. A service account with Editor is the same blast radius as a person with Editor, minus anyone to notice it is wrong.
- Which service accounts have user-managed keys, and how old. Each key is a credential living outside Google Cloud that never expires on its own.
- Which principals are not using what they hold. Google's role recommender compares a principal's total number of permissions against the permissions that principal actually used in the last 90 days, and suggests removing or replacing the excess.
- Whether one project can reach another. Some recommendations carry lateral movement insights, which identify roles that let a service account in one project impersonate one in a different project. In a small estate, that is usually how staging ended up able to touch production.
- Whether access goes to groups or to individual addresses. If it is addresses, offboarding is manual, which means partial.
The recommendations are readable from the console or the CLI:
gcloud recommender recommendations list
Four Owners and three key files is a normal result on a small estate, not an unusual one.
Replacing Owner with roles that fit the job
We never start by removing a grant. Add the replacement role, confirm the person can still do their work, then remove the basic role. Taking Owner from the only person who knows how to roll back a deploy, at 4pm on a Friday, teaches the team that least privilege is something done to them.
Google's secure-use guidance points at two tools that make this safe. Role recommendations suggest the narrower role to grant in place of the broad one. Policy Simulator shows whether a proposed change would affect a principal's existing access before you apply it. We run both, then grant per job function rather than per person: whoever deploys gets deploy permissions on that service, whoever reads the warehouse gets read on those datasets, and the two are not one grant even when they are the same human.
We keep exactly one break-glass identity with Owner. It belongs to the business, not to a contractor and not to us, its credentials live in the owner's password manager, and the team knows it exists and when to use it. A written emergency path is what stops the next outage from re-granting Owner to four people.
Service account keys, and what we use instead
This is where most of the real risk sits in a small company. Google's best practices for managing service account keys put it plainly: to bad actors, a service account key can be even more valuable than a leaked password. The secure-use guidance says to avoid keys if another option is available, and that if you authenticate with one, the security of the private key is on you.
For almost everything a 10-person company runs, another option is available:
- Code running on Google Cloud uses the service account attached to the resource it runs on. A Cloud Run service, a Compute Engine VM or a Cloud Function authenticates as its own identity, with no key file anywhere. For an internal app this is the default you want, not an upgrade: we cover the settings around it in our note on running a small team's internal app on Cloud Run.
- Code running outside Google Cloud uses Workload Identity Federation. Credentials from your external identity provider are exchanged for short-lived tokens that let the workload impersonate a service account, which is what removes the need for a key in the first place. A CI pipeline on another provider is the common case.
- People who need a service account's access impersonate it. Google's documentation describes short-lived credentials as having a lifetime of a few hours or shorter, not automatically refreshed, and as carrying less risk than long-lived credentials such as service account keys. The role that allows minting them is Service Account Token Creator, granted on the target service account, and it is also what the gcloud impersonation flag requires.
roles/iam.serviceAccountTokenCreator granted on the TARGET service account
gcloud ... --impersonate-service-account=TARGET_SA_EMAIL
Note where that role goes: on the service account being impersonated, not on the project. The token that comes back has no refresh token, so the caller repeats the impersonation when it expires. That expiry is the feature. A key file has none, which is why it still works for whoever found it.
A few older tools genuinely still need a key. Then it gets a named owner, a rotation date, a home in a secrets manager, and the narrowest role we can find on the service account behind it. One documented exception is a decision; three undocumented key files are a problem waiting for a date.
Mapping Workspace groups to Cloud access
If you already run Google Workspace, the group list in your Admin console is the cleanest access control you own, and most small teams never wire it to Google Cloud. Google's best practices for using Google groups describe exactly that: groups managing access to Google Cloud resources through IAM, with distinct group types for organizational structure, collaboration, access and policy enforcement, and a naming convention so a group's purpose shows in its name. Access groups take an access.JOB_FUNCTION shape.
access.cloudrun-deployers@example.com
access.bigquery-readers@example.com
access.billing-viewers@example.com
Roles get granted to those groups and to nothing else. After that, access changes are membership changes: a new hire joins two groups on their first day and loses them on their last, with no IAM policy edited. It also makes the access list readable by a non-engineer, which matters when the person approving it owns the business. Our note on Google Groups permissions and access control covers configuring the groups themselves.
One honest caveat from the same Google page: when groups are synchronised from an external identity provider, there can be a delay between a change in that provider and its arrival in Cloud Identity. So group removal is not an offboarding plan on its own. Suspend the account as well, which is the first step in our Google Workspace offboarding checklist.
What we turn on so it does not drift back
Tightening access once is housekeeping. Keeping it tight is policy. Two organization policy constraints do most of that work:
iam.managed.disableServiceAccountKeyCreation
iam.managed.disableServiceAccountKeyUpload
The first disables creation of new external service account keys for every service account under a project, folder or organization. The second blocks uploading external public keys to service accounts. Google lists both among the security baseline constraints that are enforced automatically when a new organization resource is created, so if your organization is recent, check before you assume you need to add them.
Order matters here too. Google's guidance is to provide alternatives to creating service account keys before restricting them, and to allow exceptions only for projects that can show they cannot use a safer method. Enforce the constraint on a team with nowhere else to go and you get an exception request that never closes, or a key created in someone's personal project.
What to watch in the first 90 days
Expect a quiet period. The recommender's observation window runs to a maximum of 90 days, and by default it waits 90 days before producing role recommendations, although project-level recommendations can be set to a 30 or 60 day window. A project you tightened last week has little to say yet, so put a date in the calendar rather than waiting to be reminded.
Check three things on that date. Did a basic role come back, and in response to what. Did a new key appear. Did the role recommendations go quiet, which is the signal that grants and usage have converged. If someone re-granted Owner to get through an incident, the narrow role was missing a permission: find it and add that instead.
How Guanacos Tech helps
We do this as a fixed piece of work: inventory the grants, the service accounts and the keys, propose replacement roles job function by job function, wire your Workspace groups to Cloud access, and hand over an access list the owner of the business can read without a translator. The break-glass path gets written down too, because an access review only we understand has improved nothing.
If you want the access on your Google Cloud projects to match who actually works at your company, that is Google Cloud consulting for small teams. Book a 30-minute call and we will name the basic-role grants and key files we would remove first, and in what order.
Sources
- Google Cloud: Use IAM securely
- Google Cloud: choose the right role type
- Google Cloud: best practices for managing service account keys
- Google Cloud: service account impersonation
- Google Cloud: best practices for using Google groups
- Google Cloud: restrict IAM service account usage (organization policy)
- Google Cloud: overview of role recommendations