Skip to content
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

Support authentication with external_account with Workload Identity Federation #606

Open
alexeyinkin opened this issue Mar 21, 2024 · 0 comments

Comments

@alexeyinkin
Copy link

alexeyinkin commented Mar 21, 2024

I try to run an app from a GitHub workflow. It needs to communicate with Google Cloud. The workflow uses Workload Identity Federation to authenticate. It produces a key of the type external_account while googleapis_auth currently only handles the type service_account.

Given that Workflow Identity Federation is the recommended way to access Google Cloud resources, I think this should be fixed.

Steps to Reproduce

1. Create a project and configure Workload Identity Federation:

export PROJECT='my-project-id'
export ORGANIZATION='my-organization-id'
export GITHUB_USERNAME='my-github-username'
export REPO='my-github-repo'

gcloud projects create $PROJECT --name=$PROJECT --organization=$ORGANIZATION
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT --format='value(projectNumber)')

gcloud services enable cloudbilling.googleapis.com --project=$PROJECT
gcloud services enable iam.googleapis.com --project=$PROJECT
gcloud iam service-accounts create "testing" --project=$PROJECT

gcloud projects add-iam-policy-binding $PROJECT \
  --member="serviceAccount:testing@$PROJECT.iam.gserviceaccount.com" \
  --role="roles/owner" \
  --project=$PROJECT

gcloud iam workload-identity-pools create "github" --location="global" --project=$PROJECT

gcloud iam \
  workload-identity-pools providers create-oidc "github" \
  --attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository" \
  --issuer-uri="https://token.actions.githubusercontent.com" \
  --location="global" \
  --workload-identity-pool="github" \
  --project=$PROJECT

gcloud projects add-iam-policy-binding $PROJECT \
  --member="principalSet://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/github/attribute.repository/$GITHUB_USERNAME/$REPO" \
  --role="roles/viewer" \
  --project=$PROJECT

2. Create a Dart app

pubspec.yaml:

name: test1
publish_to: none

environment:
  sdk: ^3.2.2

dependencies:
  googleapis_auth: ^1.4.1

main.dart:

import 'dart:io';

import 'package:googleapis_auth/auth_io.dart';

Future<void> main() async {
  print(File(Platform.environment['GOOGLE_APPLICATION_CREDENTIALS']!).readAsStringSync());
  await clientViaApplicationDefaultCredentials(scopes: []);
}

3. Set up the workflow

Create the repository variables: PROJECT_NAME, PROJECT_NUMBER.

The workflow:

on:
  - workflow_dispatch

jobs:
  test:
    permissions:
      id-token: write

    runs-on: ubuntu-latest
    steps:

      - uses: actions/checkout@v4

      - uses: 'google-github-actions/auth@v2.1.2'
        with:
          workload_identity_provider: 'projects/${{ vars.PROJECT_NUMBER }}/locations/global/workloadIdentityPools/github/providers/github'
          service_account: 'testing@${{ vars.PROJECT_NAME }}.iam.gserviceaccount.com'

      - uses: dart-lang/setup-dart@v1
        with:
          sdk: 3.3.2

      - name: 'Test'
        run: |
          dart pub get
          dart main.dart

4. Run the workflow

Expected

No error

Actual

Run dart pub get
  dart pub get
  dart main.dart
  shell: /usr/bin/bash -e {0}
  env:
    CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE: /home/runner/work/my-github-repo/my-github-repo/gha-creds-5647adab863c00a9.json
    GOOGLE_APPLICATION_CREDENTIALS: /home/runner/work/my-github-repo/my-github-repo/gha-creds-5647adab863c00a9.json
    GOOGLE_GHA_CREDS_PATH: /home/runner/work/my-github-repo/my-github-repo/gha-creds-5647adab863c00a9.json
    CLOUDSDK_CORE_PROJECT: my-project-id
    CLOUDSDK_PROJECT: my-project-id
    GCLOUD_PROJECT: my-project-id
    GCP_PROJECT: my-project-id
    GOOGLE_CLOUD_PROJECT: my-project-id
    DART_HOME: /opt/hostedtoolcache/dart/3.3.2/x64
    PUB_CACHE: /home/runner/.pub-cache
    PUB_TOKEN: ***
Resolving dependencies...
+ args 2.4.2
+ async 2.11.0
+ collection 1.18.0
+ crypto 3.0.3
+ google_identity_services_web 0.3.1+1
+ googleapis_auth 1.5.0
+ http 1.2.1
+ http_parser 4.0.2
+ meta 1.12.0
+ path 1.9.0
+ source_span 1.10.0
+ string_scanner 1.2.0
+ term_glyph 1.2.1
+ typed_data 1.3.2
+ web 0.5.1
Changed 15 dependencies!
{"type":"external_account","audience":"//iam.googleapis.com/projects/my-project-number/locations/global/workloadIdentityPools/github/providers/github","subject_token_type":"urn:ietf:params:oauth:token-type:jwt","token_url":"https://sts.googleapis.com/v1/token","credential_source":{"url":"https://pipelinesghubeus14.actions.githubusercontent.com/***/00000000-0000-0000-0000-000000000000/_apis/distributedtask/hubs/Actions/plans/***/jobs/5264e576-3c6f-51f6-f055-fab409685f20/idtoken?api-version=2.0&audience=https%3A%2F%2Fiam.googleapis.com%2Fprojects%2Fmy-project-number%2Flocations%2Fglobal%2FworkloadIdentityPools%2Fgithub%2Fproviders%2Fgithub","headers":{"Authorization":"***"},"format":{"type":"json","subject_token_field_name":"value"}},"service_account_impersonation_url":"https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/testing@my-project-id.iam.gserviceaccount.com:generateAccessToken"}
Unhandled exception:
Invalid argument(s): The given credentials are not of type service_account (was: external_account).
#0      new ServiceAccountCredentials.fromJson (package:googleapis_auth/src/service_account_credentials.dart:55:7)
#1      fromApplicationsCredentialsFile (package:googleapis_auth/src/adc_utils.dart:59:31)
<asynchronous suspension>
#2      clientViaApplicationDefaultCredentials (package:googleapis_auth/auth_io.dart:61:12)
<asynchronous suspension>
#3      main (file:///home/runner/work/my-github-repo/my-github-repo/main.dart:7:3)
<asynchronous suspension>
Error: Process completed with exit code 255.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant