Aseem
Aseem

Reputation: 6787

In Github action authenticate docker through workload identity GCP

I was able to authenticate GHA through Workload Identity federation (WIF) successfully

steps:
  - name: git checkout
    uses: actions/checkout@v3

  - id: auth
    name: Authenticate to Google Cloud with Federation
    uses: 'google-github-actions/auth@v1'
    with:
      workload_identity_provider: 'projects/11111/locations/global/workloadIdentityPools/gha-identity-pool-2/providers/gha-identity-pool-provider'
      service_account: '[email protected]'

But when I try to run docker compose service which needs GCP authentication, I get error:

google.auth.exceptions.RefreshError: ('Unable to acquire impersonated credentials: 
No access token or invalid expiration in response.', 
'{\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')

WIF cred file format:

{
    "type": "external_account",
    "audience": "//iam.google.apis.com/projects/PROJECT_NUMBER

/locations/global/workloadIdentityPools/cloudrun-oidc-pool/subject/USER_EMAIL

",
    "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
    "token_url": "https://sts.googleapis.com/v1/token",
    "credential_source": {
        "file" "token.txt" }
}

sv account key cred file format

{
  "type": "service_account",
  "project_id": "abc",
  "private_key_id": "9b173d1620d4fdf9d348d74a9d33848b39b3f117",
  "private_key": "-----BEGIN PRIVATE KEY-----aoisjd\n-----END PRIVATE KEY-----\n",
  "client_email": "[email protected]",
  "client_id": "29384u23",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/yx",
  "universe_domain": "googleapis.com"
}
GOOGLE_APPLICATION_CREDENTIALS: ${{steps.auth.outputs.credentials_file_path}}

This works with service account key authentication. doesnt work with WIF. Because both cred files have different format

My sv account has serviceAccountTokenCreator role. I also tried giving it owner role just to see if lack of role was the issue, but even then I received same error.

Terraform code to create WIF:

resource "google_iam_workload_identity_pool" "gha-identity-pool" {
  workload_identity_pool_id = "gha-identity-pool-2"
}


resource "google_iam_workload_identity_pool_provider" "gha-identity-pool-provider" {
  workload_identity_pool_id          = google_iam_workload_identity_pool.gha-identity-pool.workload_identity_pool_id
  workload_identity_pool_provider_id = "gha-identity-pool-provider"
  display_name                       = "GHA identity pool provider"
  attribute_mapping                  = {
    "google.subject"       = "assertion.sub"
    "attribute.actor"      = "assertion.actor"
    "attribute.repository" = "assertion.repository"
  }
  oidc {
    issuer_uri = "https://token.actions.githubusercontent.com"
  }
}

data "google_project" "gcp_project" {}


resource "google_service_account_iam_member" "gha-sv-account-wif-iam-member" {
  service_account_id = var.gha_service_account_name
  role               = "roles/iam.workloadIdentityUser"
  member             = "principalSet://iam.googleapis.com/projects/${data.google_project.gcp_project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.gha-identity-pool.workload_identity_pool_id}/attribute.repository/org1/repo1"
}


resource "google_service_account_iam_member" "gha-sv-account-wif-tokencreator-iam-member" {
  service_account_id = var.gha_service_account_name
  role               = "roles/owner"
  member             = "principalSet://iam.googleapis.com/projects/${data.google_project.gcp_project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.gha-identity-pool.workload_identity_pool_id}/attribute.repository/org1/repo1"
}
resource "google_project_iam_member" "wif-owner-iam" {
  project = var.project_id
  role    = "roles/owner"
  member  = "principalSet://iam.googleapis.com/projects/${data.google_project.gcp_project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.gha-identity-pool.workload_identity_pool_id}/attribute.repository/org1/repo1"
}

Upvotes: 1

Views: 1371

Answers (2)

Aseem
Aseem

Reputation: 6787

For authenticating GHA through WIF - use the same GHA code as mentioned in the question. In GHA copy credential file to a location that can be used by docker container. Link - how to create WIF through terraform for particular github repository.

The error I was having in above question was related to my terraform code. I was using wrong repository name.

Upvotes: 1

Hemanth Kumar
Hemanth Kumar

Reputation: 3762

In order to resolve your issue, you can try the below suggested points and let me know.

  • Seems to be you are having issues with service token creation. To create or access a Token you need to grant the permission to impersonation service account iam.serviceAccounts.getAccessToken and Service Account Token Creator role . Try adding above permissions and have a try .
  • Make sure you have the IAM Service Account Credentials API, API enabled in your GCP project first, which then enables the creation of short-lived tokens for service account impersonations.
  • As John Hanley suggested, make sure to add the required permission to correct workload identity. To allow external identities to impersonate a service account, you grant them the Workload Identity User role (roles/iam.workloadIdentityUser) on the service account. You can grant the role to a specific external identity, or to multiple external identities. For more configuration options, see the Workload Identity Federation documentation. As you are using Terraform to automate your infrastructure provisioning, check out the GitHub OIDC Terraform module too.

Upvotes: 0

Related Questions