Andy Hume
Andy Hume

Reputation: 41664

Google Cloud Run masks Bearer token in Authorization header

The Google documentation for Cloud Run states that you can "pull the token out of the Authorization header" (docs here) in order to validate it and obtain further information about the requesting user.

However, when reading the Authorization header while processing the request, it appears that parts of the token have been redacted after passing through Google's auth frontend. E.g

Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImY2ZjgwZjM3ZjIxYzIz.SIGNATURE_REMOVED_BY_GOOGLE

Is this a bug in Cloud Run or do we need to do something different to obtain the full Bearer token?

Upvotes: 2

Views: 2551

Answers (2)

John Hanley
John Hanley

Reputation: 81376

Here are the details for the Authorization Header and SIGNATURE_REMOVED_BY_GOOGLE as seen inside Cloud Run:

  1. If allUsers is enabled, the JWS signature comes thru and is not replaced.
  2. If allUsers is not enabled AND the OIDC token is from a Google Account (gmail) then the signature is replaced.
  3. If allUsers is not enabled AND the OIDC token is from a service account, then the signature is not replaced.

[Update 3/8/2021]

The reason that Google redacts the signature for Identity Tokens is to prevent Identity Token reuse. A valid Identity Token would allow the service to impersonate the user/account with another service which is a security risk.

Upvotes: 7

guillaume blaquiere
guillaume blaquiere

Reputation: 75790

When I check the user identity, I only take the 2nd part of the token. Here a snippet of my Python code for doing this. I rely on Google for performing security/validation stuff, and thus, don't care about the signature.

    # get the JWT token after the Bearer prefix
    authorization = request.headers['Authorization'][7:] 
    # split the token and take only the 2nd part 
    b64_profile = authorization.split('.')[1] 
    # decode correctly the B64 token part
    profile = base64.b64decode(b64_profile + '=' * (-len(b64_profile) % 4)) 
    # load the JSON and enjoy!
    print(json.loads(profile)['email']) 

Note: email is sometime empty, in case of allUsers authorization

Upvotes: 3

Related Questions