Interaction between 'delegates' and Workload Identity Federation
Tutuchan opened this issue · comments
Hello,
I'm having a hard time understanding how to create a delegation chain to impersonate a service account using this Github Action.
Here is my workflow.
In GCP project MY_PROJECT
, I have 2 service accounts:
MY_SA@MY_PROJECT.iam.gserviceaccount.com
: main service account with large permissionsMY_SA-CICD@MY_PROJECT.iam.gserviceaccount.com
: only has theroles/iam.serviceAccountTokenCreator
onMY_SA
.
Meanwhile, WIF is configured so that the principalSet corresponding to a specific repository has roles/iam.workloadIdentityUser
and roles/iam.serviceAccountTokenCreator
on MY_SA-CICD
. I am trying to authenticate to MY_SA
with a single auth Github Action.
Here is a simplified version of the Github workflow:
jobs:
test_workflow:
permissions:
contents: read
id-token: write
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- id: "auth"
uses: "google-github-actions/auth@v1"
with:
workload_identity_provider: projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/MY_POOL/providers/MY_PROVIDER
service_account: MY_SA@MY_PROJECT.iam.gserviceaccount.com
delegates: MY_SA-CICD@MY_PROJECT.iam.gserviceaccount.com
token_format: "access_token"
access_token_lifetime: 3600s
- id: "setup-gcloud"
uses: "google-github-actions/setup-gcloud@v1"
- run: |
gcloud auth list
gcloud artifacts repositories list
gcloud auth list
returns
ACTIVE ACCOUNT
* MY_SA@MY_PROJECT.iam.gserviceaccount.com
but gcloud artifacts repositories list
fails with
There was a problem refreshing your current auth tokens: ('Unable to acquire impersonated credentials', '{\n "error": {\n "code": 403,\n "message": "Permission \'iam.serviceAccounts.getAccessToken\' denied on resource (or it may not exist).",\n "status": "PERMISSION_DENIED",\n "details": [\n {\n "@type": "type.googleapis.com/google.rpc.ErrorInfo",\n "reason": "IAM_PERMISSION_DENIED",\n "domain": "iam.googleapis.com",\n "metadata": {\n "permission": "iam.serviceAccounts.getAccessToken"\n }\n }\n ]\n }\n}\n')
If I don't use delegates
and use --impersonate-service-account
in subsequent gcloud
calls, it's working fine, e.g.
jobs:
test_workflow:
permissions:
contents: read
id-token: write
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- id: "auth"
uses: "google-github-actions/auth@v1"
with:
workload_identity_provider: projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/MY_POOL/providers/MY_PROVIDER
service_account: MY_SA-CICD@MY_PROJECT.iam.gserviceaccount.com
access_token_lifetime: 3600s
- id: "setup-gcloud"
uses: "google-github-actions/setup-gcloud@v1"
- run: |
gcloud auth list
> ACTIVE ACCOUNT
> * MY_SA-CICD@MY_PROJECT.iam.gserviceaccount.com
gcloud artifacts repositories list
> WARNING: This command is using service account impersonation. All API calls will be executed as [MY_SA@MY_PROJECT.iam.gserviceaccount.com].
> [list of artifact registry repositories]
In the audit logs, for the 1st case, I'm under the impression that the delegation chain is ignored when doing the gcloud
call – based on the authenticationInfo
and request
keys in the protoPayload
field. See
{
"protoPayload": {
"@type": "type.googleapis.com/google.cloud.audit.AuditLog",
"status": {
"code": 7,
"message": "Permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist)."
},
"authenticationInfo": {
"serviceAccountDelegationInfo": [
{}
],
"principalSubject": "principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/MY_POOL/subject/repo:MY_ORG/MY_REPO:pull_request"
},
"requestMetadata": {
"callerIp": "20.172.43.82",
"callerSuppliedUserAgent": "google-cloud-sdk gcloud/450.0.0 command/gcloud.artifacts.repositories.list invocation-id/81b3609092eb4031a7d5c03adcd1fe79 environment/github-actions-setup-gcloud environment-version/1.1.1 client-os/LINUX client-os-ver/6.2.0 client-pltf-arch/x86_64 interactive/False from-script/False python/3.9.16 term/ (Linux 6.2.0-1012-azure),gzip(gfe)",
"requestAttributes": {
"time": "2023-10-12T11:56:55.782785497Z",
"auth": {}
},
"destinationAttributes": {}
},
"serviceName": "iamcredentials.googleapis.com",
"methodName": "GenerateAccessToken",
"authorizationInfo": [
{
"permission": "iam.serviceAccounts.getAccessToken",
"resourceAttributes": {}
}
],
"resourceName": "projects/-/serviceAccounts/ID",
"request": {
"@type": "type.googleapis.com/google.iam.credentials.v1.GenerateAccessTokenRequest",
"name": "projects/-/serviceAccounts/MY_SA@MY_PROJECT.iam.gserviceaccount.com"
},
"metadata": {
"identityDelegationChain": [
"projects/-/serviceAccounts/MY_SA@MY_PROJECT.iam.gserviceaccount.com"
]
}
},
"insertId": "1mk7zroe50hgl",
"resource": {
"type": "service_account",
"labels": {
"unique_id": "101851263050728808135",
"email_id": "MY_SA@MY_PROJECT.iam.gserviceaccount.com",
"project_id": "MY_PROJECT"
}
},
"timestamp": "2023-10-12T11:56:55.771815158Z",
"severity": "ERROR",
"logName": "projects/MY_PROJECT/logs/cloudaudit.googleapis.com%2Fdata_access",
"operation": {
"id": "10658336329565734952",
"producer": "iamcredentials.googleapis.com",
"first": true,
"last": true
},
"receiveTimestamp": "2023-10-12T11:56:56.845099618Z"
}
Please let me know if I'm missing anything and thanks in advance for your time.
Best,
Pierre
Hi there @Tutuchan 👋!
Thank you for opening an issue. Our team will triage this as soon as we can. Please take a moment to review the troubleshooting steps which lists common error messages and their resolution steps.
Hi @Tutuchan - thank you for opening an issue. The delegates
option is listing the delegation chain for generating an ID token and/or signing a JWT. It's specifically for doing the auth handshake. If you want to repeatedly impersonate a service account for all future calls, you need to pass in the gcloud flag or API parameter. Delegation is not a persistent option.
Hi @sethvargo , thanks for clarifying that, that makes a lot more sense now.
I'll close this issue, thank you !