5 Account inventory (incl. shared/service accounts)
A dated register of every account — human, shared and service — each with a named owner. It is built by exporting users, groups and group memberships with GAM (the command-line Workspace admin tool), then reconciling that against the human register and cross-checking the identities that never appear as ordinary users: GCP service accounts and domain-wide delegation clients. The point of the register is that it makes an unowned account a finding rather than a curiosity, so an orphaned or attacker-created identity has nowhere to hide.
Caveats
Setup steps
-
gam print users fields primaryEmail,name,suspended,isAdmin,isDelegatedAdmin,lastLoginTime,creationTime,orgUnitPath > users-$(date +%F).csvDownload a list of users ↗ REST Resource: users | Admin SDK Directory API ↗
-
gam print groups fields email,name,description,adminCreated > groups-$(date +%F).csv && gam print group-members > group-members-$(date +%F).csv - open ↗

https://admin.google.com/ac/owl/domainwidedelegation · captured 2026-07-15
Security › Access and data control › API controls › Manage Domain Wide DelegationCross-check GCP service accounts and Security > Access and data control > API controls > Manage Domain Wide Delegation against the register
Control API access with domain-wide delegation ↗ List and edit service accounts ↗
- open ↗

https://admin.google.com/ac/users · captured 2026-07-15
Directory › UsersDiff = zero unexplained accounts; every account has a named owner and a purpose - open ↗

https://admin.google.com/ac/groups · captured 2026-07-15
Directory › GroupsOwner set; external members reviewed
Ongoing maintenance
- automatable: script Monthly: re-export users/groups/delegation clients and diff against the register.
- requires a human Monthly: triage every unowned or unexplained account the diff surfaces.
How to verify
Check the newest inventory snapshot is no older than the cycle, then re-run the export and diff — an inventory is only as good as its date.
gam print users fields primaryEmail,suspended,lastLoginTime > users-check.csv && diff <(sort users-check.csv) <(sort users-<last-date>.csv)
v0.0.3Assure policy #10 · #28 ↗