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.

### Sessions

An authentication request by an application returns an ID Token. For example,
when a Sign in with Google button is pressed an ID Token is returned to the
Android, iOS, or Web client or server application displaying the button.

Authentication to sign-in to a Google Account is a distinct and separate event.
The claims returned in the ID Token represent this event. For example, the
authentication time and methods that were used to sign in to the Google Account.

There are two authentication moments and two user sessions:

- **User \<-\> Google Session** Established when a user signs into their Google Account. Google manages this session's lifecycle and security. The `auth_time` and `amr` claims provide you insights into this session.
- **User \<-\> Your Application Session** Established after the user signs in to your application, often initiated using Sign in with Google. Your application manages this session using the claims to improve session and account management decisions.

Users often interact with Google services across multiple devices, such as
phones, desktop computers, smart displays, or TVs. Signing in on each platform
or device establishes a distinct session. For web sign-ins, a session is
established between the specific browser and Google; note that Private Browsing
and Incognito modes create their own separate, isolated sessions. Because of
this, a single Google Account can have multiple distinct sessions active
simultaneously across various browsers and devices. For additional details,
refer to [See devices with account access](https://support.google.com/accounts/answer/3067630).

### Google Account status

The typical events of a Google Account lifecycle are:

- a person chooses to [Create a Google Account](https://support.google.com/accounts/answer/27441), then
- Google may disable the account or a user may re-activate it after following [How to recover your Google Account or Gmail](https://support.google.com/accounts/answer/7682439), and
- a person may decide to [Delete your Google Account](https://support.google.com/accounts/answer/32046) or due to [Inactive Google Account Policy](https://support.google.com/accounts/answer/12418290) Google may delete the account.

The Security Bundle features described by this guide apply to active or
disabled accounts, but not to Google Account creation or deletion events.

Google may disable an account at any time, for some of the reasons see
[Your account is disabled](https://support.google.com/accounts/answer/40695). When this occurs any active Google sessions
are terminated and a RISC event is sent by Google's Cross-Account Protection
service. Disabled accounts are blocked from using Sign in with Google, meaning
an ID token is never issued and so cannot be used to monitor for disabled
user accounts.

> [!IMPORTANT]
> **Important:** To improve security, we strongly recommend enabling Google's Cross-Account Protection service in order to receive and respond to account security events.

While receiving Cross-Account Protection (RISC) events is optional, these
events serve as important signals to manage the session between the user and
your app and whether. Instructions on how to implement RISC and respond to
events is described by [Protect user accounts with Cross-Account Protection](https://developers.google.com/identity/protocols/risc).

## Setup

To receive additional claims your app needs to be published, [verified](https://support.google.com/cloud/answer/13463073), and
security bundle features enabled. Start by confirming that your app is published
and verified:

1. Open [Google Auth Platform](https://console.cloud.google.com/auth)
2. Select or Create the Project for your app
3. Click **Audience** and confirm *Publishing status* is *In production*
4. Click **Verification Center** and confirm *Verification Status* is *Verified*

Next, enable additional claims:

1. Click **Settings** in the menu
2. Under **Advanced Settings** select:
   - *Session age claims* to enable `auth_time`
   - *Authentication strength claims* to enable `amr`

To learn more, visit the [OAuth App Verification Help Center](https://support.google.com/cloud/answer/13463073).

## Supported features

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

### Authentication Methods References

Authentication Methods References (`amr`) is an OpenID Connect [claim](https://openid.net/specs/openid-connect-core-1_0-final.html#IDToken) that
describes the methods used during the last authentication event between the
user and Google.

From the possible [IANA.AMR](https://www.iana.org/assignments/authentication-method-reference-values/authentication-method-reference-values.xhtml) values Google supports the following
values indicating that:

- `hwk` a hardware [security key](https://support.google.com/accounts/answer/7545682) was used
- `mfa` Multi-factor Authentication was completed
- `pwd` a Password was used
- `swk` a software key such as a [Passkey](https://support.google.com/accounts/answer/13548313) was used
- `sms` an SMS message was used for verification
- `tel` a phone call was used for verification

One or more of these values are returned as a JSON array of strings within the
ID token `amr` claim.

The `amr` claim is included in the ID token only when information is available
on the authentication method used, it may not be present even when requested.

Google Account owners may choose to require 2SV and which MFA methods to use.
When [Advanced Protection](https://landing.google.com/intl/en_in/advancedprotection/) is enabled on a Google Account a strong 2SV
method such as [Titan security keys](https://cloud.google.com/security/products/titan-security-key) (`hwk`) or [Passkey](https://www.google.com/account/about/passkeys/) (`swk`) are
required. In both situations, the `mfa` value is present when more than one
factor is used during sign-in to the Google Account.

The presence of `mfa` confirms the authentication event met Google's
requirements for Multi-Factor Authentication. For example, a Google Account
authentication with a Password (`pwd`) and a Passkey (`swk`) results in this
claim `"amr": ["mfa", "pwd", "swk"]`.

These resources have more information on account security and user
authentication:
[Get Google's strongest account security with the Advanced Protection Program](https://support.google.com/accounts/answer/7519408),
[Sign in with a passkey instead of a password](https://support.google.com/accounts/answer/13548313), and
[Use a security key for 2-Step Verification](https://support.google.com/accounts/answer/6103523).

Workspace admins control authentication policy for managed Workspace accounts,
and may require MFA or use of security keys. See
[Overview of Google identity management](https://docs.cloud.google.com/architecture/identity/overview-google-authentication) and
[Multi-factor authentication requirement for Google Cloud](https://docs.cloud.google.com/docs/authentication/mfa-requirement)
[Login protections \& controls](https://support.google.com/a/topic/7556597) for more.

### Authentication time

The [`auth_time` claim](https://openid.net/specs/openid-connect-core-1_0-final.html#IDToken) 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.

## Requests

The specific method used to request the `auth_time` and `amr` claims differs by
the API used, however every API includes an optional [`claims`](https://openid.net/specs/openid-connect-core-1_0.html#ClaimsParameter) parameter to
request `auth_time` and `amr`.

### 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}}`.
Similarly, add `{"amr":{"essential":true}}` to the `claims` to request `amr`:

```console
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 },
            "amr": {"essential":true}
          }
        }
```

> [!NOTE]
> **Note:** Line breaks were added for readability. The actual request and claims parameter value is URL-encoded JSON.

See [OpenID Connect](https://developers.google.com/identity/openid-connect/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` and `amr`
using the JavaScript API:

```html
<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, amr",
      });
      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](https://developers.google.com/identity/gsi/web/guides/overview) for more information.

### GIS for Android

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

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` objects of type `auth_time` and `amr`, using
`setClaims` to add them to the list of sign-in options:

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

See [Authenticate users with Sign in with Google](https://developer.android.com/identity/sign-in/credential-manager-siwg) for more information.

### iOS

The [Sign in with Google SDK](https://developers.google.com/identity/sign-in/ios/sign-in) for iOS adds an `authTimeClaim` object
and `claims` parameter to the `GIDSignIn` class that is used to optionally
request `auth_time` and `amr`.

> [!IMPORTANT]
> **Key Point:** If you intend to use `auth_time` do so on iOS 12 or later and macOS 10.15 or later.

Apps using `ASWebAuthenticationSession` update a device-wide shared cookie
jar. `GIDSignIn` uses this method by default in iOS 12 or later and
macOS 10.15 or later. In this scenario, a user signing in to their Google
Account is authenticated and the session is stored in the shared cookie jar.
Here `auth_time` is the user's last Google authentication on the device,
not just within your app.

`SFSafariViewController`, `WKWebView`, and `UIWebView` operate in isolated
sandboxes within your app, avoid using them when using `auth_time`. Here
`auth_time` is the user's last sign-in to the app itself, as the value is
always recent it is less meaningful.

To request `auth_time`, update [GoogleSignIn dependencies](https://developers.google.com/identity/sign-in/ios/start-integrating#install_the_google_sign-in_dependencies_in_your_project) to the latest
version and create an `authTimeClaim` object, adding it to the `claims` set.

To request `amr` create an `amrClaim` object and add it to the `claims` set.

### Swift


Add the claims set to the `GIDSignIn.sharedInstance.signIn` method:

```swift
let authTimeClaim = GIDClaim.authTime()
let amrClaim = GIDClaim.amr()
let claims = Set([authTimeClaim, amrClaim])

// Start the sign-in process
GIDSignIn.sharedInstance.signIn(
  withPresenting: rootViewController,
  claims: claims
) { signInResult, error in
  guard let result = signInResult else {
    print("Error signing in: (error?.localizedDescription ?? "No error description")")
    return
  }
  // If sign in succeeded, display the app's main content View
  print("ID Token: (result.user.idToken?.tokenString ?? "No token")")
}
```

<br />

### Objective-C


Add the claims set to the `signInWithPresentingViewController` method:

```objective-c
GIDClaim *authTimeClaim = [GIDClaim authTimeClaim];
GIDClaim *AMRClaim = [GIDClaim AMRClaim];
NSSet *claims = [NSSet setWithArray:@[authTimeClaim, AMRClaim]];

// Include the claims set and start the sign-in process
[GIDSignIn.sharedInstance
  signInWithPresentingViewController:self
                                hint:nil
                              claims:claims
                          completion:^(GIDSignInResult * _Nullable signInResult,
                                      NSError * _Nullable error) {
                            // On success signInResult.user.idToken
                            // contains the requested claims.
                          }];
```

<br />

See [Integrating Google Sign-In into your iOS or macOS app](https://developers.google.com/identity/sign-in/ios/start-integrating) for more
information.

## Responses

When the `auth_time` or `amr` claims are included in the request, they are
returned in the ID Token payload response alongside other standard claims
like `iss` (issuer), `sub` (subject), `aud` (audience), and `exp` (expiration
time).

Missing claims are likely due to the app not being verified or additional
settings are disabled, which is the default. Follow the instructions in
[Setup](https://developers.google.com/identity/siwg/security-bundle#Setup) to confirm the Client ID and App in use are Verified and
additional claims enabled.

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.

The value of the `amr` claim is a JSON array of strings representing the
authentication methods used during the last Google Account sign-in event.

This is an example of a decoded ID Token that includes the `auth_time` and
`amr` claims:

```json
{
  "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,
  "amr": ["mfa", "pwd", "tel"],
  "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.

> [!WARNING]
> **Warning:** When implementing your account management system, you **shouldn't** use the `email` field in the ID token as a unique identifier for a user. Always use the `sub` field as it is unique to a Google Account even if the user changes their email address.