Skip to content
Ops Log
Decision MemoSecurity & Infrastructure15 September 20267 min read

Google's admin.directory.user.security scope has no read-only form

Google publishes no read-only form of the admin.directory.user.security scope. The scope that lists a user's OAuth tokens and app passwords is the same scope that deletes them, so treat any grant of it as a write permission when reviewing a third-party app.

Cover image for Google's admin.directory.user.security scope has no read-only form
MJ

Google's OAuth scope https://www.googleapis.com/auth/admin.directory.user.security has no read-only counterpart. It covers every operation on a user's application-specific passwords, third-party OAuth tokens and backup verification codes, and the methods that only list those resources require the same scope as the methods that delete or invalidate them. An administrator who wants the reads has nothing narrower to grant.

Last verified: 2026-09-15.

What Google documents

The Directory API scope guide, Choose Directory API scopes, read 2026-09-15, lists this scope alone under its heading for user security features and describes it as "Scope for access to all application-specific password, OAuth token, and verification code operations." The word "all" is Google's. Every other category on the same page, users and user aliases, groups, organizational units, devices and domains among them, carries a second scope limited to retrieving or listing, such as admin.directory.user.readonly, described as "Scope for only retrieving users or user aliases." User security features is the one category with no such second scope.

Google's catalogue of scopes across its APIs, OAuth 2.0 Scopes for Google APIs, read 2026-09-15, gives the same scope a shorter line: "Manage data access permissions for users on your domain." The neighbouring rows for the user scopes read "View and manage the provisioning of users on your domain" and "See info about users on your domain". The security row carries the manage verb and no view form.

The REST reference shows which operations sit behind the scope. Six method pages, each read on 2026-09-15, list https://www.googleapis.com/auth/admin.directory.user.security as the only entry under Authorization scopes:

  • tokens.delete: "Deletes all access tokens issued by a user for an application."
  • tokens.list: "Returns the set of tokens specified user has issued to 3rd party applications."
  • asps.delete: "Deletes an ASP issued by a user."
  • asps.list: "Lists the ASPs issued by a user."
  • verificationCodes.list: "Returns the current set of valid backup verification codes for the specified user."
  • verificationCodes.invalidate: "Invalidates the current backup verification codes for the user."

The three list methods only read. They carry the same requirement as the two delete methods and the invalidate method, so a grant that permits the reads permits the deletions.

Why the name is easy to misread

A permissions review tends to look for a qualifier. The Directory API marks its retrieval-only scopes with a .readonly suffix, as in admin.directory.user.readonly and admin.directory.domain.readonly, and a scope without the suffix that sits beside one with it reads as the fuller half of a pair. This scope has no pair, and the word security suggests inspection. A tool that requests it only to count which third-party apps hold tokens can describe its own use as reading, accurately as a statement about its code, while understating what the administrator granted.

ITSailor's own build made that mistake. The Google connector behind the SaaS Auditor requests this scope to read per-user third-party token grants for Shadow IT discovery. Until a fix merged in the repository on 2026-08-08, the site's connector-permissions page and its Privacy Policy both described the scope as read-only. The annotation recorded what the code did with the scope, and the grant permits more than that.

What granting it without reading it costs

Each of the three write methods acts on a credential. tokens.delete removes every access token a user issued to one application, asps.delete removes one of the user's application-specific passwords, and verificationCodes.invalidate voids the user's current backup verification codes. A tool holding the scope holds those operations too, and so does anyone who compromises that tool or its stored credentials.

A review of the scope string alone cannot separate a tool that calls only the three list methods from one that also calls the other three, because both request the identical scope.

Which action the grant needs

An administrator who finds this scope already granted to a third-party app can start from the scope rather than from the vendor's description of it: assume the app can delete and invalidate, then decide whether its stated purpose needs any of the three resources.

How to check what is actually granted

What a vendor documents and what a domain has granted are separate facts, and the tokens resource answers the second. tokens.list returns Token resources, and the tokens resource reference, read 2026-09-15, defines the two fields that matter here: clientId, "The Client ID of the application the token is issued to", and scopes, "A list of authorization scopes the application is granted." The call itself requires admin.directory.user.security, so the audit runs with the same reach it is auditing.

http
# Read-only GET. Lists the third-party OAuth tokens one user has issued.
# Requires the admin.directory.user.security scope. It changes nothing.
GET https://admin.googleapis.com/admin/directory/v1/users/{userKey}/tokens
Authorization: Bearer {access token}

Compare the scopes array for the client in question against the purpose the app states. A grant wider than the stated use is the same gap this note describes.

Where a read-only form exists and where it does not

ScopeDirectory scope guide, read 2026-09-15OAuth scope catalogue, read 2026-09-15Retrieval-only scope
admin.directory.userGlobal scope for access to all user and user alias operations.View and manage the provisioning of users on your domainadmin.directory.user.readonly
admin.directory.user.aliasScope for access to all user alias operations.View and manage user aliases on your domainadmin.directory.user.alias.readonly
admin.directory.user.securityScope for access to all application-specific password, OAuth token, and verification code operations.Manage data access permissions for users on your domainnone listed

Recommendation

Treat admin.directory.user.security as a write scope in every review, whatever the requesting tool calls it. Before granting it, compare the app's stated purpose with the three resources the scope reaches, and record in writing which of the six documented operations the app says it calls. After the grant, the tokens.list check above shows which scopes the app holds. It cannot show which methods the app calls, so the written record is what a later review compares against.

Trade-offs

Visibility and exposure arrive together here. A domain that wants to know which third-party apps hold tokens for its users has one scope that reaches that read, and it is the scope that also deletes tokens and application-specific passwords and invalidates backup codes. Declining the grant keeps those operations out of the tool's reach and gives up the visibility. Any arrangement that makes these calls on a domain's behalf still has to name admin.directory.user.security, because it is the only scope the six method pages list.

Where it does not apply

The finding covers the three resources behind the six method pages cited above. It does not extend to the rest of the Directory API: the scope guide lists a retrieval-only scope for every other category it covers. It says nothing about Google APIs outside the Directory API.

Limitations

This note reads Google's published scope guide, scope catalogue and REST reference. It made no live call against a Workspace domain, so it makes no claim about response shape beyond the documented fields, about rate limits, or about how administrator roles narrow what these six methods can reach. The pages read say nothing about a future narrower scope, and neither does this note. The internal correction date, 2026-08-08, comes from the repository's commit history rather than from a published page, and a reader outside the practice cannot verify it independently.

The SaaS Auditor's Google Workspace connector is the ITSailor tool that requests this scope, and its connector-permissions page now labels it broader than read.

The same scope seen from the other side, reading a leaver's Google Workspace app grants during offboarding next to the Microsoft Graph equivalent, is the subject of the note on the Google Workspace token scope.

Sources and further reading

Was this field note useful?
Make the decision

Turn the trade-off into a scoped brief.

Share the constraints that differ in your environment. Michal will identify the next check needed before a delivery decision.

Start a scoped brief