Automatically Sign Up Users with Streamlined Identity Flows

By supporting the automatic sign-up flow and account linking flow, you enable users who are signed in to their Google Accounts to automatically and seamlessly create accounts on your service from Google Assistant. Automatic sign-up is the easiest way for users to get started with your Action and yields the highest rate of new account creations for your service.

Before you begin

Before you can implement automatic sign-up, you must do the following:

  • Implement the code flow or the implicit flow for account linking.
  • Support Google Sign-in as a way for users to sign in to your service.
  • Create or find an OAuth 2.0 client ID for your service. You can create or find the client ID on the Credentials page of the Google API Console. When you create a client ID for your service, select the Web application type.
  • Enable account linking for your project in the Actions console. You will need to provide the client ID you found or created in the previous step.

Overview

To implement automatic sign-up, you must extend your service's OAuth 2.0 token exchange endpoint (or, if you didn't implement the code flow, create a new endpoint) to support the assertion flow. Your token exchange endpoint will handle two kinds of assertion requests:

  • Requests to exchange JSON Web Tokens (JWTs)—which contain the user's Google Account information—for access tokens and refresh tokens
  • Requests to create a new account on your service, based on the information contained in a JWT

When Google needs to access your service's resources, and the user is signed in to their Google Account, Google sends a signed JWT with information about the user to your token exchange endpoint. The request has the following form:

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

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&intent=ACTION&assertion=JWT&consent_code=CONSENT_CODE&scope=SCOPES

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

Token endpoint parameters
grant_type The type of token being exchanged. In assertion flow requests, this parameter has the value urn:ietf:params:oauth:grant-type:jwt-bearer.
intent Either get or create. Specifies whether the request is to get an access token for an existing user or to create a new user account.
assertion A JSON Web Token (JWT) that provides a signed assertion of the Google user's identity. The JWT contains information including the user's Google Account ID, name, and email address.
consent_code Optional: When present, a one-time code that indicates that the user has granted consent for your Action to access the specified scopes.
scope Optional: The scopes, if any, you configured Google to request from users.

If the value of grant_type is urn:ietf:params:oauth:grant-type:jwt-bearer, Google is making an assertion flow request, and you should respond based on the value of the intent parameter.

Exchange JWT assertions for tokens

When your token exchange endpoint receives an assertion flow request that specifies intent=get, it should either exchange the JWT assertion included in the request for an access token and refresh token if account linking is possible, or return an error code that directs Google to other branches of the automatic account linking and sign-up flows.

Specifically, your token exchange endpoint should do the following:

  1. Validate and decode the JWT assertion. You can do so by using a JWT-decoding library for your language. Use Google's public keys (available in JWK or PEM format) to verify the token's signature.

    When decoded, the assertion looks like the following example:

    {
      "sub": 1234567890,        // The unique ID of the user's Google Account
      "iss": "https://accounts.google.com",        // The assertion's issuer
      "aud": "123-abc.apps.googleusercontent.com", // Your server's client ID
      "iat": 233366400,         // Unix timestamp of the assertion's creation time
      "exp": 233370000,         // Unix timestamp of the assertion's expiration time
      "name": "Jan Jansen",
      "given_name": "Jan",
      "family_name": "Jansen",
      "email": "jan@gmail.com", // If present, the user's email address
      "locale": "en_US"
    }
    

    In addition to verifying the token's signature, verify that the assertion's issuer (iss) is https://accounts.google.com and that the audience (aud) is your authentication server's client ID.

  2. Check whether either of the following conditions are true:
    • The Google Account ID, found in the assertion's sub claim, is in your user database
    • The email address in the assertion matches a user in your user database
    If either condition is true, the user has already signed up and you can issue an access token and refresh token as described in the code flow documentation.

    If you use scopes to control access to specific resources, you must also confirm that the user has granted access to the specified scopes. If the user has not yet granted permission to access the scopes, you must ask for permission:

  3. If neither the Google Account ID nor the email address specified in the assertion matches a user in your database, the user hasn't signed up to use your Action yet. Automatically sign up the user by responding to the request with a HTTP 401 error, specifying error=user_not_found as in the following example:
    HTTP/1.1 401 Unauthorized
    Content-Type: application/json;charset=UTF-8
    
    {
      "error":"user_not_found",
    }
    
    When Google receives the 401 error response with a user_not_found error type, it will collect any information you require to sign up a new user. Then, Google calls your token exchange endpoint with the intent=create parameter to create the new account. See Create new accounts from JWT assertions.
  4. Optional: If, at any point in your flow, you can't proceed with automatic sign-in or sign-up, you can fall back to your manual flow by directing the user to your authentication endpoint. To do so, respond to the request with an HTTP 401 error, specifying error=linking_error, and, optionally, identifying information about the user, such as an email address or the Google JWT in the login_hint parameter, as in the following example:
    HTTP/1.1 401 Unauthorized
    Content-Type: application/json;charset=UTF-8
    
    {
      "error":"linking_error",
      "login_hint": EMAIL_ADDRESS
    }
    
    
    When Google receives the 401 error response with a linking_error error type, it redirects the user to your authentication endpoint, passing along the login_hint parameter, where the user can sign in to your service.

Create new accounts from JWT assertions

When a user needs to create an account on your service, Google makes a request to your token exchange endpoint that specifies intent=create, as in the following example:

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

response_type=token&grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&scope=SCOPES&intent=create&consent_code=CONSENT_CODE&assertion=JWT[&NEW_ACCOUNT_INFO]

The NEW_ACCOUNT_INFO parameters are custom parameters that contain the information your service requires to create a new account.

To respond to account creation requests, your token exchange endpoint must do the following:

  1. Confirm that the information provided for the new account doesn't already identify one of your users. For example, if the request includes the verified_phone parameter, confirm that the specified phone number doesn't belong to one of your existing users.

    If the new account information corresponds to an existing user, prompt the user to link their existing account with their Google Account by responding to the request with an HTTP 401 error, specifying error=linking_error, and the user's email address as the login_hint.

  2. Confirm that the value of the consent_code parameter is the same as the one you created earlier, applies to the same Google Account, and isn't expired.
  3. Validate and decode the JWT assertion as you did for intent=get requests.
  4. Create a new user account using the information provided in the JWT and query parameters.

    New accounts typically do not have a password set. You can email the user a link that starts your password recovery flow to allow the user to set a password for signing in on other platforms.

    Be sure to store the user's Google Account ID—the value of the JWT's sub claim—in your user database with the new account data.

  5. Issue an access token and refresh token as described in the code flow documentation.

Allow users to access automatically-created accounts

By implementing this flow, account creation becomes a seamless 1-click process. However, new users with automatically created accounts still need a way to sign in to their accounts on their other devices and the other platforms you support.

To provide a way for users with automatically created accounts to sign in to your apps on other platforms such as your mobile app, you should support Google Sign-in as a way for users to sign in to your service.

In addition, you can optionally provide a password recovery flow that users who choose not to sign in with Google can use to set an initial password for their accounts.