Skip to content

Commit

Permalink
Add support for Direct Workload Identity auth
Browse files Browse the repository at this point in the history
This adds a new authentication mode, Direct Workload Identity Federation. This new mode permits authenticating to Google Cloud directly using the GitHub Actions OIDC token instead of proxying through a Google Cloud Service Account.
  • Loading branch information
sethvargo committed Nov 25, 2023
1 parent f105ef0 commit a4e714a
Show file tree
Hide file tree
Showing 24 changed files with 2,135 additions and 1,429 deletions.
5 changes: 5 additions & 0 deletions .eslintrc.js
Expand Up @@ -8,4 +8,9 @@ module.exports = {
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
],

// We have many situations where we accept and expect arbitrary JSON payloads.
rules: {
'@typescript-eslint/no-explicit-any': 'off',
},
};
134 changes: 98 additions & 36 deletions .github/workflows/test.yml
Expand Up @@ -48,17 +48,24 @@ jobs:
- name: 'npm test'
run: 'npm run test'

credentials_json:

#
# Direct Workload Identity Federation
#
direct_workload_identity_federation:
if: ${{ github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name }}
name: 'credentials_json'
name: 'direct_workload_identity_federation'
runs-on: '${{ matrix.os }}'
strategy:
fail-fast: false
matrix:
os:
- 'ubuntu-latest'
- 'windows-latest'
- 'macos-latest'
# - 'windows-latest'
# - 'macos-latest'

permissions:
id-token: 'write'

steps:
- uses: 'actions/checkout@v4'
Expand All @@ -74,7 +81,8 @@ jobs:
name: 'auth-default'
uses: './'
with:
credentials_json: '${{ secrets.SERVICE_ACCOUNT_KEY_JSON }}'
project_id: '${{ vars.PROJECT_ID }}'
workload_identity_provider: '${{ vars.WIF_PROVIDER_NAME }}'

- id: 'setup-gcloud'
name: 'setup-gcloud'
Expand All @@ -90,11 +98,74 @@ jobs:
name: 'auth-access-token'
uses: './'
with:
credentials_json: '${{ secrets.SERVICE_ACCOUNT_KEY_JSON }}'
workload_identity_provider: '${{ vars.WIF_PROVIDER_NAME }}'

- id: 'oauth-federated-token'
name: 'oauth-federated-token'
shell: 'bash'
run: |-
curl https://secretmanager.googleapis.com/v1/projects/${{ steps.auth-access-token.outputs.project_id }}/secrets/${{ vars.SECRET_NAME }}/versions/latest:access \
--silent \
--show-error \
--fail \
--header "Authorization: Bearer ${{ steps.auth-access-token.outputs.token }}"
#
# Workload Identity Federation through a Service Account
#
workload_identity_federation_through_service_account:
if: ${{ github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name }}
name: 'workload_identity_federation_through_service_account'
runs-on: '${{ matrix.os }}'
strategy:
fail-fast: false
matrix:
os:
- 'ubuntu-latest'
# - 'windows-latest'
# - 'macos-latest'

permissions:
id-token: 'write'

steps:
- uses: 'actions/checkout@v4'

- uses: 'actions/setup-node@v4'
with:
node-version: '20.x'

- name: 'npm build'
run: 'npm ci && npm run build'

- id: 'auth-default'
name: 'auth-default'
uses: './'
with:
workload_identity_provider: '${{ vars.WIF_PROVIDER_NAME }}'
service_account: '${{ vars.SERVICE_ACCOUNT_EMAIL }}'

- id: 'setup-gcloud'
name: 'setup-gcloud'
uses: 'google-github-actions/setup-gcloud@main'

- id: 'gcloud'
name: 'gcloud'
shell: 'bash'
run: |-
gcloud secrets versions access "latest" --secret "${{ vars.SECRET_NAME }}"
- id: 'auth-access-token'
name: 'auth-access-token'
uses: './'
with:
workload_identity_provider: '${{ vars.WIF_PROVIDER_NAME }}'
service_account: '${{ vars.SERVICE_ACCOUNT_EMAIL }}'
token_format: 'access_token'

