Search code examples
google-cloud-platformgoogle-cloud-rungoogle-cloud-iamgoogle-cloud-load-balancer

Cloud Run behind GCLB - managing access using IAM


I'm trying to make IAM policies for Cloud Run work behind Google Cloud Load Balancer.

When calling a Cloud Run service directly, I need to set a target audience equal to the URL of the Cloud Run service, e.g. my-service-abcdef.a.run.app:

import { credentials } from '@grpc/grpc-js';
import { GoogleAuth } from 'google-auth-library';

const clientCredentials = await new GoogleAuth().getIdTokenClient(
  'https://my-service-abcdef.a.run.app',
);

const client = new MyServiceClient(
  'my-service-abcdef.a.run.app',
  credentials.combineChannelCredentials(
    credentials.createSsl(),
    credentials.createFromGoogleCredential(clientCredentials),
  ),
);

Now, when I put by Cloud Run service behind GCLB, I can actually still call it when I provide a domain I have linked to GCLB (e.g. my-domain.com), but I need to keep target audience (for the getIdTokenClient call) intact (https://my-service-abcdef.a.run.app).

This breaks (which is perfectly understandable) as soon as I add more regions behind GCLB, which have different "native" URL (in the .run.app domain, therefore would require different audiences).

Do Cloud Run services accept any other audiences? Can I specify my own?


Solution

  • There is a special case of an additional audience being supported. If you look at the documentation for end user auth, it provides the clue if you look at the decoded end-user token's audience.

    You will see that when you create a web app OAuth client in your project's credential section, you will have a client-id of the form

    nnn-xyz.apps.googleusercontent.com
    

    You can specify that as the audience when creating JWTs for the auth header via service account or GCP Auth client libraries. When using this JWT in requests to GCLB, it will work for services in any region. The caller's identity still needs to be an authorized identity in the IAM invoker membership list of each service.

    If you use the client-id of IAP (which is listed in that same credentials page) this can result in a single auth header passing 2 layers of validation: IAP auth checks, as well Cloud Run's IAM invoker check (once IAP is fully supported, which is partially in place already).

    One caveat to be aware of, the client-id must be created in the project before a revision is deployed. Deploying a new revision for existing services will pick up recently created client-ids.