google-github-actions / auth

A GitHub Action for authenticating to Google Cloud.
https://cloud.google.com/iam
Apache License 2.0
958 stars 195 forks source link

Direct Workload Identity Federation readme outdated or missing details for working example #418

Closed jondkelley closed 4 months ago

jondkelley commented 4 months ago

TL;DR

Following (Preferred) Direct Workload Identity Federation it doesn't work failed to access secret "projects/123456123456/secrets/GITHUB_POC_SECRET/versions/latest": permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist).

Expected behavior

Successful behavior.

Observed behavior

Run google-github-actions/get-secretmanager-secrets@v2.1.3

Error: google-github-actions/get-secretmanager-secrets failed with: failed to access secret "projects/123456123456/secrets/GITHUB_POC_SECRET/versions/latest": permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist).

Action YAML

name: Secret Demo
on:
  push:
    branches:
      - main
      - 'release/*'
jobs:
  job_id:
    permissions:
      contents: 'read'  # This is required for actions/checkout
      id-token: 'write' # This is required for requesting the JWT
    runs-on: ubuntu-latest
    steps:
      - name: Authenticate to Google Cloud
        id: 'auth'
        uses: 'google-github-actions/auth@v1'
        with:
          project_id: 'com-org-dev-760a2504'
          workload_identity_provider: 'projects/123456123456/locations/global/workloadIdentityPools/github2/providers/org-github'
          service_account: 'githubactionspoc2-dev@com-org-dev-760a2504.iam.gserviceaccount.com'
      - name: Pull Secrets from Secret Manager
        id: 'secrets'
        uses: google-github-actions/get-secretmanager-secrets@v2.1.3
        with:
          secrets: |-
            pocsecret:projects/123456123456/secrets/GITHUB_POC_SECRET
      - id: 'publish'
        name: Echo Token
        run: |
          echo "Token: ${{ steps.secrets.outputs.pocsecret }}"

Log output

