Search code examples
google-cloud-platformgithub-actionsworkload-identity

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"
}

Solution

  • 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.