- id: 'access-token'
name: 'access-token'
- id: 'oauth-token'
name: 'oauth-token'
shell: 'bash'
run: |-
curl https://secretmanager.googleapis.com/v1/projects/${{ steps.auth-access-token.outputs.project_id }}/secrets/${{ vars.SECRET_NAME }}/versions/latest:access \
Expand All @@ -103,38 +174,31 @@ jobs:
--fail \
--header "Authorization: Bearer ${{ steps.auth-access-token.outputs.access_token }}"
- id: 'auth-id-token'
name: 'auth-id-token'
- id: 'oidc-token'
name: 'oidc-token'
uses: './'
with:
credentials_json: '${{ secrets.SERVICE_ACCOUNT_KEY_JSON }}'
workload_identity_provider: '${{ vars.WIF_PROVIDER_NAME }}'
service_account: '${{ vars.SERVICE_ACCOUNT_EMAIL }}'
token_format: 'id_token'
id_token_audience: 'https://secretmanager.googleapis.com/'
id_token_include_email: true

- id: 'auth-sa-retries'
name: 'auth-sa-retries'
uses: './'
with:
retries: '2'
backoff: '200'
backoff_limit: '1000'
credentials_json: '${{ secrets.SERVICE_ACCOUNT_KEY_JSON }}'

workload_identity_federation:
#
# Service Account Key JSON
#
credentials_json:
if: ${{ github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name }}
name: 'workload_identity_federation'
name: 'credentials_json'
runs-on: '${{ matrix.os }}'
strategy:
fail-fast: false
matrix:
os:
- 'ubuntu-latest'
- 'windows-latest'
- 'macos-latest'

permissions:
id-token: 'write'
# - 'windows-latest'
# - 'macos-latest'

steps:
- uses: 'actions/checkout@v4'
Expand All @@ -150,8 +214,7 @@ jobs:
name: 'auth-default'
uses: './'
with:
workload_identity_provider: '${{ vars.WIF_PROVIDER_NAME }}'
service_account: '${{ vars.SERVICE_ACCOUNT_EMAIL }}'
credentials_json: '${{ secrets.SERVICE_ACCOUNT_KEY_JSON }}'

- id: 'setup-gcloud'
name: 'setup-gcloud'
Expand All @@ -167,8 +230,7 @@ jobs:
name: 'auth-access-token'
uses: './'
with:
workload_identity_provider: '${{ vars.WIF_PROVIDER_NAME }}'
service_account: '${{ vars.SERVICE_ACCOUNT_EMAIL }}'
credentials_json: '${{ secrets.SERVICE_ACCOUNT_KEY_JSON }}'
token_format: 'access_token'

- id: 'access-token'
Expand All @@ -185,26 +247,26 @@ jobs:
name: 'auth-id-token'
uses: './'
with:
workload_identity_provider: '${{ vars.WIF_PROVIDER_NAME }}'
service_account: '${{ vars.SERVICE_ACCOUNT_EMAIL }}'
credentials_json: '${{ secrets.SERVICE_ACCOUNT_KEY_JSON }}'
token_format: 'id_token'
id_token_audience: 'https://secretmanager.googleapis.com/'
id_token_include_email: true

- id: 'auth-wif-retries'
name: 'auth-wif-retries'
- id: 'auth-sa-retries'
name: 'auth-sa-retries'
uses: './'
with:
retries: '2'
backoff: '200'
backoff_limit: '1000'
workload_identity_provider: '${{ vars.WIF_PROVIDER_NAME }}'
service_account: '${{ vars.SERVICE_ACCOUNT_EMAIL }}'
credentials_json: '${{ secrets.SERVICE_ACCOUNT_KEY_JSON }}'

#
# This test ensures that the GOOGLE_APPLICATION_CREDENTIALS environment
# variable is shared with the container and that the path of the file is on
# the shared filesystem with the container and that the USER for the container
# has permissions to read the file.
#
docker:
if: ${{ github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name }}
name: 'docker'
Expand Down

0 comments on commit a4e714a

Please sign in to comment.