Skip to main content
Your data always lands in an S3 bucket on AWS. If your company runs on Google Cloud and has no AWS account, you don’t need to create one: you read the bucket with a service account from your own Google Cloud project. It works like this:
  1. You tell us which service account will read the data.
  2. We create a read-only role for you on our side, and it trusts only that service account.
  3. Your service account asks Google for an ID token and exchanges it with AWS for temporary credentials to that role.
  4. You use those temporary credentials to read the bucket, with the same commands as the rest of this guide.
As in the AWS setup, we don’t issue credentials to you. No Cloud Humans key is stored on your side, and none of yours is sent to us. Every credential in this flow is short-lived and generated on demand.

Requirements

  • Data export enabled on your account. Contact the support team to request it.
  • A Google Cloud project where you can create a service account, and the gcloud CLI.
  • The AWS CLI or boto3 on the machine that downloads the files. Both read the bucket without any AWS account of your own.

Step 1: Create a dedicated service account

We recommend a service account used only for this export. It keeps the access easy to audit and to revoke.
The service account needs no IAM role in your Google Cloud project. Its only job is to prove its identity to AWS.

Step 2: Send us the service account’s unique ID

Every service account has a unique ID: a long number that never changes, even if the service account is renamed. This number, and nothing else, decides who can assume your role.
Send the support team:
The email does not replace the unique ID. If you delete the service account and create another one with the same name, the new one gets a different unique ID, and it cannot assume the role until you send us the new number.

Step 3: Receive your access details

Once the role is ready, we send you three values: The role can only list, download, and restore files in your bucket: s3:ListBucket, s3:GetObject, and s3:RestoreObject. You don’t need to attach any policy on your side, which is a difference from the AWS setup.
The audience is not a secret. It labels the token as meant for this export. What protects the role is the unique ID: AWS only accepts a token issued to your service account.

Step 4: Get a Google ID token

Your service account requests an ID token from Google with the audience we sent you. How it does that depends on where the download runs.
On Compute Engine, Cloud Run, Cloud Functions, or GKE with Workload Identity, run the job as the service account from step 1. The metadata server issues the token, with no key to store:
Avoid service account keys. Both options above work without downloading a JSON key, so there is nothing long-lived to leak or rotate.

Step 5: Configure the AWS CLI profile

Point the cloudhumans-export profile at the token file. The AWS CLI and boto3 exchange the token for temporary credentials on their own, and every command in this guide works unchanged.
~/.aws/config
You don’t need a ~/.aws/credentials file, and you don’t need any AWS account.
The Google ID token expires after about an hour. Generate a new one (step 4) at the start of every run, before the first AWS command. If a run lasts longer than the token, regenerate it during the run: the CLI and boto3 read the file again whenever they renew the credentials.

Smoke test

Generate the token, then list the bucket:
The expected output is the same as in the AWS smoke test. From here on, downloading works exactly as described for AWS customers: use the cloudhumans-export profile.

In a Python job

If you’d rather not write a token file, fetch the token and exchange it in code. On Google Cloud compute, fetch_id_token uses the metadata server; elsewhere, it uses the service account in GOOGLE_APPLICATION_CREDENTIALS.
The call to AWS needs no AWS credentials: the Google token is the credential. The temporary credentials expire too, and credentials["Expiration"] tells you when. For a job that runs past it, fetch a new token and call assume_role_with_web_identity again.

Revoking access

The control stays with you. Disable or delete the service account in your Google Cloud project, and it can no longer get tokens, so it can no longer assume the role. Nothing on our end needs to change. To move the access to another service account, send the support team its unique ID. The old service account stops working as soon as we update the role.

Troubleshooting

AccessDenied on AssumeRoleWithWebIdentity

AWS checked the token and it doesn’t match the role. Decode the token’s payload and compare it with what you sent us:
  • aud must be exactly <AUDIENCE>, with no extra slash or space.
  • sub must be the unique ID you sent us. A different number means the token came from another identity: usually your own user, when impersonation was left out.

InvalidIdentityToken or ExpiredTokenException

The token is malformed or older than about an hour. Generate a new one (step 4) and run the command again.

AccessDenied on s3:ListBucket or s3:GetObject

The role was assumed, so your identity is correct. Check the bucket name and the region (us-east-1). For files older than 180 days, see InvalidObjectState on download.