Impact of GCP session length on OAuth clients
Once you’ve signed in on google.com, the Cloud Console, or any other Google site, your browser session remains valid for multiple days. Not being prompted to sign in over and over again is convenient and at least in typical consumer scenarios, the risk that comes along with keeping the session is limited.
Things can look different in a corporate scenario where users might have access to sensitive data. Keeping sessions alive for 14 days (which is the default) might seem a little risky and might not be in line with an enterprise’s idea of security. G Suite Business and Cloud Identity Premium therefore allow you to change the default session length to a different period such as 8 hours. This setting applies to all Google services, not only GCP.
Recently, Google introduced another way to control session lifetime by allowing you to control the session length for Cloud Console and gcloud sessions.
This feature might look a bit redundant at first considering that you can already adjust the default session length – but there are two important differences:
- While changing the default session length is a feature that is only available in the G Suite Business and Cloud Identity Premium SKUs, setting the GCP session length works for all SKUs, including Cloud Identity Free.
- The setting not only affects browser clients, but tools such as
gcloud
and certain OAuth clients.
The last item is interesting and worth exploring a bit more.
Browser sessions and OAuth clients
When you first use an OAuth client – be it gcloud
or some other tool, you have to
authorize the client. The works by popping open a browser window (which picks up
your existing Google session if present) and then prompting you for your consent.
Once authorized, the client can fetch a refresh token which allows it to stay authorized.
The key point to realize is that while the browser session is used to kickstart the OAuth authorization, the lifetimes of the browser session and the refresh token are now disconnected: The browser session might time out after a few hours or days or you might explicitly sign out – but this does not affect the refresh token. The client can keep using the refresh token until one of the following events occur:
- The user has revoked your app’s access.
- The refresh token has not been used for six months.
- The user changed passwords and the refresh token contains Gmail scopes.
- The user account has exceeded a maximum number of granted (live) refresh tokens.
This explains why merely adjusting the default session length does not affect OAuth clients.
Reacting to expiring sessions
Setting a custom session length for Cloud Console and gcloud sessions
not only affects the length of the browser session for the Cloud Console, but also the
lifetime of OAuth refresh tokens: If an OAuth client obtained a token for a Google
Cloud scope, then the validity of the refresh token is limited to the configured GCP
session length. The list of scopes for which this applies includes .../auth/cloud-platform
,
as well as the more specific scopes such as .../auth/bigquery.readonly
.
The GCP session length can be set to a value as short as 1 hour.
When a browser session times out, it is pretty clear what should happen next: The user is redirected to the sign-on screen, is prompted for username and password (and hopefully a second factor), and is then sent back to the original URL that he attempted to access. But how should an OAuth client behave in case of a timeout?
As it turns out, the answer depends on the kind of OAuth client. Google distinguishes
between first-party clients and third-party clients. First-party clients are
administrative tools that Google provides – the most prominent examples are gcloud
and gsutil
. Third-party clients include any OAuth client that you register in the
Cloud Console.
First-party clients
When you use a first-party client such as gcloud
and the GCP session timeout expires, you are prompted
to re-authenticate. Depending on the configuration
that you applied in the Admin Console, you are either prompted
to re-enter your username and password or to touch your USB key:
When you look under the hood by observing the network communication of gcloud
, you can
see that the tool uses a new set of APIs (red) to negotiate the re-authentication before
it fetches a new token (green):
Notably, the prompt and logic to communicate with with those new APIs is implemented by
gcloud
itself.
When you use OAuth, you usually want to prevent that individual clients
ever get to see the user’s credentials. Having a tool like gcloud
implement a
re-authentication prompt deviates from this idea
for the sake of a better user experience – and it should therefore come as no surprise
that the new API that gcloud
is using is private and can only be used by first-party tools.
Third-party clients
When a third-party client attempts to refresh a token after the GCP session has expired, the OAuth call fails with the following error:
{
"error": "invalid_grant",
"error_description": "reauth related error (invalid_rapt)",
"error_subtype": "invalid_rapt"
}
This error is almost indistinguishable from the error a client receives
when the authorization for the client was revoked on myaccount.google.com
or when the refresh token expired for a different reason. The only difference is the subtype invalid_rapt
which indicates that the actual reason was that the GCP session length has expired.
By responding with a standard error code, Google remains fully OAuth compliant
which is an obvious advantage. Also, any well-behaved OAuth client should already
be able to deal with invalid_grant
errors by re-initiating the OAuth authorization flow.
In practice, many OAuth clients might not be as well-behaved however – it used
to be a rare event that a refresh token expired while a user was using the client.
And it is certainly not a very common scenario that a user revokes an authorization on
myaccount.google.com while still using the client.
Chances therefore are that a good percentage of clients either do not handle invalid_grant
errors at all, or at least not in a very graceful manner.
Preparing for custom GCP session lengths
Configuring a custom GCP session length means that an event that used to be quite
rare turns into an everyday event and OAuth clients need to be prepared to receive
invalid_grant
errors more often.
As an administrator, it is best to test how commonly used OAuth clients react to expiring sessions before configuring a custom session length. An easy way to do this is to revoke the authorization on myaccount.google.com while running the application and see how it reacts.
As a developer of an application that uses any of the Google Cloud OAuth scopes,
you should make sure that the application handles inavlid_token
errors properly:
If refreshing a token fails, the application should react by reinitiating an OAuth
authorization flow. Ideally, the application retries the failed operation once the
reauthorization has been completed successfully.
Granted, gracefully handling invalid_grant
errors can be challenging, especially in
GUI applications. Handling the error requires interacting with the user – but the
error could happen at any time and the GUI might not always be in a state where
such user interaction is possible.