Unlinking may be initiated from your platform or Google, and the display of a
consistent link state on both provides the best user experience. Support for a
token revocation endpoint or Cross-Account Protection is optional for Google
Account Linking.

Accounts can become unlinked by any of the following:

- User request from
  - a Google application or [Google Account](https://myaccount.google.com) settings
  - Your platform
- Failure to renew an expired refresh token
- Other events initiated by you or Google. For example, account suspension by abuse and threat detection services.

## User requested unlinking from Google

Account unlinking initiated through a user's Google Account or app deletes any
previously issued access and refresh tokens, removes user consent, and
optionally calls your token revocation endpoint if you chose to implement one.

## User requested unlinking from your platform

You should provide a mechanism for users to unlink, such as a URL to their
account. If you don't offer a way for users to unlink, include a link to the
[Google Account](https://myaccount.google.com) so that the users
can manage their linked account.

You can choose to implement Risk \& Incident Sharing and Collaboration (RISC) and
notify Google of changes to the users account linking status. This allows for an
improved user experience where both your platform and Google show a current and
consistent linking status without the need to rely on a refresh or access token
request to update linking state.

## Token expiration

To provide a smooth user experience and avoid service disruption, Google
attempts to renew refresh tokens near the end of their lifetime. In some
scenarios, user consent might be required to re-link accounts when a valid
refresh token is unavailable.

Designing your platform to support multiple unexpired access and refresh tokens
can minimize race conditions present in client-server exchanges between
clustered environments, avoid user disruption, and minimize complex timing and
error handling scenarios. While eventually consistent, both previous and newly
issued unexpired tokens might be in use for a short period of time during the
client-server token renewal exchange and prior to cluster synchronization. For
example, a Google request to your service that uses the previous unexpired
access token occurs just after you issue a new access token, but before receipt
and cluster synchronization takes place at Google. Alternative security measures
to
[Refresh Token Rotation](https://tools.ietf.org/html/rfc6819#section-5.2.2.3)
are recommended.

## Other events

Accounts can be unlinked due to various other reasons, such as inactivity,
suspension, malicious behavior, and so forth. In such scenarios, your platform
and Google can best manage user accounts and relink by notifying one another of
changes to account and link state.

Implement a token revocation endpoint for Google to call, and notify Google of
your token revocation events using RISC to ensure your platform and Google
maintain consistent user account link state.

## Token revocation endpoint

If you support an OAuth 2.0
[token revocation endpoint](https://tools.ietf.org/html/rfc7009),
your platform can receive notifications from Google. This lets you inform users
of link state changes, invalidate a token, and cleanup security credentials and
authorization grants.

The request has the following form:

```
POST /revoke HTTP/1.1
Host: oauth2.example.com
Content-Type: application/x-www-form-urlencoded

client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET&token=TOKEN&token_type_hint=refresh_token
```

Your token revocation endpoint must be able to handle the following parameters:

| Revocation endpoint parameters ||
|---|---|
| `client_id` | A string that identifies the request origin as Google. This string must be registered within your system as Google's unique identifier. |
| `client_secret` | A secret string that you registered with Google for your service. |
| `token` | The token to be revoked. |
| `token_type_hint` | (Optional) The type of token being revoked, either an `access_token` or `refresh_token`. If unspecified, defaults to `access_token`. |

> [!NOTE]
> **Note:** Due to long lifetimes only refresh tokens will typically need to be revoked, short access token lifetimes can make revocation unnecessary.

Return a response when the token is deleted or invalid. See the following for
an example:

```
HTTP/1.1 200 Success
Content-Type: application/json;charset=UTF-8
```

If the token can't be deleted for any reason, return a 503 response code,
as shown in the following example:

```
HTTP/1.1 503 Service Unavailable
Content-Type: application/json;charset=UTF-8
Retry-After: HTTP-date / delay-seconds
```

Google retries the request later or as requested by `Retry-After`.

## Cross-Account Protection (RISC)

If you support Cross-Account Protection, your platform can notify Google when
access or refresh tokens are revoked. This allows Google to inform users of
link state changes, invalidate the token, cleanup security credentials, and
authorization grants.

Cross-Account Protection is based on the
[RISC standard](https://openid.net/wg/sse/) developed at the
OpenID Foundation.

> [!IMPORTANT]
> **Important:** This data is provided under the [Google APIs Terms of
> Service](https://developers.google.com/terms) and the additional [RISC Terms of Service](https://console.cloud.google.com/tos?id=risc) ("RISC Terms"). These signals may only be used for security, anti-fraud, and session management purposes. Please review and comply with the RISC Terms; failure to do so may result in project suspension or account suspension.

A [Security Event Token](https://tools.ietf.org/html/rfc8417)
is used to notify Google of token revocation.

When decoded, a token revocation event looks like the following example:

    {
      "iss":"http://risc.example.com",
      "iat":1521068887,
      "aud":"google_account_linking",
      "jti":"101942095",
      "toe": "1508184602",
      "events": {
        "https://schemas.openid.net/secevent/oauth/event-type/token-revoked":{
          "subject_type": "oauth_token",
          "token_type": "refresh_token",
          "token_identifier_alg": "hash_SHA512_double",
          "token": "double SHA-512 hash value of token"
        }
      }
    }

Security Event Tokens that you use to notify Google of token revocation events
must conform to the requirements in the following table:

| Token revocation events ||
|---|---|
| `iss` | **Issuer Claim:** This is a URL which you host, and it's shared with Google during registration. |
| `aud` | **Audience Claim:** This identifies Google as the JWT recipient. It must be set to `google_account_linking`. |
| `jti` | **JWT ID Claim:** This is a unique ID that you generate for every security event token. |
| `iat` | **Issued At Claim:** This is a `NumericDate` value that represents the time when this security event token was created. |
| `toe` | **Time of Event Claim:** This is an **optional** `NumericDate` value that represents the time at which the token was revoked. |
| `exp` | **Expiration Time Claim:** Do *not* include this field, as the event resulting in this notification has already taken place. |
| `events` | | Security Events Claim: This is a JSON object, and must include only a single token revocation event. || |---|---| | `subject_type` | This must be set to `oauth_token`. | | `token_type` | This is the type of token being revoked, either `access_token` or `refresh_token`. | | `token_identifier_alg` | This is the algorithm used to encode the token, and it must be `hash_SHA512_double`. | | `token` | This is the ID of the revoked token. | |

For more information on field types and formats, see
[JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519).