GCP Auth - Restrict Token Creator Role to a Specific Service Account (Only Make JWTs for Self)

I’m experimenting with GCP auth for HashiCorp Vault, using iam based authentication on Compute Engine instances.

I’ve created service accounts for both the Vault server and an application server and applied them to Compute Engine instances. As suggested in the Vault docs, the Vault server has iam.serviceAccountKeyAdmin and the app server has iam.serviceAccountTokenCreator.

A warning in the docs says to Make sure this role [serviceAccountTokenCreator] is only applied so your service account can impersonate itself. If this role is applied GCP project-wide, this will allow the service account to impersonate any service account in the GCP project where it resides. I have proved this is an issue to myself, by having the app server create a JWT for the attached service account and the Vault service account(!).

The question is, how do I heed the above warning? How do I make sure the application server can only create JWTs for itself?

What Doesn’t Work

I have tried adding a condition to the app server’s service account, on the iam.serviceAccountTokenCreator role. With name matching, I’ve tried

  • The service account’s own email address
  • The full name of the service account (projects/-/serviceAccounts/service_account_email_address)
  • The full instance name of the instance that should have access (projects/project-id/zones/zone-id/instances/instance-id) where instance_id is the ID from the VM details and the human-readable name that I’ve given the machine.

None of them allow a user on the application server to create a JWT for the attached service account, they all result in not being able to create any JWT - googleapi: Error 403: The caller does not have permission, forbidden

I am using the Vault CLI login helper to test this (vault login -method=gcp). I’ve been waiting a few minutes between each attempt to allow the changes to propagate through the IAM API.

What Does Work (but I’m not sure of it’s validity)

Using three service accounts, one for Vault as above and two for the app server; an app server “ID” account with no roles attached and a “machine” account added as a principal onto the “ID” account with the serviceAccountTokenCreator role.

The “machine” account was then used as the service account for the app server Compute Engine instance. Now, from that machine, I can only create a JWT for the app server “ID” account and not the Vault service account. Is this a valid solution?

1 Like