Authenticating end users in Cloud Run (fully managed)

If your application handles requests from end users, it's a best practice to restrict access to only the allowed end users. In order to accomplish this, you can choose one of the following:

In either of the above choices, you need a public web or mobile app that handles the sign-in flow and then makes authenticated API calls to a Cloud Run (fully managed) service. This public web app can itself be hosted on a public Cloud Run (fully managed) service. If you are using Google Sign-In, this public web app must be under the same domain as the Cloud Run (fully managed) service that requires authentication.

Using Identity Platform or Firebase Authentication

If you want to authenticate users using email/password, phone number, social providers like Facebook or GitHub, or a custom authentication mechanism, you can use Firebase Authentication or Identity Platform.

Using Firebase Authentication is similar to using Identity Platform.

  1. Set up Firebase Authentication in your project and service:

    1. Set up Firebase Authentication in the Firebase Console.

      Go to the Firebase Console

    2. Import the appropriate Firebase Admin SDK and configure it properly.

    3. Add middleware to your code to verify Firebase ID tokens.

    4. Deploy your service publicly.

  2. Do the following in your web or mobile app:

    1. Use the appropriate Firebase Auth client library to get an ID token:
    2. Include the ID token in an Authorization: Bearer ID_TOKEN header in the request to the service.

Getting user profile information

If you want to access user profile information, you can use the Firebase Admin SDK to retrieve user data.

Using Google Sign-In

Enable Google Sign-In in your project:

  1. Create an OAuth 2.0 client ID for your app in the same project as the service you want to secure:
    1. Go to the Credentials page.

      Go to the Credentials page

    2. Select the project with the service you want to secure.
    3. Click Create credentials, then select OAuth Client ID.
      1. You may be required to configure your OAuth consent screen before creating a client ID. If necessary, do so in order to continue.
    4. Select the Application type for which you want to create credentials.
    5. Add a Name and Restrictions if appropriate, then click Create.
  2. Re-deploy the service you want to secure. This will ensure that the correct client ID is set on the service.

    If you have multiple OAuth client IDs (for example, one each for Android, iOS, and web), you must re-deploy your service(s) after adding each one to ensure the service picks up the change. Similarly, if you delete a client ID, you must re-deploy your service(s) to remove that client ID and deny requests. All client IDs within a project will be accepted.

Do the following in your web or mobile app:

  1. Get an ID token for the OAuth client ID:
  2. Include the ID token in an Authorization: Bearer ID_TOKEN header in the request to the service.

Cloud Run validates the auth token and either allows the request or rejects it before the service starts up. If a request is rejected, you aren't billed for that request.

Web apps, authentication, and CORS

When you build a web app, you have to account for Cross-Origin Resource Sharing (CORS) issues. For example, CORS preflight requests are sent without an Authorization header, so they are rejected on a non-public service. Because the preflight requests fail, the main request will also fail.

To work around this, you can host your web app and service(s) on the same domain to avoid CORS preflight requests. You can achieve that by using Firebase Hosting.

Getting user profile information

If you want to access user profile information, you can pull the token out of the Authorization header and make a request to the Validate Token endpoint.

The body of the ID token is returned with the following information:

{
 // These six fields are included in all Google ID Tokens.
 "iss": "https://accounts.google.com",
 "sub": "110169484474386276334",
 "azp": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
 "aud": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
 "iat": "1433978353",
 "exp": "1433981953",

 // These seven fields are only included when the user has granted the "profile"
 // and "email" OAuth scopes to the application.
 "email": "testuser@gmail.com",
 "email_verified": "true",
 "name" : "Test User",
 "picture": "https://lh4.googleusercontent.com/-kYgzyAWpZzJ/ABCDEFGHI/AAAJKLMNOP/tIXL9Ir44LE/s99-c/photo.jpg",
 "given_name": "Test",
 "family_name": "User",
 "locale": "en"
}

Troubleshooting

If user requests are rejected and you believe they should be allowed, ensure that users have been granted the roles/run.invoker role, or have the run.routes.invoke permission. Learn more about these in the Cloud Run IAM reference.