2024-06-14T17:46:42.8831544Z Current runner version: '2.317.0'
2024-06-14T17:46:42.8859705Z ##[group]Operating System
2024-06-14T17:46:42.8860354Z Ubuntu
2024-06-14T17:46:42.8860664Z 22.04.4
2024-06-14T17:46:42.8861101Z LTS
2024-06-14T17:46:42.8861437Z ##[endgroup]
2024-06-14T17:46:42.8861794Z ##[group]Runner Image
2024-06-14T17:46:42.8862286Z Image: ubuntu-22.04
2024-06-14T17:46:42.8862680Z Version: 20240609.1.0
2024-06-14T17:46:42.8863599Z Included Software: https://github.com/actions/runner-images/blob/ubuntu22/20240609.1/images/ubuntu/Ubuntu2204-Readme.md
2024-06-14T17:46:42.8865014Z Image Release: https://github.com/actions/runner-images/releases/tag/ubuntu22%2F20240609.1
2024-06-14T17:46:42.8865828Z ##[endgroup]
2024-06-14T17:46:42.8866200Z ##[group]Runner Image Provisioner
2024-06-14T17:46:42.8866738Z 2.0.370.1
2024-06-14T17:46:42.8867094Z ##[endgroup]
2024-06-14T17:46:42.8867939Z ##[group]GITHUB_TOKEN Permissions
2024-06-14T17:46:42.8869585Z Contents: read
2024-06-14T17:46:42.8869993Z Metadata: read
2024-06-14T17:46:42.8870668Z ##[endgroup]
2024-06-14T17:46:42.8873735Z Secret source: Actions
2024-06-14T17:46:42.8874443Z Prepare workflow directory
2024-06-14T17:46:42.9495702Z Prepare all required actions
2024-06-14T17:46:42.9662231Z Getting action download info
2024-06-14T17:46:43.2716117Z Download action repository 'google-github-actions/auth@v1' (SHA:3a3c4c57d294ef65efaaee4ff17b22fa88dd3c69)
2024-06-14T17:46:43.7859633Z Download action repository 'google-github-actions/get-secretmanager-secrets@v2.1.3' (SHA:dc4a1392bad0fd60aee00bb2097e30ef07a1caae)
2024-06-14T17:46:44.3648697Z Complete job name: job_id
2024-06-14T17:46:44.4608109Z ##[group]Run google-github-actions/auth@v1
2024-06-14T17:46:44.4608606Z with:
2024-06-14T17:46:44.4609074Z   project_id: com-org-dev-760a2504
2024-06-14T17:46:44.4609979Z   workload_identity_provider: projects/123456123456/locations/global/workloadIdentityPools/github2/providers/org-github
2024-06-14T17:46:44.4611006Z   service_account: githubactionspoc2-dev@com-org-dev-760a2504.iam.gserviceaccount.com
2024-06-14T17:46:44.4611798Z   create_credentials_file: true
2024-06-14T17:46:44.4612203Z   export_environment_variables: true
2024-06-14T17:46:44.4612678Z   cleanup_credentials: true
2024-06-14T17:46:44.4613047Z   access_token_lifetime: 3600s
2024-06-14T17:46:44.4613566Z   access_token_scopes: https://www.googleapis.com/auth/cloud-platform
2024-06-14T17:46:44.4614192Z   retries: 3
2024-06-14T17:46:44.4614489Z   backoff: 250
2024-06-14T17:46:44.4614819Z   id_token_include_email: false
2024-06-14T17:46:44.4615280Z ##[endgroup]
2024-06-14T17:46:45.0280129Z ##[warning]The "create_credentials_file" option is true, but the current GitHub workspace is empty. Did you forget to use "actions/checkout" before this step? If you do not intend to share authentication with future steps in this job, set "create_credentials_file" to false.
2024-06-14T17:46:45.0292754Z Created credentials file at "/home/runner/work/citest-python/citest-python/gha-creds-a526d62f0f94404b.json"
2024-06-14T17:46:45.0600335Z ##[group]Run google-github-actions/get-secretmanager-secrets@v2.1.3
2024-06-14T17:46:45.0600978Z with:
2024-06-14T17:46:45.0601539Z   secrets: pocsecret:projects/123456123456/secrets/GITHUB_POC_SECRET
2024-06-14T17:46:45.0602069Z   min_mask_length: 4
2024-06-14T17:46:45.0602397Z   export_to_environment: false
2024-06-14T17:46:45.0602873Z   encoding: utf8
2024-06-14T17:46:45.0603200Z env:
2024-06-14T17:46:45.0603941Z   CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE: /home/runner/work/citest-python/citest-python/gha-creds-a526d62f0f94404b.json
2024-06-14T17:46:45.0604996Z   GOOGLE_APPLICATION_CREDENTIALS: /home/runner/work/citest-python/citest-python/gha-creds-a526d62f0f94404b.json
2024-06-14T17:46:45.0605975Z   GOOGLE_GHA_CREDS_PATH: /home/runner/work/citest-python/citest-python/gha-creds-a526d62f0f94404b.json
2024-06-14T17:46:45.0606779Z   CLOUDSDK_CORE_PROJECT: com-org-dev-760a2504
2024-06-14T17:46:45.0607346Z   CLOUDSDK_PROJECT: com-org-dev-760a2504
2024-06-14T17:46:45.0607913Z   GCLOUD_PROJECT: com-org-dev-760a2504
2024-06-14T17:46:45.0608741Z   GCP_PROJECT: com-org-dev-760a2504
2024-06-14T17:46:45.0609217Z   GOOGLE_CLOUD_PROJECT: com-org-dev-760a2504
2024-06-14T17:46:45.0609647Z ##[endgroup]
2024-06-14T17:46:45.8364362Z ##[error]google-github-actions/get-secretmanager-secrets failed with: failed to access secret "projects/123456123456/secrets/GITHUB_POC_SECRET/versions/latest": permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist).
2024-06-14T17:46:45.8512806Z Post job cleanup.
2024-06-14T17:46:45.9409621Z Removed exported credentials at "/home/runner/work/citest-python/citest-python/gha-creds-a526d62f0f94404b.json".
2024-06-14T17:46:46.0103758Z Cleaning up orphan processes

Additional information

Direct Workload Identity Federation requires additional permissions, not sure what is missing.

IAM Logs { "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/123456123456/locations/global/workloadIdentityPools/github2/subject/repo:org/citest-python:ref:refs/heads/main" }, "requestMetadata": { "callerIp": "40.79.245.146", "callerSuppliedUserAgent": "google-api-nodejs-client/9.10.0,gzip(gfe)", "requestAttributes": { "time": "2024-06-14T16:10:10.779381134Z", "auth": {} }, "destinationAttributes": {} }, "serviceName": "iamcredentials.googleapis.com", "methodName": "GenerateAccessToken", "authorizationInfo": [ { "permission": "iam.serviceAccounts.getAccessToken", "resourceAttributes": {}, "permissionType": "ADMIN_READ" } ], "resourceName": "projects/-/serviceAccounts/113057325249898657053", "request": { "name": "projects/-/serviceAccounts/githubactionspoc2-dev@com-org-dev-760a2504.iam.gserviceaccount.com", "@type": "type.googleapis.com/google.iam.credentials.v1.GenerateAccessTokenRequest" }, "metadata": { "identityDelegationChain": [ "projects/-/serviceAccounts/githubactionspoc2-dev@com-org-dev-760a2504.iam.gserviceaccount.com" ] } }, "insertId": "chid3oe15e1a", "resource": { "type": "service_account", "labels": { "email_id": "githubactionspoc2-dev@com-org-dev-760a2504.iam.gserviceaccount.com", "project_id": "com-org-dev-760a2504", "unique_id": "113057325249898657053" } }, "timestamp": "2024-06-14T16:10:10.764276225Z", "severity": "ERROR", "logName": "projects/com-org-dev-760a2504/logs/cloudaudit.googleapis.com%2Fdata_access", "operation": { "id": "13097961325791772796", "producer": "iamcredentials.googleapis.com", "first": true, "last": true }, "receiveTimestamp": "2024-06-14T16:10:11.571327922Z" }

How to reproduce

Environment Variables Used

export PROJECT_ID=com-org-dev-760a2504
export SVC_ACC=githubactionspoc2-dev
export IDENTITY_POOL=github2
export IDENTITY_PROVIDER=org-github

Step 1: Create a Service Account

This command creates a new service account with the name specified by the SVC_ACC environment variable in the project specified by the PROJECT_ID environment variable.

Create Service Account gcloud iam service-accounts create "$SVC_ACC" \ --project "${PROJECT_ID}"

Step 2: Create a Workload Identity Pool

This command creates a new Workload Identity Pool named github2 with a display name GitHub Actions Pool in the specified project.

Create Workload Identity Pool gcloud iam workload-identity-pools create "$IDENTITY_POOL" \ --project="${PROJECT_ID}" \ --location="global" \ --display-name="GitHub Actions Pool"

Step 3: Describe the Workload Identity Pool

This command retrieves the name of the Workload Identity Pool named github in the specified project and outputs its value.

Describe Workload Identity Pool gcloud iam workload-identity-pools describe "$IDENTITY_POOL" \ --project="${PROJECT_ID}" \ --location="global" \ --format="value(name)" Gives me projects/123456123456/locations/global/workloadIdentityPools/github2

Step 4: Create an OIDC Provider

This command creates an OIDC provider within the specified Workload Identity Pool, mapping specific attributes from the GitHub OIDC token and setting an attribute condition for the repository owner.

Create OIDC Provider gcloud iam workload-identity-pools providers create-oidc "$IDENTITY_PROVIDER" \ --project="${PROJECT_ID}" \ --location="global" \ --workload-identity-pool="$IDENTITY_POOL" \ --display-name="My GitHub repo Provider" \ --attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.repository=assertion.repository,attribute.repository_owner=assertion.repository_owner" \ --attribute-condition="assertion.repository_owner == 'myorg_in_github'" \ --issuer-uri="https://token.actions.githubusercontent.com"

