mirror of
https://github.com/google-github-actions/auth.git
synced 2026-06-05 19:45:13 +00:00
Compare commits
26 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc2174804b |
||
|
|
0dfce0c0f8 |
||
|
|
7c6bc770da |
||
|
|
42e4997ee3 |
||
|
|
5ea4dc1147 |
||
|
|
c200f3691d |
||
|
|
3a53be7e7c |
||
|
|
b7593ed2ef |
||
|
|
c1ee334b4f |
||
|
|
140bb5113f |
||
|
|
ab3132e2ad |
||
|
|
25b96bac99 |
||
|
|
0920706a19 |
||
|
|
ba79af0395 |
||
|
|
bfaa66bd66 |
||
|
|
d0822ad9bf |
||
|
|
7b53cdc2a3 |
||
|
|
a9cfddf5d2 |
||
|
|
b011f3988e |
||
|
|
71f986410d |
||
|
|
0cd8f2e4e2 |
||
|
|
332e0ba72f |
||
|
|
28d44ba259 |
||
|
|
83354cacbb |
||
|
|
6fc4af4b14 |
||
|
|
212f83afe8 |
18 changed files with 693 additions and 549 deletions
5
.github/actionlint.yml
vendored
Normal file
5
.github/actionlint.yml
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
paths:
|
||||
'**/*.yml':
|
||||
ignore:
|
||||
# https://github.com/rhysd/actionlint/issues/559
|
||||
- 'invalid runner name "node24"'
|
||||
21
.github/workflows/draft-release.yml
vendored
21
.github/workflows/draft-release.yml
vendored
|
|
@ -1,17 +1,3 @@
|
|||
# Copyright 2023 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
name: 'Draft release'
|
||||
|
||||
on:
|
||||
|
|
@ -29,10 +15,11 @@ on:
|
|||
|
||||
jobs:
|
||||
draft-release:
|
||||
name: 'Draft release'
|
||||
uses: 'google-github-actions/.github/.github/workflows/draft-release.yml@v0'
|
||||
uses: 'google-github-actions/.github/.github/workflows/draft-release.yml@v3' # ratchet:exclude
|
||||
permissions:
|
||||
contents: 'read'
|
||||
pull-requests: 'write'
|
||||
with:
|
||||
version_strategy: '${{ github.event.inputs.version_strategy }}'
|
||||
# secrets must be explicitly passed to reusable workflows https://docs.github.com/en/enterprise-cloud@latest/actions/using-workflows/reusing-workflows#using-inputs-and-secrets-in-a-reusable-workflow
|
||||
secrets:
|
||||
ACTIONS_BOT_TOKEN: '${{ secrets.ACTIONS_BOT_TOKEN }}'
|
||||
|
|
|
|||
25
.github/workflows/publish.yml
vendored
Normal file
25
.github/workflows/publish.yml
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
name: 'Publish immutable action version'
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
release:
|
||||
types:
|
||||
- 'published'
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: 'ubuntu-latest'
|
||||
permissions:
|
||||
contents: 'read'
|
||||
id-token: 'write'
|
||||
packages: 'write'
|
||||
|
||||
steps:
|
||||
- name: 'Checkout'
|
||||
uses: 'actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683' # ratchet:actions/checkout@v4
|
||||
|
||||
- name: 'Publish'
|
||||
id: 'publish'
|
||||
uses: 'actions/publish-immutable-action@4bc8754ffc40f27910afb20287dbbbb675a4e978' # ratchet:actions/publish-immutable-action@v0.0.4
|
||||
with:
|
||||
github-token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
25
.github/workflows/release.yml
vendored
25
.github/workflows/release.yml
vendored
|
|
@ -1,17 +1,3 @@
|
|||
# Copyright 2023 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
name: 'Release'
|
||||
|
||||
on:
|
||||
|
|
@ -22,7 +8,10 @@ on:
|
|||
|
||||
jobs:
|
||||
release:
|
||||
if: |-
|
||||
${{ startsWith(github.event.head_commit.message, 'Release: v') }}
|
||||
name: 'Release'
|
||||
uses: 'google-github-actions/.github/.github/workflows/release.yml@v0'
|
||||
uses: 'google-github-actions/.github/.github/workflows/release.yml@v3' # ratchet:exclude
|
||||
permissions:
|
||||
attestations: 'write'
|
||||
contents: 'write'
|
||||
packages: 'write'
|
||||
secrets:
|
||||
ACTIONS_BOT_TOKEN: '${{ secrets.ACTIONS_BOT_TOKEN }}'
|
||||
|
|
|
|||
57
.github/workflows/test.yml
vendored
57
.github/workflows/test.yml
vendored
|
|
@ -29,6 +29,10 @@ concurrency:
|
|||
group: '${{ github.workflow }}-${{ github.head_ref || github.ref }}'
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: 'read'
|
||||
statuses: 'write'
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: 'bash'
|
||||
|
|
@ -39,18 +43,15 @@ jobs:
|
|||
runs-on: 'ubuntu-latest'
|
||||
|
||||
steps:
|
||||
- uses: 'actions/checkout@v4'
|
||||
- uses: 'actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683' # ratchet:actions/checkout@v4
|
||||
|
||||
- uses: 'actions/setup-node@v4'
|
||||
- uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20.x'
|
||||
node-version-file: 'package.json'
|
||||
|
||||
- name: 'npm build'
|
||||
run: 'npm ci && npm run build'
|
||||
|
||||
- name: 'npm lint'
|
||||
run: 'npm run lint'
|
||||
|
||||
- name: 'npm test'
|
||||
run: 'npm run test'
|
||||
|
||||
|
|
@ -59,7 +60,8 @@ jobs:
|
|||
# Direct Workload Identity Federation
|
||||
#
|
||||
direct_workload_identity_federation:
|
||||
if: ${{ github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name }}
|
||||
if: |-
|
||||
${{ github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name }}
|
||||
name: 'direct_workload_identity_federation'
|
||||
runs-on: '${{ matrix.os }}'
|
||||
strategy:
|
||||
|
|
@ -74,11 +76,11 @@ jobs:
|
|||
id-token: 'write'
|
||||
|
||||
steps:
|
||||
- uses: 'actions/checkout@v4'
|
||||
- uses: 'actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683' # ratchet:actions/checkout@v4
|
||||
|
||||
- uses: 'actions/setup-node@v4'
|
||||
- uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20.x'
|
||||
node-version-file: 'package.json'
|
||||
|
||||
- name: 'npm build'
|
||||
run: 'npm ci && npm run build'
|
||||
|
|
@ -99,7 +101,7 @@ jobs:
|
|||
--fail \
|
||||
--header "Authorization: Bearer ${{ steps.auth-default.outputs.auth_token }}"
|
||||
|
||||
- uses: 'google-github-actions/setup-gcloud@v2'
|
||||
- uses: 'google-github-actions/setup-gcloud@main' # ratchet:exclude
|
||||
with:
|
||||
version: '>= 363.0.0'
|
||||
|
||||
|
|
@ -112,7 +114,8 @@ jobs:
|
|||
# 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 }}
|
||||
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:
|
||||
|
|
@ -127,11 +130,11 @@ jobs:
|
|||
id-token: 'write'
|
||||
|
||||
steps:
|
||||
- uses: 'actions/checkout@v4'
|
||||
- uses: 'actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683' # ratchet:actions/checkout@v4
|
||||
|
||||
- uses: 'actions/setup-node@v4'
|
||||
- uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20.x'
|
||||
node-version-file: 'package.json'
|
||||
|
||||
- name: 'npm build'
|
||||
run: 'npm ci && npm run build'
|
||||
|
|
@ -143,7 +146,7 @@ jobs:
|
|||
workload_identity_provider: '${{ vars.WIF_PROVIDER_NAME }}'
|
||||
service_account: '${{ vars.SERVICE_ACCOUNT_EMAIL }}'
|
||||
|
||||
- uses: 'google-github-actions/setup-gcloud@v2'
|
||||
- uses: 'google-github-actions/setup-gcloud@main' # ratchet:exclude
|
||||
with:
|
||||
version: '>= 363.0.0'
|
||||
|
||||
|
|
@ -183,7 +186,8 @@ jobs:
|
|||
# Service Account Key JSON
|
||||
#
|
||||
credentials_json:
|
||||
if: ${{ github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name }}
|
||||
if: |-
|
||||
${{ github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name }}
|
||||
name: 'credentials_json'
|
||||
runs-on: '${{ matrix.os }}'
|
||||
strategy:
|
||||
|
|
@ -195,11 +199,11 @@ jobs:
|
|||
- 'macos-latest'
|
||||
|
||||
steps:
|
||||
- uses: 'actions/checkout@v4'
|
||||
- uses: 'actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683' # ratchet:actions/checkout@v4
|
||||
|
||||
- uses: 'actions/setup-node@v4'
|
||||
- uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20.x'
|
||||
node-version-file: 'package.json'
|
||||
|
||||
- name: 'npm build'
|
||||
run: 'npm ci && npm run build'
|
||||
|
|
@ -210,7 +214,7 @@ jobs:
|
|||
with:
|
||||
credentials_json: '${{ secrets.SERVICE_ACCOUNT_KEY_JSON }}'
|
||||
|
||||
- uses: 'google-github-actions/setup-gcloud@v2'
|
||||
- uses: 'google-github-actions/setup-gcloud@main' # ratchet:exclude
|
||||
with:
|
||||
version: '>= 363.0.0'
|
||||
|
||||
|
|
@ -250,17 +254,18 @@ jobs:
|
|||
# has permissions to read the file.
|
||||
#
|
||||
docker:
|
||||
if: ${{ github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name }}
|
||||
if: |-
|
||||
${{ github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name }}
|
||||
name: 'docker'
|
||||
runs-on: 'ubuntu-latest'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: 'actions/checkout@v4'
|
||||
- uses: 'actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683' # ratchet:actions/checkout@v4
|
||||
|
||||
- uses: 'actions/setup-node@v4'
|
||||
- uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20.x'
|
||||
node-version-file: 'package.json'
|
||||
|
||||
- name: 'npm build'
|
||||
run: 'npm ci && npm run build'
|
||||
|
|
@ -271,7 +276,7 @@ jobs:
|
|||
credentials_json: '${{ secrets.SERVICE_ACCOUNT_KEY_JSON }}'
|
||||
|
||||
- name: 'docker'
|
||||
uses: 'docker://alpine:3'
|
||||
uses: 'docker://index.docker.io/library/alpine@sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1' # ratchet:docker://alpine:3
|
||||
with:
|
||||
entrypoint: '/bin/sh'
|
||||
args: '-euc "test -n "${GOOGLE_APPLICATION_CREDENTIALS}" && test -r "${GOOGLE_APPLICATION_CREDENTIALS}"'
|
||||
|
|
|
|||
2
.github/workflows/troubleshooting.yml
vendored
2
.github/workflows/troubleshooting.yml
vendored
|
|
@ -27,7 +27,7 @@ jobs:
|
|||
runs-on: 'ubuntu-latest'
|
||||
|
||||
steps:
|
||||
- uses: 'actions/github-script@v7'
|
||||
- uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea' # ratchet:actions/github-script@v7
|
||||
with:
|
||||
script: |-
|
||||
const msg =
|
||||
|
|
|
|||
22
README.md
22
README.md
|
|
@ -39,7 +39,7 @@ support](https://cloud.google.com/support).**
|
|||
gha-creds-*.json
|
||||
```
|
||||
|
||||
- This action runs using Node 20. Use a [runner
|
||||
- This action runs using Node 24. Use a [runner
|
||||
version](https://github.com/actions/virtual-environments) that supports this
|
||||
version of Node or newer.
|
||||
|
||||
|
|
@ -49,6 +49,9 @@ support](https://cloud.google.com/support).**
|
|||
```yaml
|
||||
jobs:
|
||||
job_id:
|
||||
# Any runner supporting Node 20 or newer
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
# Add "id-token" with the intended permissions.
|
||||
permissions:
|
||||
contents: 'read'
|
||||
|
|
@ -57,7 +60,7 @@ jobs:
|
|||
steps:
|
||||
- uses: 'actions/checkout@v4'
|
||||
|
||||
- uses: 'google-github-actions/auth@v2'
|
||||
- uses: 'google-github-actions/auth@v3'
|
||||
with:
|
||||
project_id: 'my-project'
|
||||
workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider'
|
||||
|
|
@ -81,6 +84,12 @@ For more usage options, see the [examples](docs/EXAMPLES.md).
|
|||
> SDK](https://github.com/firebase/firebase-admin-node/issues/1377). Use Service
|
||||
> Account Key JSON authentication instead.
|
||||
|
||||
> [!WARNING]
|
||||
>
|
||||
> As of the time of this writing, the GitHub OIDC token expires in 5 minutes,
|
||||
> which means any derived credentials also expire in 5 minutes.
|
||||
|
||||
|
||||
The following inputs are for _authenticating_ to Google Cloud via Workload
|
||||
Identity Federation.
|
||||
|
||||
|
|
@ -240,7 +249,7 @@ regardless of the authentication mechanism.
|
|||
job_id:
|
||||
steps:
|
||||
- uses: 'actions/checkout@v4' # Must come first!
|
||||
- uses: 'google-github-actions/auth@v2'
|
||||
- uses: 'google-github-actions/auth@v3'
|
||||
```
|
||||
|
||||
- `export_environment_variables`: (Optional) If true, the action will export
|
||||
|
|
@ -313,7 +322,6 @@ regardless of the authentication mechanism.
|
|||
"token_format" is "id_token".
|
||||
|
||||
|
||||
|
||||
<a id="setup"></a>
|
||||
## Setup
|
||||
|
||||
|
|
@ -426,7 +434,7 @@ These instructions use the [gcloud][gcloud] command-line tool.
|
|||
Actions YAML:
|
||||
|
||||
```yaml
|
||||
- uses: 'google-github-actions/auth@v2'
|
||||
- uses: 'google-github-actions/auth@v3'
|
||||
with:
|
||||
project_id: 'my-project'
|
||||
workload_identity_provider: '...' # "projects/123456789/locations/global/workloadIdentityPools/github/providers/my-repo"
|
||||
|
|
@ -590,7 +598,7 @@ These instructions use the [gcloud][gcloud] command-line tool.
|
|||
Actions YAML:
|
||||
|
||||
```yaml
|
||||
- uses: 'google-github-actions/auth@v2'
|
||||
- uses: 'google-github-actions/auth@v3'
|
||||
with:
|
||||
service_account: '...' # my-service-account@my-project.iam.gserviceaccount.com
|
||||
workload_identity_provider: '...' # "projects/123456789/locations/global/workloadIdentityPools/github/providers/my-repo"
|
||||
|
|
@ -659,7 +667,7 @@ These instructions use the [gcloud][gcloud] command-line tool.
|
|||
the GitHub Actions YAML:
|
||||
|
||||
```yaml
|
||||
- uses: 'google-github-actions/auth@v2'
|
||||
- uses: 'google-github-actions/auth@v3'
|
||||
with:
|
||||
credentials_json: '${{ secrets.GOOGLE_CREDENTIALS }}' # Replace with the name of your GitHub Actions secret
|
||||
```
|
||||
|
|
|
|||
34
action.yml
34
action.yml
|
|
@ -56,7 +56,7 @@ inputs:
|
|||
description: |-
|
||||
If true, the action will securely generate a credentials file which can be
|
||||
used for authentication via gcloud and Google Cloud SDKs.
|
||||
default: true
|
||||
default: 'true'
|
||||
required: false
|
||||
export_environment_variables:
|
||||
description: |-
|
||||
|
|
@ -79,7 +79,7 @@ inputs:
|
|||
If false, the action will not export any environment variables, meaning
|
||||
future steps are unlikely to be automatically authenticated to Google
|
||||
Cloud.
|
||||
default: true
|
||||
default: 'true'
|
||||
required: false
|
||||
token_format:
|
||||
description: |-
|
||||
|
|
@ -113,7 +113,7 @@ inputs:
|
|||
If true, the action will remove any created credentials from the
|
||||
filesystem upon completion. This only applies if "create_credentials_file"
|
||||
is true.
|
||||
default: true
|
||||
default: 'true'
|
||||
required: false
|
||||
|
||||
# access token params
|
||||
|
|
@ -138,30 +138,6 @@ inputs:
|
|||
default: ''
|
||||
required: false
|
||||
|
||||
# retries - TODO - remove in v3.0
|
||||
retries:
|
||||
description: |-
|
||||
Number of times to retry a failed authentication attempt. This is useful
|
||||
for automated pipelines that may execute before IAM permissions are fully
|
||||
propagated.
|
||||
deprecationMessage: |-
|
||||
This field is no longer used and will be removed in a future release.
|
||||
required: false
|
||||
backoff:
|
||||
description: |-
|
||||
Delay time before trying another authentication attempt. This is
|
||||
implemented using a fibonacci backoff method (e.g. 1-1-2-3-5). The default
|
||||
value is 250 milliseconds.
|
||||
deprecationMessage: |-
|
||||
This field is no longer used and will be removed in a future release.
|
||||
required: false
|
||||
backoff_limit:
|
||||
description: |-
|
||||
Limits the retry backoff to the specified value.
|
||||
deprecationMessage: |-
|
||||
This field is no longer used and will be removed in a future release.
|
||||
required: false
|
||||
|
||||
# id token params
|
||||
id_token_audience:
|
||||
description: |-
|
||||
|
|
@ -175,7 +151,7 @@ inputs:
|
|||
generated token. If true, the token will contain "email" and
|
||||
"email_verified" claims. This is only valid when "token_format" is
|
||||
"id_token".
|
||||
default: false
|
||||
default: 'false'
|
||||
required: false
|
||||
|
||||
outputs:
|
||||
|
|
@ -204,6 +180,6 @@ branding:
|
|||
color: 'blue'
|
||||
|
||||
runs:
|
||||
using: 'node20'
|
||||
using: 'node24'
|
||||
main: 'dist/main/index.js'
|
||||
post: 'dist/post/index.js'
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
set -eEuo pipefail
|
||||
|
||||
#
|
||||
# As of Node 20, the --test parameter does not support globbing, and it does not
|
||||
# support variable Windows paths. We also cannot invoke the test runner
|
||||
# directly, because while it has an API, there's no way to force it to transpile
|
||||
# the Typescript into JavaScript before passing it to the runner.
|
||||
#
|
||||
# So we're left with this solution, which shells out to Node to list all files
|
||||
# that end in *.test.ts (excluding node_modules/), and then execs out to that
|
||||
# process. We have to exec so the stderr/stdout and exit code is appropriately
|
||||
# fed to the caller.
|
||||
#
|
||||
|
||||
FILES="$(node -e "process.stdout.write(require('node:fs').readdirSync('./', { recursive: true }).filter((e) => {return e.endsWith('.test.ts') && !e.startsWith('node_modules');}).sort().join(' '));")"
|
||||
|
||||
set -x
|
||||
exec node --require ts-node/register --test-reporter spec --test ${FILES}
|
||||
6
dist/main/index.js
vendored
6
dist/main/index.js
vendored
File diff suppressed because one or more lines are too long
6
dist/post/index.js
vendored
6
dist/post/index.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -20,7 +20,7 @@ jobs:
|
|||
id-token: 'write'
|
||||
|
||||
- id: 'auth'
|
||||
uses: 'google-github-actions/auth@v2'
|
||||
uses: 'google-github-actions/auth@v3'
|
||||
with:
|
||||
project_id: 'my-project'
|
||||
workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider'
|
||||
|
|
@ -45,7 +45,7 @@ jobs:
|
|||
contents: 'read'
|
||||
id-token: 'write'
|
||||
|
||||
- uses: 'google-github-actions/auth@v2'
|
||||
- uses: 'google-github-actions/auth@v3'
|
||||
with:
|
||||
project_id: 'my-project'
|
||||
workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider'
|
||||
|
|
@ -56,7 +56,7 @@ jobs:
|
|||
# the service account, specify the 'token_format' parameter and use the
|
||||
# 'accesss_token' output.
|
||||
#
|
||||
# - uses: 'google-github-actions/auth@v2'
|
||||
# - uses: 'google-github-actions/auth@v3'
|
||||
# with:
|
||||
# workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider'
|
||||
# service_account: 'my-service-account@my-project.iam.gserviceaccount.com'
|
||||
|
|
@ -79,7 +79,7 @@ jobs:
|
|||
steps:
|
||||
- uses: 'actions/checkout@v4'
|
||||
|
||||
- uses: 'google-github-actions/auth@v2'
|
||||
- uses: 'google-github-actions/auth@v3'
|
||||
with:
|
||||
credentials_json: '${{ secrets.GOOGLE_CREDENTIALS }}'
|
||||
```
|
||||
|
|
@ -100,7 +100,7 @@ jobs:
|
|||
- uses: 'actions/checkout@v4'
|
||||
|
||||
- id: 'auth'
|
||||
uses: 'google-github-actions/auth@v2'
|
||||
uses: 'google-github-actions/auth@v3'
|
||||
with:
|
||||
project_id: 'my-project'
|
||||
workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider'
|
||||
|
|
@ -136,7 +136,7 @@ jobs:
|
|||
- uses: 'actions/checkout@v4'
|
||||
|
||||
- id: 'auth'
|
||||
uses: 'google-github-actions/auth@v2'
|
||||
uses: 'google-github-actions/auth@v3'
|
||||
with:
|
||||
token_format: 'access_token' # <--
|
||||
workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider'
|
||||
|
|
@ -173,7 +173,7 @@ jobs:
|
|||
- uses: 'actions/checkout@v4'
|
||||
|
||||
- id: 'auth'
|
||||
uses: 'google-github-actions/auth@v2'
|
||||
uses: 'google-github-actions/auth@v3'
|
||||
with:
|
||||
token_format: 'id_token' # <--
|
||||
workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider'
|
||||
|
|
@ -187,6 +187,69 @@ jobs:
|
|||
run: |-
|
||||
curl https://myapp-uvehjacqzq.a.run.app \
|
||||
--header "Authorization: Bearer ${{ steps.auth.outputs.id_token }}"
|
||||
|
||||
# Example of using ID token in Python code
|
||||
- id: 'python-example'
|
||||
run: |-
|
||||
python -c "
|
||||
import os
|
||||
import requests
|
||||
|
||||
# ID token is available as environment variable
|
||||
id_token = os.environ.get('GOOGLE_ID_TOKEN', '${{ steps.auth.outputs.id_token }}')
|
||||
|
||||
# Use the token to invoke a Cloud Run service
|
||||
response = requests.get(
|
||||
'https://myapp-uvehjacqzq.a.run.app',
|
||||
headers={'Authorization': f'Bearer {id_token}'}
|
||||
)
|
||||
print(response.text)
|
||||
"
|
||||
```
|
||||
|
||||
### Using Default Credentials with Scopes in Python
|
||||
|
||||
When using Workload Identity Federation with Python libraries, you may need to
|
||||
add scopes before refreshing credentials:
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
job_id:
|
||||
permissions:
|
||||
contents: 'read'
|
||||
id-token: 'write'
|
||||
|
||||
steps:
|
||||
- uses: 'actions/checkout@v4'
|
||||
|
||||
- id: 'auth'
|
||||
uses: 'google-github-actions/auth@v3'
|
||||
with:
|
||||
workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider'
|
||||
service_account: 'my-service-account@my-project.iam.gserviceaccount.com'
|
||||
|
||||
- id: 'python-auth'
|
||||
run: |-
|
||||
python -c "
|
||||
from google.auth import default
|
||||
from google.auth.transport.requests import Request
|
||||
|
||||
# Get default credentials
|
||||
credentials, project = default()
|
||||
|
||||
# Add scopes before refreshing for impersonation
|
||||
credentials = credentials.with_scopes(
|
||||
['https://www.googleapis.com/auth/cloud-platform']
|
||||
)
|
||||
|
||||
# Refresh to get the token
|
||||
credentials.refresh(request=Request())
|
||||
|
||||
# Now you can use the credentials
|
||||
print(f'Access token: {credentials.token}')
|
||||
if hasattr(credentials, 'id_token'):
|
||||
print(f'ID token: {credentials.id_token}')
|
||||
"
|
||||
```
|
||||
|
||||
[github-markdown-toc]: https://github.blog/changelog/2021-04-13-table-of-contents-support-in-markdown-files/
|
||||
|
|
|
|||
|
|
@ -6,9 +6,7 @@
|
|||
see exactly which step is failing. Ensure you are using the latest version
|
||||
of the GitHub Action.
|
||||
|
||||
> [!CAUTION]
|
||||
>
|
||||
> Enabling debug logging increases the chances of a secret
|
||||
> **⚠️ WARNING!** Enabling debug logging increases the chances of a secret
|
||||
> being accidentally logged. While GitHub Actions will scrub secrets,
|
||||
> please take extra caution when sharing these debug logs in publicly
|
||||
> accessible places like GitHub issues.
|
||||
|
|
@ -29,7 +27,7 @@
|
|||
```yaml
|
||||
steps:
|
||||
- uses: 'actions/checkout@v4'
|
||||
- uses: 'google-github-actions/auth@v2'
|
||||
- uses: 'google-github-actions/auth@v3'
|
||||
```
|
||||
|
||||
1. Ensure the value for `workload_identity_provider` is the full _Provider_
|
||||
|
|
@ -46,7 +44,7 @@
|
|||
|
||||
```diff
|
||||
- projects/my-project/locations/global/workloadIdentityPools/my-pool/providers/my-provider
|
||||
+ projects/1234567890/locations/global/workloadIdentityPools/my-pool/providers/
|
||||
+ projects/1234567890/locations/global/workloadIdentityPools/my-pool/providers/my-provider
|
||||
```
|
||||
|
||||
1. Ensure that you have the correct `permissions:` for the job in your
|
||||
|
|
@ -64,11 +62,9 @@
|
|||
GitHub OIDC token. You cannot grant permissions on an attribute unless you
|
||||
map that value from the incoming GitHub OIDC token.
|
||||
|
||||
> [!TIP]
|
||||
>
|
||||
> Use the [GitHub Actions OIDC Debugger][oidc-debugger] to print the list of
|
||||
> token claims and compare them to your Attribute Mappings and Attribute
|
||||
> Conditions.
|
||||
> **ℹ️ TIP!** Use the [GitHub Actions OIDC Debugger][oidc-debugger] to print
|
||||
> the list of token claims and compare them to your Attribute Mappings and
|
||||
> Attribute Conditions.
|
||||
|
||||
1. Ensure you have the correct character casing and capitalization. GitHub does
|
||||
not distinguish between "foobar" and "FooBar", but Google Cloud does. Ensure
|
||||
|
|
@ -89,10 +85,8 @@
|
|||
1. Enable `Admin Read`, `Data Read`, and `Data Write` [Audit Logging][cal] for
|
||||
Identity and Access Management (IAM) in your Google Cloud project.
|
||||
|
||||
> [!WARNING]
|
||||
>
|
||||
> This will increase log volume which may increase costs. You can disable
|
||||
> this audit logging after you have debugged the issue.
|
||||
> **⚠️ WARNING!** This will increase log volume which may increase costs.
|
||||
> You can disable this audit logging after you have debugged the issue.
|
||||
|
||||
Try to authenticate again, and then explore the logs for your Workload
|
||||
Identity Provider and Workload Identity Pool. Sometimes these error messages
|
||||
|
|
@ -236,11 +230,56 @@ tool like `jq`:
|
|||
cat credentials.json | jq -r tostring
|
||||
```
|
||||
|
||||
<a name="cannot-refresh"></a>
|
||||
|
||||
## Cannot refresh credentials to retrieve an ID token
|
||||
|
||||
If you get an error like:
|
||||
|
||||
```text
|
||||
google.auth.exceptions.RefreshError: ('Unable to acquire impersonated credentials', '{"error": {"code": 400, "message": "Request contains an invalid argument.", "status": "INVALID_ARGUMENT"}}')
|
||||
```
|
||||
|
||||
when trying to refresh credentials in Python code to get an ID token, this is
|
||||
usually because the credentials are missing required scopes. The Google Auth
|
||||
library requires scopes to be set when refreshing credentials for impersonation.
|
||||
|
||||
To fix this issue, add the required scopes before refreshing:
|
||||
|
||||
```python
|
||||
from google.auth import default
|
||||
from google.auth.transport.requests import Request
|
||||
|
||||
credentials, project = default()
|
||||
|
||||
# Add scopes before refreshing
|
||||
credentials = credentials.with_scopes(
|
||||
["https://www.googleapis.com/auth/cloud-platform"]
|
||||
)
|
||||
credentials.refresh(request=Request())
|
||||
|
||||
# Now you can access the ID token
|
||||
print(credentials.id_token)
|
||||
```
|
||||
|
||||
Alternatively, you can use the `token_format` parameter of this action to
|
||||
generate an ID token directly:
|
||||
|
||||
```yaml
|
||||
- uses: 'google-github-actions/auth@v3'
|
||||
with:
|
||||
workload_identity_provider: ${{ secrets.WIF_PROVIDER }}
|
||||
service_account: ${{ secrets.WIF_SERVICE_ACCOUNT }}
|
||||
token_format: 'id_token'
|
||||
id_token_audience: 'https://example.com'
|
||||
```
|
||||
|
||||
This will export the ID token as an environment variable that you can use in
|
||||
your Python code.
|
||||
|
||||
## Organizational Policy Constraints
|
||||
|
||||
> [!NOTE]
|
||||
>
|
||||
> Your Google Cloud organization administrator controls these
|
||||
> **ℹ️ NOTE!** Your Google Cloud organization administrator controls these
|
||||
> policies. You must work with your internal IT department to resolve OrgPolicy
|
||||
> violations and constraints.
|
||||
|
||||
|
|
|
|||
804
package-lock.json
generated
804
package-lock.json
generated
File diff suppressed because it is too large
Load diff
36
package.json
36
package.json
|
|
@ -1,13 +1,17 @@
|
|||
{
|
||||
"name": "@google-github-actions/auth",
|
||||
"version": "2.1.6",
|
||||
"version": "3.0.0",
|
||||
"description": "Authenticate to Google Cloud using OIDC tokens or JSON service account keys.",
|
||||
"main": "dist/main/index.js",
|
||||
"scripts": {
|
||||
"build": "ncc build -m src/main.ts -o dist/main && ncc build -m src/post.ts -o dist/post",
|
||||
"lint": "eslint .",
|
||||
"format": "eslint . --fix",
|
||||
"test": "bash ./bin/runTests.sh"
|
||||
"test": "node --require ts-node/register --test-reporter spec --test tests/**/*.test.ts"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 24.x",
|
||||
"npm": ">= 11.x"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
@ -23,22 +27,22 @@
|
|||
"author": "GoogleCloudPlatform",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.1",
|
||||
"@actions/http-client": "^2.2.2",
|
||||
"@google-github-actions/actions-utils": "^0.8.3"
|
||||
"@actions/core": "^1.11.1",
|
||||
"@actions/http-client": "^2.2.3",
|
||||
"@google-github-actions/actions-utils": "^1.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "^3.1.0",
|
||||
"@eslint/js": "^9.9.0",
|
||||
"@types/node": "^22.4.1",
|
||||
"@vercel/ncc": "^0.38.1",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-prettier": "^5.2.1",
|
||||
"eslint": "^9.9.0",
|
||||
"prettier": "^3.3.3",
|
||||
"@eslint/eslintrc": "^3.3.1",
|
||||
"@eslint/js": "^9.34.0",
|
||||
"@types/node": "^24.3.0",
|
||||
"@vercel/ncc": "^0.38.3",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-prettier": "^5.5.4",
|
||||
"eslint": "^9.34.0",
|
||||
"prettier": "^3.6.2",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript-eslint": "^8.2.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.2.0",
|
||||
"typescript": "^5.5.4"
|
||||
"typescript-eslint": "^8.41.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.41.0",
|
||||
"typescript": "^5.9.2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
16
src/main.ts
16
src/main.ts
|
|
@ -16,7 +16,6 @@ import { join as pathjoin } from 'path';
|
|||
|
||||
import {
|
||||
exportVariable,
|
||||
getBooleanInput,
|
||||
getIDToken,
|
||||
getInput,
|
||||
setFailed,
|
||||
|
|
@ -29,8 +28,10 @@ import {
|
|||
isEmptyDir,
|
||||
isPinnedToHead,
|
||||
parseMultilineCSV,
|
||||
parseBoolean,
|
||||
parseDuration,
|
||||
pinnedToHeadWarning,
|
||||
withRetries,
|
||||
} from '@google-github-actions/actions-utils';
|
||||
|
||||
import {
|
||||
|
|
@ -79,8 +80,8 @@ export async function run(logger: Logger) {
|
|||
const oidcTokenAudience =
|
||||
getInput(`audience`) || `https://iam.googleapis.com/${workloadIdentityProvider}`;
|
||||
const credentialsJSON = getInput(`credentials_json`);
|
||||
const createCredentialsFile = getBooleanInput(`create_credentials_file`);
|
||||
const exportEnvironmentVariables = getBooleanInput(`export_environment_variables`);
|
||||
const createCredentialsFile = parseBoolean(getInput(`create_credentials_file`));
|
||||
const exportEnvironmentVariables = parseBoolean(getInput(`export_environment_variables`));
|
||||
const tokenFormat = getInput(`token_format`);
|
||||
const delegates = parseMultilineCSV(getInput(`delegates`));
|
||||
const universe = getInput(`universe`);
|
||||
|
|
@ -110,7 +111,12 @@ export async function run(logger: Logger) {
|
|||
throw new Error(oidcWarning);
|
||||
}
|
||||
|
||||
const oidcToken = await getIDToken(oidcTokenAudience);
|
||||
const oidcToken = await withRetries(
|
||||
async (): Promise<string> => {
|
||||
return await getIDToken(oidcTokenAudience);
|
||||
},
|
||||
{ retries: 3 },
|
||||
)();
|
||||
client = new WorkloadIdentityFederationClient({
|
||||
logger: logger,
|
||||
universe: universe,
|
||||
|
|
@ -301,7 +307,7 @@ export async function run(logger: Logger) {
|
|||
logger.debug(`Creating id token`);
|
||||
|
||||
const idTokenAudience = getInput('id_token_audience', { required: true });
|
||||
const idTokenIncludeEmail = getBooleanInput('id_token_include_email');
|
||||
const idTokenIncludeEmail = parseBoolean(getInput('id_token_include_email'));
|
||||
|
||||
// Ensure a service_account was provided if using WIF.
|
||||
if (!serviceAccount) {
|
||||
|
|
|
|||
|
|
@ -12,21 +12,21 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { getBooleanInput, setFailed } from '@actions/core';
|
||||
import { getInput, setFailed } from '@actions/core';
|
||||
|
||||
import { errorMessage, forceRemove } from '@google-github-actions/actions-utils';
|
||||
import { errorMessage, forceRemove, parseBoolean } from '@google-github-actions/actions-utils';
|
||||
|
||||
import { Logger } from './logger';
|
||||
|
||||
export async function run(logger: Logger) {
|
||||
try {
|
||||
const createCredentials = getBooleanInput('create_credentials_file');
|
||||
const createCredentials = parseBoolean(getInput('create_credentials_file'));
|
||||
if (!createCredentials) {
|
||||
logger.info(`Skipping credential cleanup - "create_credentials_file" is false.`);
|
||||
return;
|
||||
}
|
||||
|
||||
const cleanupCredentials = getBooleanInput('cleanup_credentials');
|
||||
const cleanupCredentials = parseBoolean(getInput('cleanup_credentials'));
|
||||
if (!cleanupCredentials) {
|
||||
logger.info(`Skipping credential cleanup - "cleanup_credentials" is false.`);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"alwaysStrict": true,
|
||||
"target": "es6",
|
||||
"target": "es2022",
|
||||
"module": "commonjs",
|
||||
"lib": ["es6"],
|
||||
"lib": ["es2022"],
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"strict": true,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue