← №5 Account inventory (incl. shared/service accounts)
Account inventory
A worked example: from raw GAM output to a register with named owners
The walkthrough says "export, reconcile, assign owners." This page shows
what that actually looks like, on a fictional 12-person tenant
(example.dev) whose data is shaped like yours will be.
1 — What the user export looks like
gam print users … writes a CSV, one row per account. Opened
in a spreadsheet it looks like this:
primaryEmail name.fullName suspended isAdmin lastLoginTime creationTime orgUnitPath
maya@example.dev Maya Lindqvist False True 2026-07-23T08:14:02Z 2021-03-01T09:00:00Z /
jonas@example.dev Jonas Petit False False 2026-07-24T16:41:55Z 2022-11-14T10:22:00Z /Staff
billing@example.dev Billing Inbox False False 2026-07-21T07:03:11Z 2021-03-02T12:00:00Z /Shared
svc-backup@example.dev Backup Runner False False Never 2023-06-19T02:10:00Z /Service
k.osei@example.dev Kwame Osei True False 2024-01-30T11:47:23Z 2022-02-07T08:30:00Z /Staff
mailer@example.dev Newsletter Bot False False 2026-07-25T04:00:19Z 2024-09-12T15:45:00Z /Service
Six rows, four different kinds of thing. maya and
jonas are humans. billing@ is a shared mailbox
several people read. svc-backup@ and mailer@
are service accounts driven by software. k.osei@ is
suspended — a leaver. Every one of them can hold data, OAuth grants and
group memberships, which is why every one of them goes in the register:
suspended and robot accounts included.
2 — Groups and memberships
The two group exports are just as plain:
email name adminCreated
staff@example.dev All staff True
finance@example.dev Finance True
partners@example.dev Partner liaison False
group member role type
staff@example.dev maya@example.dev OWNER USER
staff@example.dev jonas@example.dev MEMBER USER
finance@example.dev billing@example.dev MEMBER USER
partners@example.dev anna@consultancy.example MEMBER USER
Two things to notice. partners@ was created by a user, not
an admin (adminCreated = False) — nobody decided it should
exist. And its member anna@consultancy.example is
outside the domain. Neither is inventory's problem to
fix — group hygiene is
№34's audit — but the register records that partners@ exists and who
answers for it.
3 — The identities with no user row
Domain-wide delegation clients live on their own console screen (Security → API controls → Manage Domain Wide Delegation) and look like this:
Name Client ID Scopes
Backup vendor 103846752019384756201 https://www.googleapis.com/auth/drive.readonly
(unnamed) 118293003847561029447 https://mail.google.com/ The second row is the interesting one: a client id with full Gmail scope and no name. Nothing in the user export points at it — DWD clients never appear as users, which is exactly why the walkthrough makes you visit this screen. In the register it becomes a row whose owner is "unknown", and an unknown owner on a Gmail-scope grant is a finding you chase this week, not a curiosity.
4 — Reconciliation, row by row
Reconciliation is a join: every exported account either matches a line in a source you already trust, or it doesn't. The trusted sources are the HR/people list for humans, and last cycle's register for everything else. Concretely:
maya@example.dev → on the HR list ✓ human, owner = herself
jonas@example.dev → on the HR list ✓ human, owner = himself
billing@example.dev → in last cycle's register ✓ shared, owner = Maya (finance lead)
svc-backup@example.dev → in last cycle's register ✓ service, owner = Jonas (runs backups)
k.osei@example.dev → HR list says: left 2024-01 ✓ leaver — offboarding per №21
mailer@example.dev → NOT on HR list, NOT in register ✗ UNEXPLAINED → investigate
Five rows explain themselves in seconds. The sixth is the entire point
of the exercise: mailer@ appeared between cycles, nobody
recorded it, and "Newsletter Bot" is precisely the kind of plausible
name an attacker gives a persistence account. Investigating usually
takes one message — "who set up mailer@?" in the team channel — and ends
in one of two ways: someone says "that's mine, for the October
campaign" (record them as owner, done), or nobody claims it within a
day and you treat it as an incident: suspend, pull its audit log,
check its OAuth grants and filters.
5 — What "named owner" means
An owner is one human, by name, who can answer "what is this account for and can we turn it off?" Not a team, not a distribution list — a person (with a deputy if you like, but one name is accountable). For human accounts the owner is the human. For shared and service accounts, ownership is established the unglamorous way: you ask. Once. In writing. "You run the backups — are you the owner of svc-backup@?" The answer goes in the register, and from then on the monthly diff only ever asks about new rows, so the asking never repeats for settled accounts.
The register is also what makes the question cheap next year, when Maya
has left: filter the register on owner = maya and you have
the exact list of accounts needing a new owner — part of №21's
offboarding.
6 — The register template
One sheet, one row per account, these columns. Paste the block below
into a file and import it into Google Sheets (File → Import), or keep
it as CSV next to the exports — the format matters less than the
owner column never being empty.
email,kind,owner,purpose,created,status,reviewed,notes
maya@example.dev,human,maya,Founder / admin,2021-03-01,active,2026-07-26,
jonas@example.dev,human,jonas,Engineering,2022-11-14,active,2026-07-26,
billing@example.dev,shared,maya,Invoices in/out,2021-03-02,active,2026-07-26,3 readers via finance@
svc-backup@example.dev,service,jonas,Nightly Drive backup,2023-06-19,active,2026-07-26,DWD client 1038…6201
k.osei@example.dev,human,maya,Left 2024-01,2022-02-07,suspended,2026-07-26,data transfer pending (№21)
mailer@example.dev,service,UNKNOWN,under investigation,2024-09-12,active,2026-07-26,unclaimed — treating per §4
partners@example.dev,group,maya,Partner liaison list,—,active,2026-07-26,external member; audited by №34
118293…9447,dwd-client,UNKNOWN,Gmail scope grant,—,active,2026-07-26,unnamed client — finding kind is one of human / shared / service / group /
dwd-client; reviewed is the date a human last
confirmed the row, which is what the monthly maintenance diff updates.
The two UNKNOWN rows are not failures of the register —
they are the register working.