IAM bindings granted to personal @gmail.com accounts
What does ZopNight detect here?
IAM bindings granted to @gmail.com addresses sit outside the organization's identity lifecycle: no central offboarding, no enforced MFA, no domain-filtered audits. ZopNight's RC-133 fires when the discoverer's project-policy scan records gmail_user_access=true, and stays silent when the scan is incomplete rather than guessing either way.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-133 |
| Category | compliance |
| Severity | medium |
| Metric | none — pure configuration read |
| Source | iam_gmail_access.go |
A consumer account inside a corporate project
Every user:someone@gmail.com member in a project IAM policy is an identity your
organization does not control. Your identity provider cannot disable it, your MFA policy
does not apply to it, and its password hygiene is whatever the individual chose. The
common origin stories are benign: a contractor onboarded in a hurry, a founder’s personal
account from before Workspace existed, a vendor given “temporary” access for a migration.
But the governance consequence is identical: the account survives offboarding. When the
contractor’s engagement ends, HR-driven deprovisioning removes their corporate account and
misses the Gmail one entirely. The access persists silently until someone audits the
policy, which is exactly the audit this rule automates.
What an auditor or attacker does with it
For an auditor, a Gmail grant is an instant finding: access reviews built on the corporate directory cannot even see the account, so attestations of “all access reviewed quarterly” become false. For an attacker, a personal account is the softest target in the policy. Credential-stuffing and personal-device compromise are far likelier against an account with no enforced 2-step verification and no conditional-access policy in front of it.
Sweep the policy yourself
gcloud projects get-iam-policy PROJECT_ID \ --flatten="bindings[].members" \ --filter="bindings.members ~ @gmail.com" \ --format="table(bindings.members, bindings.role)"Replace each hit with the person’s organization-domain identity at the same role, then
delete the Gmail binding. To close the class permanently, configure the org policy
constraints/iam.allowedPolicyMemberDomains so only your Workspace / Cloud Identity
customer IDs can appear in future bindings.
Absent means unknown, not clean
The discoverer’s IAM listing scans the project policy and writes
gmail_user_access=true or false onto the project resource, and deliberately writes
nothing when the scan did not complete. The rule fires only on the explicit true; an absent
key is treated as unknown and produces no finding, so a partially discovered project is
never certified clean by omission. The wildcard resource-type registration narrows naturally
to the project row, since only it carries the key. The whole detection is a read of the
project policy; there is no automated unbinding, because removing a person’s access is a
decision with an owner, and the finding closes on a later discovery cycle once the policy
no longer contains @gmail.com members.