简体   繁体   中英

AWS Web Identity Federation with GCP ServiceAccount Credentials

I would like to access AWS resource with GCP credentials from my local computer. My code works fine if I run everything in GCP from a cloud function, but this also should work locally.

If I run my code locally I got the following error which says taht my generated JWT token is invalid.

An error occurred (InvalidIdentityToken) when calling the AssumeRoleWithWebIdentity operation: Error normalizing issuer

I have a service Account keyfile on my local machine. I create a JWT token from this file:

def create_jwt_token(keyfile: str, audience: str):
  jwt_creds = google_auth_jwt.Credentials.from_service_account_file(
    keyfile, audience=audience)
  request = ga_requests.Request()
  jwt_creds.refresh(request)
  return jwt_creds.token.decode('utf-8')

The issuer is equal the serviceaccount email address. Fore the audience I set the gcp project-id.

Here is the code for generating AWS credentials:

def generate_aws_credentials(arn: str, token: str, role_session_name: str):
  sts = boto3.client('sts', region_name="eu-west-1")
  try:
    result = sts.assume_role_with_web_identity(
        RoleArn=arn,
        WebIdentityToken=token,
        RoleSessionName=role_session_name)
  except Exception as ex:
    raise Exception(f"unable to create aws identity token. {ex}")
  return result

As I said, the code works from within gcp but not locally. I am not able to see the difference between the tokens in gcp and local.

This is not an answer - the following text is too large to fit as a comment.

It has been a while since I wrote GCP -> AWS federation. IIRC you should call assume_role_with_web_identity() with an OIDC Identity Token from the service account. You are passing a JWT which is the first step in the creation of an OAuth Access Token. Access Tokens are not used for identity federation. Your JWT is used for RBAC and not Identity.

Setting the audience to the gcp project-id is also not correct.

Another requirement is to create an AWS Role and Trust Policy. Your question does not mention either. The trust policy must specify conditions based upon the OIDC Identity Token.

I think you are confused with JWTs created by google_auth_jwt and OIDC Identity Tokens. Both are similar but are used differently. They are both JWTs but with different payloads.

The JWT azp contains the service account email address.

The JWT aud contains the target audience which you specify when requesting an OIDC Identity Token.

AWS will use the JWT header kid to determine the certificate that signed the JWT.

Since I am pulling this from memory, I might have a detail wrong. However, the key item that you are doing incorrectly is using the wrong type of JWT for the identity federation.

I had the same issue and found that the above code signs a JWT using the referenced service account key, but that JWT is not issued by Google.

Try gcloud auth activate-service-account --key-file=./YOUR/KEY.json --audiences=<AUDIENCE and you get a very different JWT with "iss": "https://accounts.google.com",

That can be done in Python too I'm sure - sorry I don't have a sample.

Now my issue is a mismatch of audiences against the OIDC provider configured in AWS.. separate issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM