Use Workload Identity Federation with another GCP project

Loïc Sikidi
Google Cloud - Community
5 min readOct 31, 2022
Photo by Claudio Schwarz

Since April 2021, GCP allows to setup an identity federation for external workloads. As mentioned in the official documentation:

Using identity federation, you can grant on-premises or multi-cloud workloads access to Google Cloud resources, without using a service account key.

Here, the term « external » seems to embrace all processes running outside GCP (eg. AWS, Azure, on-prem, SaaS, etc.). In deed, the main problem that Workload Identity Federation is trying to solve is the use of long-lived credentials, very well embodied by service account keys.

On my opinion, an « external » workload is everything that is running outside a GCP organization.

This being said, what happens when two GCP organizations need to work together?

From the moment, you know the email of a service account owned by another org, you can grant it permissions to your resources via:

  • Direct Access
  • Indirect Access: allow the latter to impersonate one of your service account

Knowing that the external service account is running on GCP, it can benefits from ambient credentials instead of a key.

DefinitionAmbient credentials are credentials that the application can obtain without having to perform any additional authentication.For example, in GCP it's provided thanks to a runtime service account + metadata server

With this in mind, it may sounds silly or overkill to use Workload Identity Federation for this kind of use case 😵.

However, let’s see how it can be useful!

Workload Identity Federation with a GCP project is not pointless

Let’s get straight to the point! The main drawback when you give access to an external SA in the « native way » is that it will be imperceptible in your audit logs.

Sample of audit logs using native IAM policy (direct access)

To put it another way, audit logs won’t highlight the fact that a service account DOESN'T belong to your org!

Note: I’ve observed the same behavior with an impersonation (indirect access).

In order to get this information, you will have to parse logs (eg. extract project_id or project_number from the email) and compare with your referential (eg. Cloud Asset Inventory) which requires time and resources.

On the other hand, if you use Workload Identity Federation, it will be explicit that an identity is outside of your realm.

Sample of audit logs using Workload Identity Federation

In my example, the subject follows this arbitrary pattern ext_gcp_sa::<sa_id>::<sa_email> . Now, if your organization respects a naming convention, your security team will be able to track external identities footprint without the need of data transformation!

Furthermore, treat all external identities in the same way provides consistency (eg. process, log format) which reduces overall complexity.

Now, I’ll show you how to setup this ⬇️

A concrete example

First of all, all the content describe below is also available in this repository.

We will create something like this:

Note: for simplicity’s sake, we will create all resources in the same project.

How the magic works?

  1. The trust relationship relies on two preconditions:
    a) the OIDC token MUST be issued by « https://accounts.google.com »
    b) the claim representing the service account ID in the OIDC token (here sub) MUST be in our allowed list. The trust is based on the SA ID because this value is unique over time (eg. if the service account is deleted and then recreated with the same email, the latter will be rejected because the ID will be different)
  2. The External Account Credentials (interpreted by Application Default Credentials) will look like something like this:
{
"type": "external_account",
"audience": "<AUDIENCE>",
"subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
"token_url": "https://sts.googleapis.com/v1/token",
"credential_source": {
"url": "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=<AUDIENCE>",
"headers": {
"Metadata-Flavor": "Google"
}
},
"service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/<SA_EMAIL>:generateAccessToken"
}

The subject_token is retrieved directly from the metadata server.

Setup

The first step is to enable Cloud Storage audit logs.

Then, run commands below:

Test

# Call the cloudfunction to produce audit logsfor i in {1..10}
do
curl -sS -H "Authorization: Bearer $(gcloud auth print-identity-token)" $CF_URL
done

Now, check Cloud Logging with this query protoPayload.serviceName="storage.googleapis.com" to see audit logs and check IAM delegation details.

Clean Up

Uncomment the Clean Up section from the script above in order to delete created resources.

If needed, disable Cloud Storage audit logs.

Conclusion

As you can see, using Workload Identity Federation with another GCP project can make sense. The feature brings a better visibility in your GCP organization and this, without a big effort. Visibility which can help your different teams (devs, security & compliance, top managements, etc.) in their daily tasks.

Generally speaking, if you have to give access to an external service account, always prefer indirect access to direct access .

I score the different methods as follows:

  1. Workload Identity Federation: solution that offers the best coverage of features.
  2. Regular impersonation: good trade-off but audit logs are less « context-aware ».
  3. Direct access: don’t allow to enforce any security policies (eg. org policy, get insights from Policy Intelligence, etc.) defined by your org. With this method you totally depend on the good will of your partner.

That’s all for today.

I hope this reflexion will be useful to some of you!

--

--

Loïc Sikidi
Google Cloud - Community

🇫🇷 Software engineer, passionate about IT. Highly interested in: web identity, security, automation and RFCs! Views expressed are my own.