All access tokens aren't created equal
Whenever we want to call a Google or Google Cloud API, we need an access token. But there’s more than one way to obtain an access token, and depending on which way we use, the resulting access token might behave a little differently. What kinds of access tokens are there, and how do they differ?
Whenever we encounter a new kind of token, or want to learn more about a specific type of token, it’s helpful to look at four properties:
- Format: Is the token opaque, or can we (as the user or client) decode and inspect the token?
- Binding: Is the token bound to a particular communication channel or secondary credential, or is it a bearer token that can be forwarded freely?
- Lifetime: Is it a long-lived or a short-lived token? Short-lived tokens tend to have a lifetime that’s measured in minutes or (a small number of) hours, while long-lived tokens can remain valid for days, months, or even years.
- Revocability: Can a token, once issued, be revoked? Or do we have to wait for it to expire?
What’s common among all Google-issued access tokens is the following:
- Format: Access tokens are opaque, and they typically have a
ya29.
prefix (although that might change in the future). Beyond that, there’s not much more to be learned from looking at an access token. Binding: Access tokens are bearer tokens and they’re forwardable: For example, a client application (such as a mobile app) might pass an access token to a server-side application, and that application forwards it to the Google API.
Irrespective of token binding, the receiving API might take additional context information into account when making an access decision. For example, it might check if the token was obtained from a known device and whether the user and their device satisfy a certain access level. Or, if the accessed resource belongs to a VPC-SC perimeter, the API might check which network the call originated from.
Knowing OAuth 2, we can also expect that access tokens are short-lived. But how short-lived? And what about revocability? Here, we begin to see differences.
User access tokens
A user access token is the kind of access token we get when we perform an OAuth authorization code flow or let a user authenticate using OpenID Connect. A user access token identifies a consumer user account or a managed user account, but never a service account.
For user access tokens, the following applies:
- Lifetime: User access tokens are always valid for 1 hour, which makes them short-lived.
Revocability: User access tokens can be revoked: Users can revoke their own access token by removing third-party account access for the respective OAuth client. Admins can revoke other user’s access tokens by using the
tokens.delete
API, or by suspending the user in Cloud Identity or Workspace.Once revoked, an access token typically stops working within a few seconds (but YMMV).
Despite their opaqueness, we can introspect user access tokens by using the tokeninfo endpoint. The endpoint checks if the token is valid, and if it is, returns some (not particularly verbose) diagnostic information about it. For example:
{
"issued_to": "14763833….apps.googleusercontent.com", <-- Client ID
"audience": "14763833….apps.googleusercontent.com", <-- Client ID
"scope": "https://www.googleapis.com/auth/tasks",
"expires_in": 3554,
"access_type": "offline"
}
Service account access tokens
A service account access token is the kind of access token we get when we:
- Deploy an application on Google Cloud and attach a service account to the underlying compute resource.
- Authenticate using a service account key.
- Impersonate a service account by using
projects.serviceAccounts.generateAccessToken
API, or a higher-level construct such as gcloud’s--impersonate-service-account
flag.
Service account access tokens typically have a ya29.c.
prefix, and for them, the following applies:
- Lifetime: By default, service account access tokens are valid for one hour. But if we use
generateAccessToken
to impersonate a service account, we can choose a shorter lifetime such as 5 minutes. We can also extend the token lifetime to up to 12 hours if we set an organizational policy constraint. - Revocability: The only way to revoke a service account access token is to disable the service account, and to leave it disabled until all its access tokens have expired.
Again, we can use the tokeninfo endpoint to introspect the (otherwise opaque) service account access token, but the result looks slightly different:
{
"issued_to": "11694136711…", <-- Service account ID
"audience": "11694136711…", <-- Service account ID
"scope": "https://www.googleapis.com/auth/cloud-platform",
"expires_in": 3590,
"access_type": "online"
}
Domain-wide delegation access tokens
A domain-wide delegation access token is the kind of access token we get when we let a service account impersonate a user account.
Domain-wide delegation access tokens behave similarly to user access tokens:
- Lifetime: They’re valid for 1 hour.
- Revocability: If we suspend the impersonated user account in Cloud Identity/Workspace, that user’s access tokens are revoked.
Domain-wide delegation access tokens use the same prefix as user access token – which isn’t totally surprising given that they also identify a user. But when we introspect a domain-wide delegation access token using the tokeninfo endpoint, the result looks more like a service account access token:
{
"issued_to": "11694136711…", <-- Service account ID
"audience": "11694136711…", <-- Service account ID
"scope": "https://www.googleapis.com/auth/admin.directory.user.readonly", <-- DWD scope
"expires_in": 3599,
"access_type": "offline"
}
STS tokens
An STS token (sometimes also called federation token or identity pool token) is the kind of access token we get when we use workload identity federation or workforce identity federation. They’re always the result of a token exchange, where the input token is either an (externally-issued) SAML assertion or an OIDC token.
STS tokens typically have a ya29.d.
prefix, and for them, the following applies:
Lifetime: In the case of workforce identity federation, an STS token’s lifetime is determined by the pool’s
sessionDuration
setting and can be between 15 minutes and 12 hours.In the case of workload identity federation, an STS token’s lifetime is determined by the
exp
claim (OIDC) or theSessionNotOnOrAfter
attribute (SAML) of the input token, but limited to 1 hour.Revocability: STS tokens aren’t revocable. They remain valid until they expire.
There’s currently no way to introspect an STS token: The normal tokeninfo endpoint doesn’t
support STS tokens, and while the STS API includes a new
introspect
API, it’s currently not supported for third-party use.
STS tokens are still relatively new and not all APIs support them yet. It’s therefore common to use an STS token to impersonate a service account, instead of trying to use the STS token directly.