Working with Google Cloud often involves multiple projects and sophisticated permission models. A common, yet sometimes tricky, requirement is enabling a service account in one project to impersonate another service account in a different project. This is crucial for maintaining the principle of least privilege and streamlining access management.
However, developers frequently encounter “Permission denied” or “Invalid argument” errors when setting this up. Below is one such error which developers encounter while using ABAP SDK for Google Cloud.
This post will guide you through the complete process, leveraging a curl command from a Compute Engine VM to generate an access token for an impersonated service account across projects.
Note: This blog outlines a sample scenario for handling service account impersonation. It is not intended to be a guide for best practices. For best practice recommendations, please consult Google Cloud documentation.
Consider a common scenario faced by enterprises: a mission-critical SAP system with ABAP SDK deployed across multiple Google Cloud projects for disaster recovery.
During a DR switchover, the SAP system in dr-site-proj needs to take over, but it still requires access to the same Google API resources that are managed and provisioned in main-site-proj. The challenge arises when the SAP system (now running in dr-site-proj) tries to authenticate using its local VM’s service account to access resources tied to the service account in main-site-proj. This blog specifically addresses how to efficiently test this cross-project access without fully bringing up the entire DR SAP system.
So, for our example:
The goal is to get a short-lived access token for abap-sdk-main@main-site-proj.iam.gserviceaccount.com while running code on a VM associated with 942160574421-compute@developer.gserviceaccount.com. Out-of-the-box, this won’t work, leading to frustrating errors like:
This diagram illustrates the cross-project service account impersonation challenge:
The diagram shows that the VM in dr-site-proj (and its service account) needs a way to act as the abap-sdk-main service account in main-site-proj to access resources like Google Cloud Storage or Document AI which are configured within the main-site-proj context.
To clarify the roles and identities in this cross-project setup, refer to the table below:
Before we dive in, ensure you have:
{
"scope": [
"https://www.googleapis.com/auth/cloud-platform"
],
"lifetime": "3600s"
}
(Note: An empty {} often results in “Invalid Argument” for this specific API.)
The VM where your curl command runs needs to have sufficient scopes to request the initial token from its own metadata server, which will then be used to call the IAM Credentials API.
This is the most critical step to overcome the “Permission denied” error. Your dr-site-proj VM’s service account needs explicit permission to generate tokens for the abap-sdk-main service account. This permission must be granted directly on the target service account.
Now, with the correct IAM permissions and VM scopes in place, you can execute the curl command from your VM in dr-site-proj.
SSH into your VM instance in the dr-site-proj project. Ensure your request.json file (as defined in Prerequisites) is in the same directory. Please ensure to update the service account and make it relevant to your project.
# Part 1: Get the access token for the current VM's service account
# (942160574421-compute@developer.gserviceaccount.com)
ACCESS_TOKEN=$(curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" -H "Metadata-Flavor: Google" | sed -n 's/.*"access_token":"\([^"]*\)".*/\1/p') && \
\
# Part 2: Use that token to call the IAM Credentials API to generate a token
# for the target service account (abap-sdk-main@main-site-proj.iam.gserviceaccount.com)
curl -X POST \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/abap-sdk-main@main-site-proj.iam.gserviceaccount.com:generateAccessToken"
Here is an example error response when IAM permission are not granted.
Once granted as describe in step2, the script will generate the required token and validation error will be resolved.
Setting up cross-project service account impersonation requires careful attention to both VM access scopes and explicit IAM role grants on the target service account. By following these detailed steps, you can successfully implement secure and efficient cross-project communication in your Google Cloud environment, addressing challenges like testing DR scenarios without full system bring-up and avoiding common “Permission denied” and “Invalid argument” errors.