Security bundle

This guide describes a collection of features that return additional trust signals about a Google Account. These trust signals help your account management system to make risk-based decisions during sign up, account creation, and later for returning users.

Setup

To receive additional claims your app needs to be published, verified, and security bundle features enabled.

To confirm that your app is published and verified:

  1. Open Google Auth Platform
  2. Select or Create the Project for your app
  3. Click Audience in the menu
  4. Confirm Publishing status is In production
  5. Click Verification Center in the menu
  6. Confirm Verification Status is Verified.

    To learn more, visit the OAuth App Verification Help Center.

To enable the auth_time claim:

  1. Open Google Auth Platform
  2. Select or Create the Project for your app
  3. Click Settings in the menu
  4. Under Advanced Settings select Session age claims to enable auth_time.

Supported features

This section describes the individual features that make up the Security Bundle.

auth_time

The auth_time claim is a standard part of the OpenID Connect protocol that provides information about when the End-User most recently authenticated with Google. It is a JSON number representing the number of seconds that have elapsed since the Unix epoch (January 1, 1970, 00:00:00 UTC) and is the time the user last authenticated. Think of it as a timestamp indicating the user's last login event to their Google Account from the current device or browser. This claim is included within the ID Token, which is a JSON Web Token (JWT) containing verified information about the authentication and the user.

The auth_time claim is valuable for your application because it lets you determine how recently a user has actively logged into a Google Account on the device or browser they are using. This can be particularly important for security purposes such as:

  • Making an informed decision about whether your app should issue an additional step-up authentication challenge prior to performing sensitive user actions like deleting the account, changing account contact methods, or making a payment. Google does not support Google Account reauth requests.

  • Using the freshness and stability of the user's Google Account session as a trust signal. Generally speaking, a recent auth_time value is an indication of freshness, while an older value indicates stability.

For web apps, the combination of the user's browser and operating system constitute a session after the user signs into their Google Account. Independently, your website also maintains a separate user session. A newer auth_time value indicates the user recently signed into their Google Account. Often this is an indication of an active, engaged user and can be interpreted as a signal of lower risk.

On mobile platforms such as Android users typically sign-in directly into their device using biometric methods like fingerprint or facial scanning and device specific PIN or pattern unlocks. Mobile apps and platforms often use these platform based authentication methods rather than creating a new session with Google, resulting in infrequent Google Account sign-ins and corresponding updates to auth_time. So here a recent auth_time value may signal a change to a long running Google Account session and thus increased risk.

Trust signals are a nuanced subject. auth_time is expected to be used along with other signals such as whether multi-factor authentication (MFA) is enabled, the authentication method used, and the duration of the user session between your application and your platform.

auth_time request

The specific method used to request the auth_time claim differs by the API used, however every API includes an optional claims parameter to request auth_time.

OIDC protocol

When using the OAuth Platform directly, request auth_time by adding it to the optional claims request parameter. Set the value of the id_token field of the claims JSON object to {"auth_time":{"essential":true}}. For example,

https://accounts.google.com/o/oauth2/v2/auth?
response_type=id_token&
client_id=YOUR_CLIENT_ID&
scope=openid email profile&
redirect_uri=https://example.com/user-login&
nonce=123-456-7890&
claims={"id_token":{"auth_time":{"essential":true}}}

See OpenID Connect for more information.

GIS for Web

The Sign in with Google library for Web has two APIs: HTML and JavaScript to request additional claims. For example, request auth_time using the JavaScript API:

<html>
<body>
  <script src="https://accounts.google.com/gsi/client" async></script>
  <script>
    window.onload = function () {
      google.accounts.id.initialize({
        client_id: "YOUR_WEB_CLIENT_ID",
        callback: function(rsp) { console.log(rsp.credential); },
        essential_claims: "auth_time",
      });
      google.accounts.id.renderButton(
        document.getElementById("buttonDiv"),
        { type: "standard", size: "large" }
      );
    }
  </script>
  <div id="buttonDiv"></div>
</body>
</html>

See Sign in with Google for Web for more information.

GIS for Android

A setClaims method and Claim object are used to request auth_time.

Update your build dependencies to use the latest versions of the androidx.credentials:credentials-play-services-auth and com.google.android.libraries.identity.googleid:googleid libraries.

Instantiate a Claim object of type auth_time, using setClaims to add it the sign-in options:

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
    .setAutoSelectEnabled(true)
    .setFilterByAuthorizedAccounts(true)
    .setServerClientId(WEB_CLIENT_ID)
    .setNonce("NONCE")
    .setClaims(ImmutableList.of(new Claim("auth_time", true)))
    .build()

See Authenticate users with Sign in with Google for more information.

auth_time response

When the auth_time claim is included in the request, it appears in the ID Token payload response alongside other standard claims like iss (issuer), sub (subject), aud (audience), and exp (expiration time). The value of the auth_time claim is a JSON number representing the number of seconds that have elapsed since the Unix epoch (January 1, 1970, 00:00:00 UTC) until the time user authentication last occurred. This is an example of a decoded ID Token that includes the auth_time claim:

{
  "iss": "https://accounts.google.com",
  "azp": "YOUR_CLIENT_ID",
  "aud": "YOUR_CLIENT_ID",
  "sub": "117726431651943698600",
  "email": "alice@example.com",
  "email_verified": true,
  "nonce": "123-456-7890",
  "auth_time": 1748875426,
  "nbf": 1748880889,
  "name": "Elisa Beckett",
  "picture": "https://lh3.googleusercontent.com/a/default-user=s96-c",
  "given_name": "Elisa",
  "family_name": "Beckett",
  "iat": 1748881189,
  "exp": 1748884789,
  "jti": "8b5d7ce345787d5dbf14ce6e08a8f88ee8c9b5b1"
}

The ID Token also contains an iat (issued at) claim, which indicates the time the JWT was issued. By comparing the iat and auth_time claims, you can determine the time elapsed since the user's last authentication relative to when the specific ID Token was created. For example, if iat is 1748881189 and auth_time is 1748875426, the difference is 5763 seconds, which represents 1 hour, 36 minutes, and 3 seconds of elapsed time.