Step 5: Describe the OIDC Provider

This command retrieves the name of the OIDC provider created in the previous step and outputs its value.

Describe OIDC Provider gcloud iam workload-identity-pools providers describe "$IDENTITY_PROVIDER" \ --project="${PROJECT_ID}" \ --location="global" \ --workload-identity-pool="$IDENTITY_POOL" \ --format="value(name)" Gives me projects/123456123456/locations/global/workloadIdentityPools/github2/providers/org-github

Step 6: Add IAM Policy Binding for Secret Access

These commands add IAM policy bindings to allow specific principals to access a secret in Google Secret Manager. The principals are identified by their attributes in the Workload Identity Pool.

Add IAM Policy Binding for Secret Access - Attempt 1 gcloud secrets add-iam-policy-binding "GITHUB_POC_SECRET" \ --project="${PROJECT_ID}" \ --role="roles/secretmanager.secretAccessor" \ --member="principalSet://iam.googleapis.com/projects/123456123456/locations/global/workloadIdentityPools/github2/attribute.repository_owner/my-github-org-name"
Add IAM Policy Binding for Secret Access - Attempt 2 gcloud secrets add-iam-policy-binding "GITHUB_POC_SECRET" \ --project="${PROJECT_ID}" \ --role="roles/secretmanager.secretAccessor" \ --member="principalSet://iam.googleapis.com/projects/123456123456/locations/global/workloadIdentityPools/github2/attribute.repository/my-github-org-name/citest-python"
Add IAM Policy Binding for Secret Access - Attempt 3 gcloud secrets add-iam-policy-binding "GITHUB_POC_SECRET" \ --project="${PROJECT_ID}" \ --role="roles/secretmanager.secretAccessor" \ --member="principalSet://iam.googleapis.com/projects/123456123456/locations/global/workloadIdentityPools/github2/attribute.repository/citest-python"

Step 7: Try and fix the iam.serviceAccounts.getAccessToken error

Allow a service account to impersonate another service account, enabling actions that require specific permissions.

Add IAM Policy Binding to Project gcloud projects add-iam-policy-binding com-org-dev-760a2504 \ --member="serviceAccount:githubactionspoc2-dev@com-org-dev-760a2504.iam.gserviceaccount.com" \ --role="roles/iam.serviceAccountTokenCreator"

So far, nothing has worked. :(

github-actions[bot] commented 4 months ago

Hi there @jondkelley :wave:!

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.

sethvargo commented 4 months ago

Before trying to debug further, can you please make sure you're using the correct version of "auth"? All the examples in the readme are v2, but you're using v1:

- uses: 'google-github-actions/auth@v1'
+ uses: 'google-github-actions/auth@v2'
jondkelley commented 4 months ago

Added

-        uses: 'google-github-actions/auth@v1'
+        uses: 'google-github-actions/auth@v2'

still getting the same error. :(

sethvargo commented 4 months ago

I think you're conflating the steps of "Direct Workload Identity Federation" and "Workload Identity Federation through a Service Account". If you're using Direct WIF, then you need to grant the WIF pool permissions on the secret. If you're using WIF via SA, you must grant the SA permissions on the secret.

It looks like you followed the setup instructions for Direct WIF, but then you're telling the auth action to use the WIF via SA method. You need to remove the service_account input:

      - name: Authenticate to Google Cloud
        id: 'auth'
        uses: 'google-github-actions/auth@v2'
        with:
          project_id: 'com-org-dev-760a2504'
          workload_identity_provider: 'projects/123456123456/locations/global/workloadIdentityPools/github2/providers/org-github'
-         service_account: 'githubactionspoc2-dev@com-org-dev-760a2504.iam.gserviceaccount.com'

As explained in the README:

Image