-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
golang SA impersonation requires permission iam.serviceAccounts.getOpenIdToken whereas other clients do not #2301
Comments
Go: google-api-go-client/idtoken/idtoken.go Line 159 in 10dbf2b
|
Moving this to a feature request because at the time of implementation impersonated service accounts were not a concept. We will evaluate if we will switch this logic in the future. |
I reported this to google cloud support, who created this issue. I believed this to be a bug in idtoken, because idtoken has special logic to handle issuing tokens using impersonated credentials added two years ago in #1792 and modified in #1897 that differs from the same feature implementation in other google auth libraries. If this is not a bug it would be very helpful for the expected behavior among the different client libraries to be documented somewhere or the idtoken docs to point to the right pattern. Both me and two separate teammates independently encountered this issue of IAM failures when attempting to use the idtoken library with impersonated credentials, even though we had I'm attaching code for reproduction below showing that Setup a new SA and give yourself #!/bin/bash
# Prerequisites:
# 1. logged into gcloud cli as a regular user (just `gcloud auth login`)
# 2. CLOUDSDK_CORE_PROJECT is set
set -euxo pipefail
SA_NAME="idtoken-2301-$(date +%Y-%m-%d)"
# Just in case, clean up any existing service account
gcloud iam service-accounts delete $SA_NAME@$CLOUDSDK_CORE_PROJECT.iam.gserviceaccount.com --quiet || true
gcloud iam service-accounts create $SA_NAME
# grant ourselves token creator on the service account
gcloud iam service-accounts add-iam-policy-binding $SA_NAME@$CLOUDSDK_CORE_PROJECT.iam.gserviceaccount.com --member=user:$(gcloud config get-value account) --role=roles/iam.serviceAccountTokenCreator
# Check that we can create a token
curl "https://oauth2.googleapis.com/tokeninfo?id_token=$(gcloud auth print-identity-token --include-email --impersonate-service-account=$SA_NAME@$CLOUDSDK_CORE_PROJECT.iam.gserviceaccount.com)"
# ADCs to use the new service account
gcloud auth application-default login --impersonate-service-account=$SA_NAME@$CLOUDSDK_CORE_PROJECT.iam.gserviceaccount.com
package main
import (
"context"
"fmt"
"google.golang.org/api/idtoken"
)
func main() {
ts, err := idtoken.NewTokenSource(context.Background(), "https://example.com")
if err != nil {
panic(err)
}
token, err := ts.Token()
if err != nil {
panic(err)
}
fmt.Println(token)
} Run with:
This will output the following, showing that the service account is attempting to issue an idToken for itself:
However, compare with this node code: const {GoogleAuth} = require('google-auth-library');
// https://github.com/googleapis/google-auth-library-nodejs/blob/6014adec1b7b1e9abe6fa2fdd53e3231029f9129/samples/idTokenFromMetadataServer.js#L34
async function main() {
const auth = new GoogleAuth();
const client = await auth.getIdTokenClient("https://example.com");
const token = await client.idTokenProvider.fetchIdToken("https://example.com");
const r = await fetch("https://oauth2.googleapis.com/tokeninfo?id_token=" + token);
console.log(await r.json());
}
main().catch(console.error); Running this with |
The |
I've encountered this issue with this library, and also submitted an issue in the I believe the issue is similar here. As noted by others in the thread, the underlying google-api-go-client/idtoken/idtoken.go Line 181 in 6495d84
|
The golang idtoken library first calls generateAccessToken on the impersonated service account as the source user, and then uses that access token to call generateIdToken on the service account.
This requires the service account to have the permission of iam.serviceAccounts.getOpenIdToken access on itself.
The issue is that the idtoken library [in Go lang] does not use the source_credentials subfield in the JSON struct when constructing the inner client, and instead uses the entire credential json. The other clients (like JS and PHP clients) do not operate in this way.
google-api-go-client/idtoken/idtoken.go
Line 159 in 10dbf2b
The text was updated successfully, but these errors were encountered: