Compare commits

...

48 commits

Author SHA1 Message Date
Seth Vargo
fc2174804b
Update README with correct Node version (#515)
Closes https://github.com/google-github-actions/auth/issues/514

Signed-off-by: Seth Vargo <seth@sethvargo.com>
2025-09-03 09:38:45 -04:00
Seth Vargo
0dfce0c0f8
Update README to reference v3 (#511) 2025-08-28 14:55:07 -04:00
Google GitHub Actions Bot
7c6bc770da
Release: v3.0.0 (#510)
## What's Changed
* Bump to Node 24 and remove old parameters by @sethvargo in
https://github.com/google-github-actions/auth/pull/508
* Remove hacky script by @sethvargo in
https://github.com/google-github-actions/auth/pull/509


**Full Changelog**:
https://github.com/google-github-actions/auth/compare/v2.1.13...v3.0.0
2025-08-28 18:51:40 +00:00
Seth Vargo
42e4997ee3
Remove hacky script (#509) 2025-08-28 14:44:31 -04:00
Seth Vargo
5ea4dc1147
Bump to Node 24 and remove old parameters (#508) 2025-08-28 14:39:57 -04:00
Google GitHub Actions Bot
c200f3691d
Release: v2.1.13 (#507)
## What's Changed
* Update deps by @sethvargo in
https://github.com/google-github-actions/auth/pull/506


**Full Changelog**:
https://github.com/google-github-actions/auth/compare/v2.1.12...v2.1.13
2025-08-28 18:27:28 +00:00
Seth Vargo
3a53be7e7c
Update deps (#506) 2025-08-28 14:25:15 -04:00
Google GitHub Actions Bot
b7593ed2ef
Release: v2.1.12 (#503)
## What's Changed
* Add retries for getIDToken by @sethvargo in
https://github.com/google-github-actions/auth/pull/502


**Full Changelog**:
https://github.com/google-github-actions/auth/compare/v2.1.11...v2.1.12
2025-08-01 15:15:43 +00:00
Seth Vargo
c1ee334b4f
Add retries for getIDToken (#502)
Closes #496
2025-08-01 10:44:21 -04:00
Google GitHub Actions Bot
140bb5113f
Release: v2.1.11 (#501)
## What's Changed
* Update troubleshooting docs for Python by @sethvargo in
https://github.com/google-github-actions/auth/pull/488
* Add linters by @sethvargo in
https://github.com/google-github-actions/auth/pull/499
* Update deps by @sethvargo in
https://github.com/google-github-actions/auth/pull/500


**Full Changelog**:
https://github.com/google-github-actions/auth/compare/v2.1.10...v2.1.11
2025-07-18 21:17:15 +00:00
Seth Vargo
ab3132e2ad
Update deps (#500) 2025-07-18 17:13:12 -04:00
Seth Vargo
25b96bac99
Add linters (#499) 2025-07-18 01:13:31 +00:00
Seth Vargo
0920706a19
Update troubleshooting docs for Python (#488)
Closes https://github.com/google-github-actions/auth/pull/487

---------

Co-authored-by: Abhi Srivastava <bits.abhi@gmail.com>
2025-06-02 10:48:14 -04:00
Google GitHub Actions Bot
ba79af0395
Release: v2.1.10 (#484)
## What's Changed
* Declare workflow permissions by @sethvargo in
https://github.com/google-github-actions/auth/pull/482
* Document that the OIDC token expires in 5min by @sethvargo in
https://github.com/google-github-actions/auth/pull/483


**Full Changelog**:
https://github.com/google-github-actions/auth/compare/v2.1.9...v2.1.10
2025-04-25 09:48:31 -04:00
Seth Vargo
bfaa66bd66
Document that the OIDC token expires in 5min (#483) 2025-04-25 08:43:32 -04:00
Seth Vargo
d0822ad9bf
Declare workflow permissions (#482) 2025-04-25 08:42:57 -04:00
Google GitHub Actions Bot
7b53cdc2a3
Release: v2.1.9 (#480)
## What's Changed
* Use our custom boolean parsing by @sethvargo in
https://github.com/google-github-actions/auth/pull/478
* Update deps by @sethvargo in
https://github.com/google-github-actions/auth/pull/479


**Full Changelog**:
https://github.com/google-github-actions/auth/compare/v2.1.8...v2.1.9
2025-04-24 17:48:14 +00:00
Seth Vargo
a9cfddf5d2
Update deps (#479) 2025-04-24 13:44:06 -04:00
Seth Vargo
b011f3988e
Use our custom boolean parsing (#478)
Fixes GH-477
2025-04-24 11:53:29 -04:00
Google GitHub Actions Bot
71f986410d
Release: v2.1.8 (#467)
## What's Changed
* Update TROUBLESHOOTING.md by @sethvargo in
https://github.com/google-github-actions/auth/pull/457
* fix: add runs-on to README.md example by @lbarthon in
https://github.com/google-github-actions/auth/pull/460
* security: bump undici from 5.28.4 to 5.28.5 in the npm_and_yarn group
by @dependabot in https://github.com/google-github-actions/auth/pull/463
* Update deps by @sethvargo in
https://github.com/google-github-actions/auth/pull/466

## New Contributors
* @lbarthon made their first contribution in
https://github.com/google-github-actions/auth/pull/460

**Full Changelog**:
https://github.com/google-github-actions/auth/compare/v2.1.7...v2.1.8
2025-02-01 14:16:56 +00:00
Seth Vargo
0cd8f2e4e2
Update deps (#466) 2025-02-01 08:49:34 -05:00
dependabot[bot]
332e0ba72f
security: bump undici from 5.28.4 to 5.28.5 in the npm_and_yarn group (#463)
Bumps the npm_and_yarn group with 1 update:
[undici](https://github.com/nodejs/undici).

Updates `undici` from 5.28.4 to 5.28.5
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/nodejs/undici/releases">undici's
releases</a>.</em></p>
<blockquote>
<h2>v5.28.5</h2>
<h1>⚠️ Security Release ⚠️</h1>
<p>Fixes CVE CVE-2025-22150 <a
href="https://github.com/nodejs/undici/security/advisories/GHSA-c76h-2ccp-4975">https://github.com/nodejs/undici/security/advisories/GHSA-c76h-2ccp-4975</a>
(embargoed until 22-01-2025).</p>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/nodejs/undici/compare/v5.28.4...v5.28.5">https://github.com/nodejs/undici/compare/v5.28.4...v5.28.5</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="6139ed2e0c"><code>6139ed2</code></a>
Bumped v5.28.5</li>
<li><a
href="711e207727"><code>711e207</code></a>
Backport of c2d78cd</li>
<li>See full diff in <a
href="https://github.com/nodejs/undici/compare/v5.28.4...v5.28.5">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=undici&package-manager=npm_and_yarn&previous-version=5.28.4&new-version=5.28.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

You can trigger a rebase of this PR by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/google-github-actions/auth/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-29 18:18:58 -05:00
Louis
28d44ba259
fix: add runs-on to README.md example (#460)
This is needed in order for this example to "work". The runner that
needs to be picked is specified above, but it's still handy if we can
simply copy / paste from the README.

<!--
Thank you for proposing a pull request! Please note that SOME TESTS WILL
LIKELY FAIL due to how GitHub exposes secrets in Pull Requests from
forks.
Someone from the team will review your Pull Request and respond.

Please describe your change and any implementation details below.
-->
2025-01-23 11:44:32 -05:00
Seth Vargo
83354cacbb
Update TROUBLESHOOTING.md (#457)
Fix a bunch of issues since GitHub apparently dropped support for
special callouts.

Refs https://github.com/google-github-actions/auth/issues/455

Signed-off-by: Seth Vargo <seth@sethvargo.com>
2024-12-02 09:20:26 -05:00
Google GitHub Actions Bot
6fc4af4b14
Release: v2.1.7 (#453)
## What's Changed
* fix: update relase workflows by @verbanicm in
https://github.com/google-github-actions/auth/pull/452


**Full Changelog**:
https://github.com/google-github-actions/auth/compare/v2.1.6...212f83afe868cc88aa354e1efbf778eff05d970a
2024-10-30 18:53:27 +00:00
Mike Verbanic
212f83afe8
fix: update relase workflows (#452)
<!--
Thank you for proposing a pull request! Please note that SOME TESTS WILL
LIKELY FAIL due to how GitHub exposes secrets in Pull Requests from
forks.
Someone from the team will review your Pull Request and respond.

Please describe your change and any implementation details below.
-->
2024-10-30 14:26:20 -04:00
Google GitHub Actions Bot
8254fb75a3
Release: v2.1.6 (#449)
## What's Changed
* Recommend `gcloud storage` over `gsutil` by @sethvargo in
https://github.com/google-github-actions/auth/pull/438
* Add missing log line by @sethvargo in
https://github.com/google-github-actions/auth/pull/448


**Full Changelog**:
https://github.com/google-github-actions/auth/compare/v2.1.5...d1b27fe5c4d3d1e3dc8a68e8fc94cc4b24009c24
2024-10-01 19:37:05 +00:00
Seth Vargo
d1b27fe5c4
Add missing log line (#448) 2024-10-01 14:04:12 +00:00
Seth Vargo
c8788cc4c5
Recommend gcloud storage over gsutil (#438)
Closes #404
2024-08-21 17:00:27 +00:00
Google GitHub Actions Bot
62cf5bd3e4
Release: v2.1.5 (#437)
## What's Changed
* Document ID Token lifetimes by @sethvargo in
https://github.com/google-github-actions/auth/pull/433
* fix !project_id error message typo by @seth-acuitymd in
https://github.com/google-github-actions/auth/pull/435
* Update deps by @sethvargo in
https://github.com/google-github-actions/auth/pull/436

## New Contributors
* @seth-acuitymd made their first contribution in
https://github.com/google-github-actions/auth/pull/435

**Full Changelog**:
https://github.com/google-github-actions/auth/compare/v2.1.4...0a94a84ba5475d3020c3df611c610b909d57bbb9
2024-08-21 02:43:58 +00:00
Seth Vargo
0a94a84ba5
Update deps (#436) 2024-08-20 20:58:29 -04:00
Seth McCombs
699582eeaf
fix !project_id error message typo (#435)
<!--
Thank you for proposing a pull request! Please note that SOME TESTS WILL
LIKELY FAIL due to how GitHub exposes secrets in Pull Requests from
forks.
Someone from the team will review your Pull Request and respond.

Please describe your change and any implementation details below.
-->

Small change! This error message seems like it's missing a word, so
based on the comment on line 202, I changed it
from
> `⚠️ Failed to a project ID from the given inputs.`

to

> `⚠️ Failed to compute a project ID from the given inputs`
2024-08-20 15:21:32 -07:00
Seth Vargo
6384b341b7
Document ID Token lifetimes (#433)
Closes https://github.com/google-github-actions/auth/issues/432
2024-08-07 01:28:34 +00:00
Google GitHub Actions Bot
f112390a2d
Release: v2.1.4 (#431)
## What's Changed
* security: bump braces from 3.0.2 to 3.0.3 in the npm_and_yarn group by
@dependabot in https://github.com/google-github-actions/auth/pull/420
* Update spelling and workflow versions by @sethvargo in
https://github.com/google-github-actions/auth/pull/422
* Update deps by @sethvargo in
https://github.com/google-github-actions/auth/pull/430


**Full Changelog**:
https://github.com/google-github-actions/auth/compare/v2.1.3...984b9cfee9afc210d62d5d59c77fdf75553ada22
2024-08-06 01:27:11 +00:00
Seth Vargo
984b9cfee9
Update deps (#430) 2024-08-05 16:15:15 -04:00
Seth Vargo
5e210ff4ed
Update spelling and workflow versions (#422)
Closes #421

---------

Signed-off-by: JGStew <james@jgstew.com>
Signed-off-by: JGStew <jamesgstewart2@gmail.com>
Co-authored-by: JGStew <james@jgstew.com>
Co-authored-by: JGStew <jamesgstewart2@gmail.com>
2024-06-21 11:57:04 -04:00
dependabot[bot]
49ae1e804e
security: bump braces from 3.0.2 to 3.0.3 in the npm_and_yarn group (#420)
Bumps the npm_and_yarn group with 1 update:
[braces](https://github.com/micromatch/braces).

Updates `braces` from 3.0.2 to 3.0.3
<details>
<summary>Commits</summary>
<ul>
<li><a
href="74b2db2938"><code>74b2db2</code></a>
3.0.3</li>
<li><a
href="88f1429a0f"><code>88f1429</code></a>
update eslint. lint, fix unit tests.</li>
<li><a
href="415d660c30"><code>415d660</code></a>
Snyk js braces 6838727 (<a
href="https://redirect.github.com/micromatch/braces/issues/40">#40</a>)</li>
<li><a
href="190510f79d"><code>190510f</code></a>
fix tests, skip 1 test in test/braces.expand</li>
<li><a
href="716eb9f12d"><code>716eb9f</code></a>
readme bump</li>
<li><a
href="a5851e57f4"><code>a5851e5</code></a>
Merge pull request <a
href="https://redirect.github.com/micromatch/braces/issues/37">#37</a>
from coderaiser/fix/vulnerability</li>
<li><a
href="2092bd1fb1"><code>2092bd1</code></a>
feature: braces: add maxSymbols (<a
href="https://github.com/micromatch/braces/issues/">https://github.com/micromatch/braces/issues/</a>...</li>
<li><a
href="9f5b4cf473"><code>9f5b4cf</code></a>
fix: vulnerability (<a
href="https://security.snyk.io/vuln/SNYK-JS-BRACES-6838727">https://security.snyk.io/vuln/SNYK-JS-BRACES-6838727</a>)</li>
<li><a
href="98414f9f1f"><code>98414f9</code></a>
remove funding file</li>
<li><a
href="665ab5d561"><code>665ab5d</code></a>
update keepEscaping doc (<a
href="https://redirect.github.com/micromatch/braces/issues/27">#27</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/micromatch/braces/compare/3.0.2...3.0.3">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=braces&package-manager=npm_and_yarn&previous-version=3.0.2&new-version=3.0.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

You can trigger a rebase of this PR by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/google-github-actions/auth/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-17 14:12:52 +00:00
Google GitHub Actions Bot
71fee32a0b
Release: v2.1.3 (#414)
## What's Changed
* Security considerations: ids are strings, not integers by @ewjoachim
in https://github.com/google-github-actions/auth/pull/400
* security: bump undici from 5.28.3 to 5.28.4 by @dependabot in
https://github.com/google-github-actions/auth/pull/405
* Fix typo by @sethvargo in
https://github.com/google-github-actions/auth/pull/408
* Switch to using universe helpers by @sethvargo in
https://github.com/google-github-actions/auth/pull/410
* Add request_reason for plumbing though user-supplied audit information
by @sethvargo in https://github.com/google-github-actions/auth/pull/413

## New Contributors
* @ewjoachim made their first contribution in
https://github.com/google-github-actions/auth/pull/400

**Full Changelog**:
https://github.com/google-github-actions/auth/compare/v2.1.2...e0122d6a976dd6794fe6e866adfcb3c11f828b36
2024-05-14 13:57:49 -04:00
Seth Vargo
e0122d6a97
Add request_reason for plumbing though user-supplied audit information (#413)
Fixes https://github.com/google-github-actions/auth/issues/412
2024-05-14 16:46:35 +00:00
Seth Vargo
34baaec3f3
Switch to using universe helpers (#410) 2024-05-04 12:05:55 -04:00
Seth Vargo
8d44d59719
Fix typo (#408)
Fixes #407
2024-04-16 21:39:19 +00:00
dependabot[bot]
d176447fc7
security: bump undici from 5.28.3 to 5.28.4 (#405)
Bumps [undici](https://github.com/nodejs/undici) from 5.28.3 to 5.28.4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/nodejs/undici/releases">undici's
releases</a>.</em></p>
<blockquote>
<h2>v5.28.4</h2>
<h2>⚠️ Security Release ⚠️</h2>
<ul>
<li>Fixes <a
href="https://github.com/nodejs/undici/security/advisories/GHSA-m4v8-wqvr-p9f7">https://github.com/nodejs/undici/security/advisories/GHSA-m4v8-wqvr-p9f7</a>
CVE-2024-30260</li>
<li>Fixes <a
href="https://github.com/nodejs/undici/security/advisories/GHSA-9qxr-qj54-h672">https://github.com/nodejs/undici/security/advisories/GHSA-9qxr-qj54-h672</a>
CVE-2024-30261</li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/nodejs/undici/compare/v5.28.3...v5.28.4">https://github.com/nodejs/undici/compare/v5.28.3...v5.28.4</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fb98306907"><code>fb98306</code></a>
Bumped v5.28.4</li>
<li><a
href="2b39440bd9"><code>2b39440</code></a>
Merge pull request from GHSA-9qxr-qj54-h672</li>
<li><a
href="64e3402da4"><code>64e3402</code></a>
Merge pull request from GHSA-m4v8-wqvr-p9f7</li>
<li><a
href="723c4e7280"><code>723c4e7</code></a>
Revert &quot;build(deps-dev): bump formdata-node from 4.4.1 to 6.0.3 (<a
href="https://redirect.github.com/nodejs/undici/issues/2389">#2389</a>)&quot;</li>
<li><a
href="0e9d54b2c2"><code>0e9d54b</code></a>
skip failing test due to Node.js changes</li>
<li>See full diff in <a
href="https://github.com/nodejs/undici/compare/v5.28.3...v5.28.4">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=undici&package-manager=npm_and_yarn&previous-version=5.28.3&new-version=5.28.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

You can trigger a rebase of this PR by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/google-github-actions/auth/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-04 16:04:39 -04:00
Joachim Jablon
33e827c6cc
Security considerations: ids are strings, not integers (#400)
Fix doc regarding using assertion on IDs rather than names. They refer
to IDs as integers, where those are actually strings, so we need to
quote them.

I lost too many hours on this to let anyone else experience the same
issue :D

Signed-off-by: Joachim Jablon <ewjoachim@gmail.com>
2024-03-12 11:21:38 -04:00
Google GitHub Actions Bot
55bd3a7c6e
Release: v2.1.2 (#399)
## What's Changed
* Remove documentation on retries (deprecated) by @sethvargo in
https://github.com/google-github-actions/auth/pull/392
* Add security considerations for Attribute Conditions by @sethvargo in
https://github.com/google-github-actions/auth/pull/393
* security: bump undici from 5.28.2 to 5.28.3 by @dependabot in
https://github.com/google-github-actions/auth/pull/394
* Reduce warnings to info level with a warning icon by @sethvargo in
https://github.com/google-github-actions/auth/pull/397

## New Contributors
* @dependabot made their first contribution in
https://github.com/google-github-actions/auth/pull/394

**Full Changelog**:
https://github.com/google-github-actions/auth/compare/v2.1.1...bf02f20c66a26ba12adc45fa735c39f496ab04df
2024-02-25 19:44:23 +00:00
Seth Vargo
bf02f20c66
Reduce warnings to info level with a warning icon (#397)
With direct WIF, there are now many legitimate use cases for not
specifying a project_id or having a local checkout.
2024-02-25 14:29:20 -05:00
dependabot[bot]
51342a1a91
security: bump undici from 5.28.2 to 5.28.3 (#394)
Bumps [undici](https://github.com/nodejs/undici) from 5.28.2 to 5.28.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/nodejs/undici/releases">undici's
releases</a>.</em></p>
<blockquote>
<h2>v5.28.3</h2>
<h2>⚠️ Security Release ⚠️</h2>
<p>Fixes:</p>
<ul>
<li><a
href="https://github.com/nodejs/undici/security/advisories/GHSA-3787-6prv-h9w3">CVE-2024-24758
Proxy-Authorization header not cleared on cross-origin redirect in
fetch</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/nodejs/undici/compare/v5.28.2...v5.28.3">https://github.com/nodejs/undici/compare/v5.28.2...v5.28.3</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="e71cb4c88f"><code>e71cb4c</code></a>
Bumped v5.28.3</li>
<li><a
href="20c65b89f4"><code>20c65b8</code></a>
Fix tests for Node.js v20.11.0 (<a
href="https://redirect.github.com/nodejs/undici/issues/2618">#2618</a>)</li>
<li><a
href="8ec52cde66"><code>8ec52cd</code></a>
Fix tests for Node.js v21 (<a
href="https://redirect.github.com/nodejs/undici/issues/2609">#2609</a>)</li>
<li><a
href="d3aa574b12"><code>d3aa574</code></a>
Merge pull request from GHSA-3787-6prv-h9w3</li>
<li>See full diff in <a
href="https://github.com/nodejs/undici/compare/v5.28.2...v5.28.3">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=undici&package-manager=npm_and_yarn&previous-version=5.28.2&new-version=5.28.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

You can trigger a rebase of this PR by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/google-github-actions/auth/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-16 15:07:59 -05:00
Seth Vargo
ee1c1b641f
Add security considerations for Attribute Conditions (#393) 2024-02-07 08:19:20 -05:00
Seth Vargo
ec485ac236
Remove documentation on retries (deprecated) (#392) 2024-02-06 16:34:44 +00:00
27 changed files with 1230 additions and 1012 deletions

View file

@ -1,15 +0,0 @@
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
],
rules: {
'@typescript-eslint/no-explicit-any': 'off',
},
};

5
.github/actionlint.yml vendored Normal file
View file

@ -0,0 +1,5 @@
paths:
'**/*.yml':
ignore:
# https://github.com/rhysd/actionlint/issues/559
- 'invalid runner name "node24"'

View file

@ -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' name: 'Draft release'
on: on:
@ -29,10 +15,11 @@ on:
jobs: jobs:
draft-release: draft-release:
name: 'Draft release' uses: 'google-github-actions/.github/.github/workflows/draft-release.yml@v3' # ratchet:exclude
uses: 'google-github-actions/.github/.github/workflows/draft-release.yml@v0' permissions:
contents: 'read'
pull-requests: 'write'
with: with:
version_strategy: '${{ github.event.inputs.version_strategy }}' 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: secrets:
ACTIONS_BOT_TOKEN: '${{ secrets.ACTIONS_BOT_TOKEN }}' ACTIONS_BOT_TOKEN: '${{ secrets.ACTIONS_BOT_TOKEN }}'

25
.github/workflows/publish.yml vendored Normal file
View 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 }}'

View file

@ -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' name: 'Release'
on: on:
@ -22,6 +8,10 @@ on:
jobs: jobs:
release: release:
if: "startsWith(github.event.head_commit.message, 'Release: v')" uses: 'google-github-actions/.github/.github/workflows/release.yml@v3' # ratchet:exclude
name: 'Release' permissions:
uses: 'google-github-actions/.github/.github/workflows/release.yml@v0' attestations: 'write'
contents: 'write'
packages: 'write'
secrets:
ACTIONS_BOT_TOKEN: '${{ secrets.ACTIONS_BOT_TOKEN }}'

View file

@ -29,6 +29,10 @@ concurrency:
group: '${{ github.workflow }}-${{ github.head_ref || github.ref }}' group: '${{ github.workflow }}-${{ github.head_ref || github.ref }}'
cancel-in-progress: true cancel-in-progress: true
permissions:
contents: 'read'
statuses: 'write'
defaults: defaults:
run: run:
shell: 'bash' shell: 'bash'
@ -39,18 +43,15 @@ jobs:
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
steps: 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: with:
node-version: '20.x' node-version-file: 'package.json'
- name: 'npm build' - name: 'npm build'
run: 'npm ci && npm run build' run: 'npm ci && npm run build'
- name: 'npm lint'
run: 'npm run lint'
- name: 'npm test' - name: 'npm test'
run: 'npm run test' run: 'npm run test'
@ -59,7 +60,8 @@ jobs:
# Direct Workload Identity Federation # Direct Workload Identity Federation
# #
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' name: 'direct_workload_identity_federation'
runs-on: '${{ matrix.os }}' runs-on: '${{ matrix.os }}'
strategy: strategy:
@ -74,11 +76,11 @@ jobs:
id-token: 'write' id-token: 'write'
steps: 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: with:
node-version: '20.x' node-version-file: 'package.json'
- name: 'npm build' - name: 'npm build'
run: 'npm ci && npm run build' run: 'npm ci && npm run build'
@ -90,14 +92,6 @@ jobs:
project_id: '${{ vars.PROJECT_ID }}' project_id: '${{ vars.PROJECT_ID }}'
workload_identity_provider: '${{ vars.WIF_PROVIDER_NAME }}' workload_identity_provider: '${{ vars.WIF_PROVIDER_NAME }}'
- uses: 'google-github-actions/setup-gcloud@v2'
with:
version: '>= 363.0.0'
- name: 'gcloud'
run: |-
gcloud secrets versions access "latest" --secret "${{ vars.SECRET_NAME }}"
- id: 'oauth-federated-token' - id: 'oauth-federated-token'
name: 'oauth-federated-token' name: 'oauth-federated-token'
run: |- run: |-
@ -107,12 +101,21 @@ jobs:
--fail \ --fail \
--header "Authorization: Bearer ${{ steps.auth-default.outputs.auth_token }}" --header "Authorization: Bearer ${{ steps.auth-default.outputs.auth_token }}"
- uses: 'google-github-actions/setup-gcloud@main' # ratchet:exclude
with:
version: '>= 363.0.0'
- name: 'gcloud'
run: |-
gcloud secrets versions access "latest" --secret "${{ vars.SECRET_NAME }}"
# #
# Workload Identity Federation through a Service Account # Workload Identity Federation through a Service Account
# #
workload_identity_federation_through_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' name: 'workload_identity_federation_through_service_account'
runs-on: '${{ matrix.os }}' runs-on: '${{ matrix.os }}'
strategy: strategy:
@ -127,11 +130,11 @@ jobs:
id-token: 'write' id-token: 'write'
steps: 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: with:
node-version: '20.x' node-version-file: 'package.json'
- name: 'npm build' - name: 'npm build'
run: 'npm ci && npm run build' run: 'npm ci && npm run build'
@ -143,7 +146,7 @@ jobs:
workload_identity_provider: '${{ vars.WIF_PROVIDER_NAME }}' workload_identity_provider: '${{ vars.WIF_PROVIDER_NAME }}'
service_account: '${{ vars.SERVICE_ACCOUNT_EMAIL }}' service_account: '${{ vars.SERVICE_ACCOUNT_EMAIL }}'
- uses: 'google-github-actions/setup-gcloud@v2' - uses: 'google-github-actions/setup-gcloud@main' # ratchet:exclude
with: with:
version: '>= 363.0.0' version: '>= 363.0.0'
@ -183,7 +186,8 @@ jobs:
# Service Account Key JSON # Service Account Key JSON
# #
credentials_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' name: 'credentials_json'
runs-on: '${{ matrix.os }}' runs-on: '${{ matrix.os }}'
strategy: strategy:
@ -195,11 +199,11 @@ jobs:
- 'macos-latest' - 'macos-latest'
steps: 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: with:
node-version: '20.x' node-version-file: 'package.json'
- name: 'npm build' - name: 'npm build'
run: 'npm ci && npm run build' run: 'npm ci && npm run build'
@ -210,7 +214,7 @@ jobs:
with: with:
credentials_json: '${{ secrets.SERVICE_ACCOUNT_KEY_JSON }}' credentials_json: '${{ secrets.SERVICE_ACCOUNT_KEY_JSON }}'
- uses: 'google-github-actions/setup-gcloud@v2' - uses: 'google-github-actions/setup-gcloud@main' # ratchet:exclude
with: with:
version: '>= 363.0.0' version: '>= 363.0.0'
@ -243,15 +247,6 @@ jobs:
id_token_audience: 'https://secretmanager.googleapis.com/' id_token_audience: 'https://secretmanager.googleapis.com/'
id_token_include_email: true 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 }}'
# #
# This test ensures that the GOOGLE_APPLICATION_CREDENTIALS environment # This test ensures that the GOOGLE_APPLICATION_CREDENTIALS environment
# variable is shared with the container and that the path of the file is on # variable is shared with the container and that the path of the file is on
@ -259,17 +254,18 @@ jobs:
# has permissions to read the file. # has permissions to read the file.
# #
docker: 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' name: 'docker'
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
strategy: strategy:
fail-fast: false fail-fast: false
steps: 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: with:
node-version: '20.x' node-version-file: 'package.json'
- name: 'npm build' - name: 'npm build'
run: 'npm ci && npm run build' run: 'npm ci && npm run build'
@ -280,7 +276,7 @@ jobs:
credentials_json: '${{ secrets.SERVICE_ACCOUNT_KEY_JSON }}' credentials_json: '${{ secrets.SERVICE_ACCOUNT_KEY_JSON }}'
- name: 'docker' - name: 'docker'
uses: 'docker://alpine:3' uses: 'docker://index.docker.io/library/alpine@sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1' # ratchet:docker://alpine:3
with: with:
entrypoint: '/bin/sh' entrypoint: '/bin/sh'
args: '-euc "test -n "${GOOGLE_APPLICATION_CREDENTIALS}" && test -r "${GOOGLE_APPLICATION_CREDENTIALS}"' args: '-euc "test -n "${GOOGLE_APPLICATION_CREDENTIALS}" && test -r "${GOOGLE_APPLICATION_CREDENTIALS}"'

View file

@ -27,7 +27,7 @@ jobs:
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
steps: steps:
- uses: 'actions/github-script@v6' - uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea' # ratchet:actions/github-script@v7
with: with:
script: |- script: |-
const msg = const msg =

171
README.md
View file

@ -14,6 +14,10 @@ Action to authenticate to Google Cloud:
1. [Workload Identity Federation through a Service Account](#indirect-wif) 1. [Workload Identity Federation through a Service Account](#indirect-wif)
1. [Service Account Key JSON](#sake) 1. [Service Account Key JSON](#sake)
> [!IMPORTANT]
> The `gsutil` command will **not** use the credentials exported by this GitHub
> Action. Customers should use `gcloud storage` instead.
**This is not an officially supported Google product, and it is not covered by a **This is not an officially supported Google product, and it is not covered by a
Google Cloud support contract. To report bugs or request features in a Google Google Cloud support contract. To report bugs or request features in a Google
Cloud product, please contact [Google Cloud Cloud product, please contact [Google Cloud
@ -35,10 +39,7 @@ support](https://cloud.google.com/support).**
gha-creds-*.json gha-creds-*.json
``` ```
- To use the `bq` or `gsutil` tools, use the Google Cloud SDK version 390.0.0 - This action runs using Node 24. Use a [runner
or newer.
- This action runs using Node 20. Use a [runner
version](https://github.com/actions/virtual-environments) that supports this version](https://github.com/actions/virtual-environments) that supports this
version of Node or newer. version of Node or newer.
@ -48,6 +49,9 @@ support](https://cloud.google.com/support).**
```yaml ```yaml
jobs: jobs:
job_id: job_id:
# Any runner supporting Node 20 or newer
runs-on: ubuntu-latest
# Add "id-token" with the intended permissions. # Add "id-token" with the intended permissions.
permissions: permissions:
contents: 'read' contents: 'read'
@ -56,7 +60,7 @@ jobs:
steps: steps:
- uses: 'actions/checkout@v4' - uses: 'actions/checkout@v4'
- uses: 'google-github-actions/auth@v2' - uses: 'google-github-actions/auth@v3'
with: with:
project_id: 'my-project' project_id: 'my-project'
workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider' workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider'
@ -80,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 > SDK](https://github.com/firebase/firebase-admin-node/issues/1377). Use Service
> Account Key JSON authentication instead. > 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 The following inputs are for _authenticating_ to Google Cloud via Workload
Identity Federation. Identity Federation.
@ -191,6 +201,10 @@ Cloud as an output for use in future steps in the workflow. These options only
apply to ID tokens generated by this action. By default, this action does not apply to ID tokens generated by this action. By default, this action does not
generate any tokens. generate any tokens.
> [!CAUTION]
>
> ID Tokens have a maximum lifetime of 10 minutes. This value cannot be changed.
- `service_account`: (Required) Email address or unique identifier of the - `service_account`: (Required) Email address or unique identifier of the
Google Cloud service account for which to generate the ID token. For Google Cloud service account for which to generate the ID token. For
example: example:
@ -208,24 +222,6 @@ generate any tokens.
will contain "email" and "email_verified" claims. This is only valid when will contain "email" and "email_verified" claims. This is only valid when
"token_format" is "id_token". The default value is false. "token_format" is "id_token". The default value is false.
### Inputs: Retry options
The following inputs are for controlling retry behavior. By default, this GitHub
Action will retry API calls in an attempt to reduce transient failures. You can
control and disable the retry behavior with these inputs.
- `retries`: (Optional) Number of times to retry a failed authentication
attempt. This is useful for automated pipelines that may execute before IAM
permissions are fully propogated or intermittent connectivity failures. The
default value is "3".
- `backoff`: (Optional) Delay time before trying another authentication
attempt. This is implemented using a fibonacci backoff method (e.g.
1-1-2-3-5). This value defaults to 250 milliseconds.
- `backoff_limit`: (Optional) Limits the retry backoff to the specified value.
The default value is no limit.
### Inputs: Miscellaneous ### Inputs: Miscellaneous
The following inputs are for controlling the behavior of this GitHub Actions, The following inputs are for controlling the behavior of this GitHub Actions,
@ -253,7 +249,7 @@ regardless of the authentication mechanism.
job_id: job_id:
steps: steps:
- uses: 'actions/checkout@v4' # Must come first! - 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 - `export_environment_variables`: (Optional) If true, the action will export
@ -287,13 +283,22 @@ regardless of the authentication mechanism.
https://cloud.google.com. Trusted Partner Cloud and Google Distributed https://cloud.google.com. Trusted Partner Cloud and Google Distributed
Hosted Cloud should set this to their universe address. Hosted Cloud should set this to their universe address.
You can also override individual API endpoints by setting the environment variable `GHA_ENDPOINT_OVERRIDE_<endpoint>` where endpoint is the API endpoint to override. This only applies to the `auth` action and does not persist to other steps. For example: You can also override individual API endpoints by setting the environment
variable `GHA_ENDPOINT_OVERRIDE_<endpoint>` where endpoint is the API
endpoint to override. This only applies to the `auth` action and does not
persist to other steps. For example:
```yaml ```yaml
env: env:
GHA_ENDPOINT_OVERRIDE_oauth2: 'https://oauth2.myapi.endpoint/v1' GHA_ENDPOINT_OVERRIDE_oauth2: 'https://oauth2.myapi.endpoint/v1'
``` ```
- `request_reason`: (Optional) An optional Reason Request [System
Parameter](https://cloud.google.com/apis/docs/system-parameters) for each
API call made by the GitHub Action. This will inject the
"X-Goog-Request-Reason" HTTP header, which will provide user-supplied
information in Google Cloud audit logs.
- `cleanup_credentials`: (Optional) If true, the action will remove any - `cleanup_credentials`: (Optional) If true, the action will remove any
created credentials from the filesystem upon completion. This only applies created credentials from the filesystem upon completion. This only applies
if "create_credentials_file" is true. The default is true. if "create_credentials_file" is true. The default is true.
@ -317,7 +322,6 @@ regardless of the authentication mechanism.
"token_format" is "id_token". "token_format" is "id_token".
<a id="setup"></a> <a id="setup"></a>
## Setup ## Setup
@ -342,8 +346,8 @@ In this setup, the Workload Identity Pool has direct IAM permissions on Google
Cloud resources; there are no intermediate service accounts or keys. This is Cloud resources; there are no intermediate service accounts or keys. This is
preferred since it directly authenticates GitHub Actions to Google Cloud without preferred since it directly authenticates GitHub Actions to Google Cloud without
a proxy resource. However, not all Google Cloud resources support `principalSet` a proxy resource. However, not all Google Cloud resources support `principalSet`
identities. Please see the documentation for your Google Cloud service for more identities, and the resulting token has a maximum lifetime of 10 minutes. Please
information. see the documentation for your Google Cloud service for more information.
[![Authenticate to Google Cloud from GitHub Actions with Direct Workload Identity Federation](docs/google-github-actions-auth-direct-workload-identity-federation.svg)](docs/google-github-actions-auth-direct-workload-identity-federation.svg) [![Authenticate to Google Cloud from GitHub Actions with Direct Workload Identity Federation](docs/google-github-actions-auth-direct-workload-identity-federation.svg)](docs/google-github-actions-auth-direct-workload-identity-federation.svg)
@ -363,6 +367,8 @@ These instructions use the [gcloud][gcloud] command-line tool.
1. Create a Workload Identity Pool: 1. Create a Workload Identity Pool:
```sh ```sh
# TODO: replace ${PROJECT_ID} with your value below.
gcloud iam workload-identity-pools create "github" \ gcloud iam workload-identity-pools create "github" \
--project="${PROJECT_ID}" \ --project="${PROJECT_ID}" \
--location="global" \ --location="global" \
@ -372,6 +378,8 @@ These instructions use the [gcloud][gcloud] command-line tool.
1. Get the full ID of the Workload Identity **Pool**: 1. Get the full ID of the Workload Identity **Pool**:
```sh ```sh
# TODO: replace ${PROJECT_ID} with your value below.
gcloud iam workload-identity-pools describe "github" \ gcloud iam workload-identity-pools describe "github" \
--project="${PROJECT_ID}" \ --project="${PROJECT_ID}" \
--location="global" \ --location="global" \
@ -386,29 +394,35 @@ These instructions use the [gcloud][gcloud] command-line tool.
1. Create a Workload Identity **Provider** in that pool: 1. Create a Workload Identity **Provider** in that pool:
**🛑 CAUTION!** Always add an Attribute Condition to restrict entry into the
Workload Identity Pool. You can further restrict access in IAM Bindings, but
always add a basic condition that restricts admission into the pool. A good
default option is to restrict admission based on your GitHub organization as
demonstrated below. Please see the [security
considerations][security-considerations] for more details.
```sh ```sh
# TODO: replace ${PROJECT_ID} and ${GITHUB_ORG} with your values below.
gcloud iam workload-identity-pools providers create-oidc "my-repo" \ gcloud iam workload-identity-pools providers create-oidc "my-repo" \
--project="${PROJECT_ID}" \ --project="${PROJECT_ID}" \
--location="global" \ --location="global" \
--workload-identity-pool="github" \ --workload-identity-pool="github" \
--display-name="My GitHub repo Provider" \ --display-name="My GitHub repo Provider" \
--attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.repository=assertion.repository" \ --attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.repository=assertion.repository,attribute.repository_owner=assertion.repository_owner" \
--attribute-condition="assertion.repository_owner == '${GITHUB_ORG}'" \
--issuer-uri="https://token.actions.githubusercontent.com" --issuer-uri="https://token.actions.githubusercontent.com"
``` ```
The attribute mappings map claims in the GitHub Actions JWT to assertions > **❗️ IMPORTANT** You must map any claims in the incoming token to
you can make about the request (like the repository or GitHub username of > attributes before you can assert on those attributes in a CEL expression
the principal invoking the GitHub Action). These can be used to further > or IAM policy!
restrict the authentication using `--attribute-condition` flags.
> [!IMPORTANT]
>
> You must map any claims in the incoming token to attributes before you can
> assert on those attributes in a CEL expression or IAM policy!
1. Extract the Workload Identity **Provider** resource name: 1. Extract the Workload Identity **Provider** resource name:
```sh ```sh
# TODO: replace ${PROJECT_ID} with your value below.
gcloud iam workload-identity-pools providers describe "my-repo" \ gcloud iam workload-identity-pools providers describe "my-repo" \
--project="${PROJECT_ID}" \ --project="${PROJECT_ID}" \
--location="global" \ --location="global" \
@ -420,18 +434,16 @@ These instructions use the [gcloud][gcloud] command-line tool.
Actions YAML: Actions YAML:
```yaml ```yaml
- uses: 'google-github-actions/auth@v2' - uses: 'google-github-actions/auth@v3'
with: with:
project_id: 'my-project' project_id: 'my-project'
workload_identity_provider: '...' # "projects/123456789/locations/global/workloadIdentityPools/github/providers/my-repo" workload_identity_provider: '...' # "projects/123456789/locations/global/workloadIdentityPools/github/providers/my-repo"
``` ```
> [!IMPORTANT] > **❗️ IMPORTANT** The `project_id` input is optional, but may be required
> > by downstream authentication systems such as the `gcloud` CLI.
> The `project_id` input is optional, but may be required by downstream > Unfortunately we cannot extract the project ID from the Workload Identity
> authentication systems such as the `gcloud` CLI. Unfortunately we cannot > Provider, since it requires the project _number_.
> extract the project ID from the Workload Identity Provider, since it
> requires the project _number_.
> >
> It is technically possible to convert a project _number_ into a project > It is technically possible to convert a project _number_ into a project
> _ID_, but it requires permissions to call Cloud Resource Manager, and we > _ID_, but it requires permissions to call Cloud Resource Manager, and we
@ -446,9 +458,14 @@ These instructions use the [gcloud][gcloud] command-line tool.
specific repository a secret in Google Secret Manager. specific repository a secret in Google Secret Manager.
```sh ```sh
# TODO(developer): Update this value to your GitHub repository. # TODO: replace ${PROJECT_ID}, ${WORKLOAD_IDENTITY_POOL_ID}, and ${REPO}
export REPO="username/name" # e.g. "google/chrome" # with your values below.
export WORKLOAD_IDENTITY_POOL_ID="value/from/above" # e.g. "projects/123456789/locations/global/workloadIdentityPools/github" #
# ${REPO} is the full repo name including the parent GitHub organization,
# such as "my-org/my-repo".
#
# ${WORKLOAD_IDENTITY_POOL_ID} is the full pool id, such as
# "projects/123456789/locations/global/workloadIdentityPools/github".
gcloud secrets add-iam-policy-binding "my-secret" \ gcloud secrets add-iam-policy-binding "my-secret" \
--project="${PROJECT_ID}" \ --project="${PROJECT_ID}" \
@ -482,6 +499,8 @@ These instructions use the [gcloud][gcloud] command-line tool.
Service Account, take note of the email address and skip this step. Service Account, take note of the email address and skip this step.
```sh ```sh
# TODO: replace ${PROJECT_ID} with your value below.
gcloud iam service-accounts create "my-service-account" \ gcloud iam service-accounts create "my-service-account" \
--project "${PROJECT_ID}" --project "${PROJECT_ID}"
``` ```
@ -489,6 +508,8 @@ These instructions use the [gcloud][gcloud] command-line tool.
1. Create a Workload Identity Pool: 1. Create a Workload Identity Pool:
```sh ```sh
# TODO: replace ${PROJECT_ID} with your value below.
gcloud iam workload-identity-pools create "github" \ gcloud iam workload-identity-pools create "github" \
--project="${PROJECT_ID}" \ --project="${PROJECT_ID}" \
--location="global" \ --location="global" \
@ -498,6 +519,8 @@ These instructions use the [gcloud][gcloud] command-line tool.
1. Get the full ID of the Workload Identity **Pool**: 1. Get the full ID of the Workload Identity **Pool**:
```sh ```sh
# TODO: replace ${PROJECT_ID} with your value below.
gcloud iam workload-identity-pools describe "github" \ gcloud iam workload-identity-pools describe "github" \
--project="${PROJECT_ID}" \ --project="${PROJECT_ID}" \
--location="global" \ --location="global" \
@ -512,33 +535,42 @@ These instructions use the [gcloud][gcloud] command-line tool.
1. Create a Workload Identity **Provider** in that pool: 1. Create a Workload Identity **Provider** in that pool:
**🛑 CAUTION!** Always add an Attribute Condition to restrict entry into the
Workload Identity Pool. You can further restrict access in IAM Bindings, but
always add a basic condition that restricts admission into the pool. A good
default option is to restrict admission based on your GitHub organization as
demonstrated below. Please see the [security
considerations][security-considerations] for more details.
```sh ```sh
# TODO: replace ${PROJECT_ID} and ${GITHUB_ORG} with your values below.
gcloud iam workload-identity-pools providers create-oidc "my-repo" \ gcloud iam workload-identity-pools providers create-oidc "my-repo" \
--project="${PROJECT_ID}" \ --project="${PROJECT_ID}" \
--location="global" \ --location="global" \
--workload-identity-pool="github" \ --workload-identity-pool="github" \
--display-name="My GitHub repo Provider" \ --display-name="My GitHub repo Provider" \
--attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.repository=assertion.repository" \ --attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.repository=assertion.repository,attribute.repository_owner=assertion.repository_owner" \
--attribute-condition="assertion.repository_owner == '${GITHUB_ORG}'" \
--issuer-uri="https://token.actions.githubusercontent.com" --issuer-uri="https://token.actions.githubusercontent.com"
``` ```
The attribute mappings map claims in the GitHub Actions JWT to assertions > **❗️ IMPORTANT** You must map any claims in the incoming token to
you can make about the request (like the repository or GitHub username of > attributes before you can assert on those attributes in a CEL expression
the principal invoking the GitHub Action). These can be used to further > or IAM policy!
restrict the authentication using `--attribute-condition` flags.
> [!IMPORTANT]
>
> You must map any claims in the incoming token to attributes before you can
> assert on those attributes in a CEL expression or IAM policy!**
1. Allow authentications from the Workload Identity Pool to your Google Cloud 1. Allow authentications from the Workload Identity Pool to your Google Cloud
Service Account. Service Account.
```sh ```sh
# TODO(developer): Update this value to your GitHub repository. # TODO: replace ${PROJECT_ID}, ${WORKLOAD_IDENTITY_POOL_ID}, and ${REPO}
export REPO="username/name" # e.g. "google/chrome" # with your values below.
export WORKLOAD_IDENTITY_POOL_ID="value/from/above" # e.g. "projects/123456789/locations/global/workloadIdentityPools/github" #
# ${REPO} is the full repo name including the parent GitHub organization,
# such as "my-org/my-repo".
#
# ${WORKLOAD_IDENTITY_POOL_ID} is the full pool id, such as
# "projects/123456789/locations/global/workloadIdentityPools/github".
gcloud iam service-accounts add-iam-policy-binding "my-service-account@${PROJECT_ID}.iam.gserviceaccount.com" \ gcloud iam service-accounts add-iam-policy-binding "my-service-account@${PROJECT_ID}.iam.gserviceaccount.com" \
--project="${PROJECT_ID}" \ --project="${PROJECT_ID}" \
@ -553,6 +585,8 @@ These instructions use the [gcloud][gcloud] command-line tool.
1. Extract the Workload Identity **Provider** resource name: 1. Extract the Workload Identity **Provider** resource name:
```sh ```sh
# TODO: replace ${PROJECT_ID} with your value below.
gcloud iam workload-identity-pools providers describe "my-repo" \ gcloud iam workload-identity-pools providers describe "my-repo" \
--project="${PROJECT_ID}" \ --project="${PROJECT_ID}" \
--location="global" \ --location="global" \
@ -564,7 +598,7 @@ These instructions use the [gcloud][gcloud] command-line tool.
Actions YAML: Actions YAML:
```yaml ```yaml
- uses: 'google-github-actions/auth@v2' - uses: 'google-github-actions/auth@v3'
with: with:
service_account: '...' # my-service-account@my-project.iam.gserviceaccount.com service_account: '...' # my-service-account@my-project.iam.gserviceaccount.com
workload_identity_provider: '...' # "projects/123456789/locations/global/workloadIdentityPools/github/providers/my-repo" workload_identity_provider: '...' # "projects/123456789/locations/global/workloadIdentityPools/github/providers/my-repo"
@ -575,6 +609,8 @@ These instructions use the [gcloud][gcloud] command-line tool.
shows granting access to a secret in Google Secret Manager. shows granting access to a secret in Google Secret Manager.
```sh ```sh
# TODO: replace ${PROJECT_ID} with your value below.
gcloud secrets add-iam-policy-binding "my-secret" \ gcloud secrets add-iam-policy-binding "my-secret" \
--project="${PROJECT_ID}" \ --project="${PROJECT_ID}" \
--role="roles/secretmanager.secretAccessor" \ --role="roles/secretmanager.secretAccessor" \
@ -595,7 +631,7 @@ as a secret.
> [!CAUTION] > [!CAUTION]
> >
> Google Cloud Service Account Key JSON files must be secured > Google Cloud Service Account Key JSON files must be secured
> and treated like a password. Anyone with acess to the JSON key can > and treated like a password. Anyone with access to the JSON key can
> authenticate to Google Cloud as the underlying Service Account. By default, > authenticate to Google Cloud as the underlying Service Account. By default,
> these credentials never expire, which is why the former authentication options > these credentials never expire, which is why the former authentication options
> are much preferred. > are much preferred.
@ -609,6 +645,8 @@ These instructions use the [gcloud][gcloud] command-line tool.
Service Account, take note of the email address and skip this step. Service Account, take note of the email address and skip this step.
```sh ```sh
# TODO: replace ${PROJECT_ID} with your value below.
gcloud iam service-accounts create "my-service-account" \ gcloud iam service-accounts create "my-service-account" \
--project "${PROJECT_ID}" --project "${PROJECT_ID}"
``` ```
@ -616,6 +654,8 @@ These instructions use the [gcloud][gcloud] command-line tool.
1. Create a Service Account Key JSON for the Service Account. 1. Create a Service Account Key JSON for the Service Account.
```sh ```sh
# TODO: replace ${PROJECT_ID} with your value below.
gcloud iam service-accounts keys create "key.json" \ gcloud iam service-accounts keys create "key.json" \
--iam-account "my-service-account@${PROJECT_ID}.iam.gserviceaccount.com" --iam-account "my-service-account@${PROJECT_ID}.iam.gserviceaccount.com"
``` ```
@ -623,11 +663,11 @@ These instructions use the [gcloud][gcloud] command-line tool.
1. Upload the contents of this file as a [GitHub Actions 1. Upload the contents of this file as a [GitHub Actions
Secret](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions). Secret](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions).
Use the name of the GitHub Actios secret as the `credentials_json` value in Use the name of the GitHub Actions secret as the `credentials_json` value in
the GitHub Actions YAML: the GitHub Actions YAML:
```yaml ```yaml
- uses: 'google-github-actions/auth@v2' - uses: 'google-github-actions/auth@v3'
with: with:
credentials_json: '${{ secrets.GOOGLE_CREDENTIALS }}' # Replace with the name of your GitHub Actions secret credentials_json: '${{ secrets.GOOGLE_CREDENTIALS }}' # Replace with the name of your GitHub Actions secret
``` ```
@ -639,3 +679,4 @@ These instructions use the [gcloud][gcloud] command-line tool.
[github-perms]: https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#permissions [github-perms]: https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#permissions
[map-external]: https://cloud.google.com/iam/docs/access-resources-oidc#impersonate [map-external]: https://cloud.google.com/iam/docs/access-resources-oidc#impersonate
[wif]: https://cloud.google.com/iam/docs/workload-identity-federation [wif]: https://cloud.google.com/iam/docs/workload-identity-federation
[security-considerations]: docs/SECURITY_CONSIDERATIONS.md

View file

@ -56,7 +56,7 @@ inputs:
description: |- description: |-
If true, the action will securely generate a credentials file which can be If true, the action will securely generate a credentials file which can be
used for authentication via gcloud and Google Cloud SDKs. used for authentication via gcloud and Google Cloud SDKs.
default: true default: 'true'
required: false required: false
export_environment_variables: export_environment_variables:
description: |- description: |-
@ -79,7 +79,7 @@ inputs:
If false, the action will not export any environment variables, meaning If false, the action will not export any environment variables, meaning
future steps are unlikely to be automatically authenticated to Google future steps are unlikely to be automatically authenticated to Google
Cloud. Cloud.
default: true default: 'true'
required: false required: false
token_format: token_format:
description: |- description: |-
@ -102,12 +102,18 @@ inputs:
Hosted Cloud should set this to their universe address. Hosted Cloud should set this to their universe address.
required: false required: false
default: 'googleapis.com' default: 'googleapis.com'
request_reason:
description: |-
An optional Reason Request System Parameter for each API call made by the
GitHub Action. This will inject the "X-Goog-Request-Reason" HTTP header,
which will provide user-supplied information in Google Cloud audit logs.
required: false
cleanup_credentials: cleanup_credentials:
description: |- description: |-
If true, the action will remove any created credentials from the If true, the action will remove any created credentials from the
filesystem upon completion. This only applies if "create_credentials_file" filesystem upon completion. This only applies if "create_credentials_file"
is true. is true.
default: true default: 'true'
required: false required: false
# access token params # access token params
@ -132,30 +138,6 @@ inputs:
default: '' default: ''
required: false 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
propogated.
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 params
id_token_audience: id_token_audience:
description: |- description: |-
@ -169,7 +151,7 @@ inputs:
generated token. If true, the token will contain "email" and generated token. If true, the token will contain "email" and
"email_verified" claims. This is only valid when "token_format" is "email_verified" claims. This is only valid when "token_format" is
"id_token". "id_token".
default: false default: 'false'
required: false required: false
outputs: outputs:
@ -198,6 +180,6 @@ branding:
color: 'blue' color: 'blue'
runs: runs:
using: 'node20' using: 'node24'
main: 'dist/main/index.js' main: 'dist/main/index.js'
post: 'dist/post/index.js' post: 'dist/post/index.js'

View file

@ -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

File diff suppressed because one or more lines are too long

6
dist/post/index.js vendored

File diff suppressed because one or more lines are too long

View file

@ -20,7 +20,7 @@ jobs:
id-token: 'write' id-token: 'write'
- id: 'auth' - id: 'auth'
uses: 'google-github-actions/auth@v2' uses: 'google-github-actions/auth@v3'
with: with:
project_id: 'my-project' project_id: 'my-project'
workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider' workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider'
@ -45,7 +45,7 @@ jobs:
contents: 'read' contents: 'read'
id-token: 'write' id-token: 'write'
- uses: 'google-github-actions/auth@v2' - uses: 'google-github-actions/auth@v3'
with: with:
project_id: 'my-project' project_id: 'my-project'
workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider' 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 # the service account, specify the 'token_format' parameter and use the
# 'accesss_token' output. # 'accesss_token' output.
# #
# - uses: 'google-github-actions/auth@v2' # - uses: 'google-github-actions/auth@v3'
# with: # with:
# workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider' # workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider'
# service_account: 'my-service-account@my-project.iam.gserviceaccount.com' # service_account: 'my-service-account@my-project.iam.gserviceaccount.com'
@ -79,7 +79,7 @@ jobs:
steps: steps:
- uses: 'actions/checkout@v4' - uses: 'actions/checkout@v4'
- uses: 'google-github-actions/auth@v2' - uses: 'google-github-actions/auth@v3'
with: with:
credentials_json: '${{ secrets.GOOGLE_CREDENTIALS }}' credentials_json: '${{ secrets.GOOGLE_CREDENTIALS }}'
``` ```
@ -100,7 +100,7 @@ jobs:
- uses: 'actions/checkout@v4' - uses: 'actions/checkout@v4'
- id: 'auth' - id: 'auth'
uses: 'google-github-actions/auth@v2' uses: 'google-github-actions/auth@v3'
with: with:
project_id: 'my-project' project_id: 'my-project'
workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider' workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider'
@ -136,7 +136,7 @@ jobs:
- uses: 'actions/checkout@v4' - uses: 'actions/checkout@v4'
- id: 'auth' - id: 'auth'
uses: 'google-github-actions/auth@v2' uses: 'google-github-actions/auth@v3'
with: with:
token_format: 'access_token' # <-- token_format: 'access_token' # <--
workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider' workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider'
@ -173,7 +173,7 @@ jobs:
- uses: 'actions/checkout@v4' - uses: 'actions/checkout@v4'
- id: 'auth' - id: 'auth'
uses: 'google-github-actions/auth@v2' uses: 'google-github-actions/auth@v3'
with: with:
token_format: 'id_token' # <-- token_format: 'id_token' # <--
workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider' workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider'
@ -187,6 +187,69 @@ jobs:
run: |- run: |-
curl https://myapp-uvehjacqzq.a.run.app \ curl https://myapp-uvehjacqzq.a.run.app \
--header "Authorization: Bearer ${{ steps.auth.outputs.id_token }}" --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/ [github-markdown-toc]: https://github.blog/changelog/2021-04-13-table-of-contents-support-in-markdown-files/

View file

@ -0,0 +1,47 @@
# Security Considerations
There are important risks to consider when mapping GitHub Actions OIDC token
claims.
## Use Unique Mapping Values
Many of the claims embedded in the GitHub Actions OIDC token are not guaranteed
to be unique, and tokens issued by other GitHub organizations or repositories
may contain the same values, allowing them to establish an identity. To protect
against this situation, always use an Attribute Condition to restrict access to
tokens issued by your GitHub organization.
```cel
assertion.repository_owner == 'my-github-org'
```
Never use a "*" in an IAM Binding unless you absolutely know what you are doing!
## Use GitHub's Numeric, Immutable Values
Using "name" fields in Attribute Conditions or IAM Bindings like `repository` and `repository_owner` increase the chances of [cybersquatting][] and [typosquatting][] attacks. If you delete your GitHub repository or GitHub organization, someone could claim that same name and establish an identity. To protect against this situation, use the numeric `*_id` fields instead, which GitHub guarantees to be unique and never re-used.
To get your numeric organization ID:
```sh
ORG="my-org" # TODO: replace with your org
curl -sfL -H "Accept: application/json" "https://api.github.com/orgs/${ORG}" | jq .id
```
To get your numeric repository ID:
```sh
REPO="my-org/my-repo" # TODO: replace with your full repo including the org
curl -sfL -H "Accept: application/json" "https://api.github.com/repos/${REPO}" | jq .id
```
These can be used in an Attribute Condition:
```cel
assertion.repository_owner_id == '1342004' && assertion.repository_id == '260064828'
```
[cybersquatting]: https://en.wikipedia.org/wiki/Cybersquatting
[typosquatting]: https://en.wikipedia.org/wiki/Typosquatting

View file

@ -6,10 +6,8 @@
see exactly which step is failing. Ensure you are using the latest version see exactly which step is failing. Ensure you are using the latest version
of the GitHub Action. of the GitHub Action.
> [!CAUTION] > **⚠️ WARNING!** Enabling debug logging increases the chances of a secret
> > being accidentally logged. While GitHub Actions will scrub secrets,
> Enabling debug logging increases the chances of a secret
> being accidentially logged. While GitHub Actions will scrub secrets,
> please take extra caution when sharing these debug logs in publicly > please take extra caution when sharing these debug logs in publicly
> accessible places like GitHub issues. > accessible places like GitHub issues.
> >
@ -29,7 +27,7 @@
```yaml ```yaml
steps: steps:
- uses: 'actions/checkout@v4' - 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_ 1. Ensure the value for `workload_identity_provider` is the full _Provider_
@ -46,7 +44,7 @@
```diff ```diff
- projects/my-project/locations/global/workloadIdentityPools/my-pool/providers/my-provider - 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 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 GitHub OIDC token. You cannot grant permissions on an attribute unless you
map that value from the incoming GitHub OIDC token. map that value from the incoming GitHub OIDC token.
> [!TIP] > ** TIP!** Use the [GitHub Actions OIDC Debugger][oidc-debugger] to print
> > the list of token claims and compare them to your Attribute Mappings and
> Use the [GitHub Actions OIDC Debugger][oidc-debugger] to print the list of > Attribute Conditions.
> token claims and compare them to your Attribute Mappings and Attribute
> Conditions.
1. Ensure you have the correct character casing and capitalization. GitHub does 1. Ensure you have the correct character casing and capitalization. GitHub does
not distinguish between "foobar" and "FooBar", but Google Cloud does. Ensure not distinguish between "foobar" and "FooBar", but Google Cloud does. Ensure
@ -81,7 +77,7 @@
token", it means admission into the Workload Identity Pool failed. Check token", it means admission into the Workload Identity Pool failed. Check
your [**Attribute Conditions**][attribute-conditions]. your [**Attribute Conditions**][attribute-conditions].
- If the error message inclues "Failed to generate OAuth 2.0 Access - If the error message includes "Failed to generate OAuth 2.0 Access
Token", it means Service Account Impersonation failed. Check your Token", it means Service Account Impersonation failed. Check your
[**Service Account Impersonation**][sa-impersonation] settings and [**Service Account Impersonation**][sa-impersonation] settings and
ensure the principalSet is correct. ensure the principalSet is correct.
@ -89,10 +85,8 @@
1. Enable `Admin Read`, `Data Read`, and `Data Write` [Audit Logging][cal] for 1. Enable `Admin Read`, `Data Read`, and `Data Write` [Audit Logging][cal] for
Identity and Access Management (IAM) in your Google Cloud project. Identity and Access Management (IAM) in your Google Cloud project.
> [!WARNING] > **⚠️ WARNING!** This will increase log volume which may increase costs.
> > You can disable this audit logging after you have debugged the issue.
> 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 Try to authenticate again, and then explore the logs for your Workload
Identity Provider and Workload Identity Pool. Sometimes these error messages Identity Provider and Workload Identity Pool. Sometimes these error messages
@ -236,11 +230,56 @@ tool like `jq`:
cat credentials.json | jq -r tostring 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 ## Organizational Policy Constraints
> [!NOTE] > ** NOTE!** Your Google Cloud organization administrator controls these
>
> Your Google Cloud organization administrator controls these
> policies. You must work with your internal IT department to resolve OrgPolicy > policies. You must work with your internal IT department to resolve OrgPolicy
> violations and constraints. > violations and constraints.

18
eslint.config.mjs Normal file
View file

@ -0,0 +1,18 @@
import js from '@eslint/js';
import ts from 'typescript-eslint';
import tsParser from '@typescript-eslint/parser';
import prettierRecommended from 'eslint-plugin-prettier/recommended';
export default ts.config(
js.configs.recommended,
ts.configs.eslintRecommended,
{
files: ['**/*.ts', '**/*.tsx'],
languageOptions: {
parser: tsParser,
},
},
{ ignores: ['dist/', '**/*.js'] },
prettierRecommended,
);

1458
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,13 +1,17 @@
{ {
"name": "@google-github-actions/auth", "name": "@google-github-actions/auth",
"version": "2.1.1", "version": "3.0.0",
"description": "Authenticate to Google Cloud using OIDC tokens or JSON service account keys.", "description": "Authenticate to Google Cloud using OIDC tokens or JSON service account keys.",
"main": "dist/main/index.js", "main": "dist/main/index.js",
"scripts": { "scripts": {
"build": "ncc build -m src/main.ts -o dist/main && ncc build -m src/post.ts -o dist/post", "build": "ncc build -m src/main.ts -o dist/main && ncc build -m src/post.ts -o dist/post",
"lint": "eslint . --ext .ts,.tsx", "lint": "eslint .",
"format": "prettier --write **/*.ts", "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": { "repository": {
"type": "git", "type": "git",
@ -23,20 +27,22 @@
"author": "GoogleCloudPlatform", "author": "GoogleCloudPlatform",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@actions/core": "^1.10.1", "@actions/core": "^1.11.1",
"@actions/http-client": "^2.2.0", "@actions/http-client": "^2.2.3",
"@google-github-actions/actions-utils": "^0.7.0" "@google-github-actions/actions-utils": "^1.0.1"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^20.11.5", "@eslint/eslintrc": "^3.3.1",
"@typescript-eslint/eslint-plugin": "^6.19.1", "@eslint/js": "^9.34.0",
"@typescript-eslint/parser": "^6.19.1", "@types/node": "^24.3.0",
"@vercel/ncc": "^0.38.1", "@vercel/ncc": "^0.38.3",
"eslint": "^8.56.0", "eslint-config-prettier": "^10.1.8",
"eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.5.4",
"eslint-plugin-prettier": "^5.1.3", "eslint": "^9.34.0",
"prettier": "^3.2.4", "prettier": "^3.6.2",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typescript": "^5.3.3" "typescript-eslint": "^8.41.0",
"@typescript-eslint/eslint-plugin": "^8.41.0",
"typescript": "^5.9.2"
} }
} }

View file

@ -14,6 +14,8 @@
import { HttpClient } from '@actions/http-client'; import { HttpClient } from '@actions/http-client';
import { expandUniverseEndpoints } from '@google-github-actions/actions-utils';
import { Logger } from '../logger'; import { Logger } from '../logger';
import { userAgent } from '../utils'; import { userAgent } from '../utils';
@ -32,23 +34,24 @@ export interface AuthClient {
* other Google Cloud tools) that instructs the tool how to perform identity * other Google Cloud tools) that instructs the tool how to perform identity
* federation. * federation.
*/ */
createCredentialsFile(outputPath: string): Promise<string>; createCredentialsFile(outputPath: string): Promise<string>; // eslint-disable-line no-unused-vars
/** /**
* signJWT signs a JWT using the auth provider. * signJWT signs a JWT using the auth provider.
*/ */
signJWT(claims: any): Promise<string>; signJWT(claims: any): Promise<string>; // eslint-disable-line no-unused-vars
} }
export interface ClientParameters { export interface ClientParameters {
logger: Logger; logger: Logger;
universe: string; universe: string;
child: string; requestReason?: string;
} }
export class Client { export abstract class Client {
protected readonly _logger: Logger; protected readonly _logger: Logger;
protected readonly _httpClient: HttpClient; protected readonly _httpClient: HttpClient;
private readonly _requestReason: string | undefined;
protected readonly _endpoints = { protected readonly _endpoints = {
iam: 'https://iam.{universe}/v1', iam: 'https://iam.{universe}/v1',
@ -57,10 +60,9 @@ export class Client {
sts: 'https://sts.{universe}/v1', sts: 'https://sts.{universe}/v1',
www: 'https://www.{universe}', www: 'https://www.{universe}',
}; };
protected readonly _universe;
constructor(opts: ClientParameters) { constructor(child: string, opts: ClientParameters) {
this._logger = opts.logger.withNamespace(opts.child); this._logger = opts.logger.withNamespace(child);
// Create the http client with our user agent. // Create the http client with our user agent.
this._httpClient = new HttpClient(userAgent, undefined, { this._httpClient = new HttpClient(userAgent, undefined, {
@ -71,26 +73,19 @@ export class Client {
maxRetries: 3, maxRetries: 3,
}); });
// Expand universe to support TPC and custom endpoints. this._endpoints = expandUniverseEndpoints(this._endpoints, opts.universe);
this._universe = opts.universe; this._requestReason = opts.requestReason;
for (const key of Object.keys(this._endpoints) as Array<keyof typeof this._endpoints>) {
this._endpoints[key] = this.expandEndpoint(key);
}
this._logger.debug(`Computed endpoints for universe ${this._universe}`, this._endpoints);
} }
expandEndpoint(key: keyof typeof this._endpoints): string { /**
const envOverrideKey = `GHA_ENDPOINT_OVERRIDE_${key}`; * _headers returns any added headers to apply to HTTP API calls.
const envOverrideValue = process.env[envOverrideKey]; */
if (envOverrideValue && envOverrideValue !== '') { protected _headers(): Record<string, string> {
this._logger.debug( const headers: Record<string, string> = {};
`Overriding API endpoint for ${key} because ${envOverrideKey} is set`, if (this._requestReason) {
envOverrideValue, headers['X-Goog-Request-Reason'] = this._requestReason;
);
return envOverrideValue.replace(/\/+$/, '');
} }
return headers;
return (this._endpoints[key] || '').replace(/{universe}/g, this._universe).replace(/\/+$/, '');
} }
} }
export { IAMCredentialsClient, IAMCredentialsClientParameters } from './iamcredentials'; export { IAMCredentialsClient, IAMCredentialsClientParameters } from './iamcredentials';

View file

@ -16,8 +16,7 @@ import { URLSearchParams } from 'url';
import { errorMessage } from '@google-github-actions/actions-utils'; import { errorMessage } from '@google-github-actions/actions-utils';
import { Client } from './client'; import { Client, ClientParameters } from './client';
import { Logger } from '../logger';
/** /**
* GenerateAccessTokenParameters are the inputs to the generateAccessToken call. * GenerateAccessTokenParameters are the inputs to the generateAccessToken call.
@ -42,10 +41,7 @@ export interface GenerateIDTokenParameters {
/** /**
* IAMCredentialsClientParameters are the inputs to the IAM client. * IAMCredentialsClientParameters are the inputs to the IAM client.
*/ */
export interface IAMCredentialsClientParameters { export interface IAMCredentialsClientParameters extends ClientParameters {
readonly logger: Logger;
readonly universe: string;
readonly authToken: string; readonly authToken: string;
} }
@ -57,11 +53,7 @@ export class IAMCredentialsClient extends Client {
readonly #authToken: string; readonly #authToken: string;
constructor(opts: IAMCredentialsClientParameters) { constructor(opts: IAMCredentialsClientParameters) {
super({ super('IAMCredentialsClient', opts);
logger: opts.logger,
universe: opts.universe,
child: `IAMCredentialsClient`,
});
this.#authToken = opts.authToken; this.#authToken = opts.authToken;
} }
@ -80,7 +72,9 @@ export class IAMCredentialsClient extends Client {
const pth = `${this._endpoints.iamcredentials}/projects/-/serviceAccounts/${serviceAccount}:generateAccessToken`; const pth = `${this._endpoints.iamcredentials}/projects/-/serviceAccounts/${serviceAccount}:generateAccessToken`;
const headers = { Authorization: `Bearer ${this.#authToken}` }; const headers = Object.assign(this._headers(), {
Authorization: `Bearer ${this.#authToken}`,
});
const body: Record<string, string | Array<string>> = {}; const body: Record<string, string | Array<string>> = {};
if (delegates && delegates.length > 0) { if (delegates && delegates.length > 0) {
@ -126,10 +120,10 @@ export class IAMCredentialsClient extends Client {
const pth = `${this._endpoints.oauth2}/token`; const pth = `${this._endpoints.oauth2}/token`;
const headers = { const headers = Object.assign(this._headers(), {
'Accept': 'application/json', 'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded', 'Content-Type': 'application/x-www-form-urlencoded',
}; });
const body = new URLSearchParams(); const body = new URLSearchParams();
body.append('grant_type', 'urn:ietf:params:oauth:grant-type:jwt-bearer'); body.append('grant_type', 'urn:ietf:params:oauth:grant-type:jwt-bearer');
@ -173,7 +167,9 @@ export class IAMCredentialsClient extends Client {
const pth = `${this._endpoints.iamcredentials}/projects/-/serviceAccounts/${serviceAccount}:generateIdToken`; const pth = `${this._endpoints.iamcredentials}/projects/-/serviceAccounts/${serviceAccount}:generateIdToken`;
const headers = { Authorization: `Bearer ${this.#authToken}` }; const headers = Object.assign(this._headers(), {
Authorization: `Bearer ${this.#authToken}`,
});
const body: Record<string, string | string[] | boolean> = { const body: Record<string, string | string[] | boolean> = {
audience: audience, audience: audience,

View file

@ -23,17 +23,13 @@ import {
writeSecureFile, writeSecureFile,
} from '@google-github-actions/actions-utils'; } from '@google-github-actions/actions-utils';
import { AuthClient, Client } from './client'; import { AuthClient, Client, ClientParameters } from './client';
import { Logger } from '../logger';
/** /**
* ServiceAccountKeyClientParameters is used as input to the * ServiceAccountKeyClientParameters is used as input to the
* ServiceAccountKeyClient. * ServiceAccountKeyClient.
*/ */
export interface ServiceAccountKeyClientParameters { export interface ServiceAccountKeyClientParameters extends ClientParameters {
readonly logger: Logger;
readonly universe: string;
readonly serviceAccountKey: string; readonly serviceAccountKey: string;
} }
@ -46,11 +42,7 @@ export class ServiceAccountKeyClient extends Client implements AuthClient {
readonly #audience: string; readonly #audience: string;
constructor(opts: ServiceAccountKeyClientParameters) { constructor(opts: ServiceAccountKeyClientParameters) {
super({ super('ServiceAccountKeyClient', opts);
logger: opts.logger,
universe: opts.universe,
child: `ServiceAccountKeyClient`,
});
const serviceAccountKey = parseCredential(opts.serviceAccountKey); const serviceAccountKey = parseCredential(opts.serviceAccountKey);
if (!isServiceAccountKey(serviceAccountKey)) { if (!isServiceAccountKey(serviceAccountKey)) {

View file

@ -14,17 +14,13 @@
import { errorMessage, writeSecureFile } from '@google-github-actions/actions-utils'; import { errorMessage, writeSecureFile } from '@google-github-actions/actions-utils';
import { AuthClient, Client } from './client'; import { AuthClient, Client, ClientParameters } from './client';
import { Logger } from '../logger';
/** /**
* WorkloadIdentityFederationClientParameters is used as input to the * WorkloadIdentityFederationClientParameters is used as input to the
* WorkloadIdentityFederationClient. * WorkloadIdentityFederationClient.
*/ */
export interface WorkloadIdentityFederationClientParameters { export interface WorkloadIdentityFederationClientParameters extends ClientParameters {
readonly logger: Logger;
readonly universe: string;
readonly githubOIDCToken: string; readonly githubOIDCToken: string;
readonly githubOIDCTokenRequestURL: string; readonly githubOIDCTokenRequestURL: string;
readonly githubOIDCTokenRequestToken: string; readonly githubOIDCTokenRequestToken: string;
@ -51,11 +47,7 @@ export class WorkloadIdentityFederationClient extends Client implements AuthClie
#cachedAt?: number; #cachedAt?: number;
constructor(opts: WorkloadIdentityFederationClientParameters) { constructor(opts: WorkloadIdentityFederationClientParameters) {
super({ super('WorkloadIdentityFederationClient', opts);
logger: opts.logger,
universe: opts.universe,
child: `WorkloadIdentityFederationClient`,
});
this.#githubOIDCToken = opts.githubOIDCToken; this.#githubOIDCToken = opts.githubOIDCToken;
this.#githubOIDCTokenRequestURL = opts.githubOIDCTokenRequestURL; this.#githubOIDCTokenRequestURL = opts.githubOIDCTokenRequestURL;
@ -90,6 +82,8 @@ export class WorkloadIdentityFederationClient extends Client implements AuthClie
const pth = `${this._endpoints.sts}/token`; const pth = `${this._endpoints.sts}/token`;
const headers = Object.assign(this._headers(), {});
const body = { const body = {
audience: this.#audience, audience: this.#audience,
grantType: `urn:ietf:params:oauth:grant-type:token-exchange`, grantType: `urn:ietf:params:oauth:grant-type:token-exchange`,
@ -102,11 +96,12 @@ export class WorkloadIdentityFederationClient extends Client implements AuthClie
logger.debug(`Built request`, { logger.debug(`Built request`, {
method: `POST`, method: `POST`,
path: pth, path: pth,
headers: headers,
body: body, body: body,
}); });
try { try {
const resp = await this._httpClient.postJson<{ access_token: string }>(pth, body); const resp = await this._httpClient.postJson<{ access_token: string }>(pth, body, headers);
const statusCode = resp.statusCode || 500; const statusCode = resp.statusCode || 500;
if (statusCode < 200 || statusCode > 299) { if (statusCode < 200 || statusCode > 299) {
throw new Error(`Failed to call ${pth}: HTTP ${statusCode}: ${resp.result || '[no body]'}`); throw new Error(`Failed to call ${pth}: HTTP ${statusCode}: ${resp.result || '[no body]'}`);
@ -140,9 +135,9 @@ export class WorkloadIdentityFederationClient extends Client implements AuthClie
const pth = `${this._endpoints.iamcredentials}/projects/-/serviceAccounts/${this.#serviceAccount}:signJwt`; const pth = `${this._endpoints.iamcredentials}/projects/-/serviceAccounts/${this.#serviceAccount}:signJwt`;
const headers = { const headers = Object.assign(this._headers(), {
Authorization: `Bearer ${await this.getToken()}`, Authorization: `Bearer ${await this.getToken()}`,
}; });
const body = { const body = {
payload: claims, payload: claims,

View file

@ -25,6 +25,7 @@ import {
* LoggerFunction is the type signature of a log function for the GitHub Actions * LoggerFunction is the type signature of a log function for the GitHub Actions
* SDK. * SDK.
*/ */
// eslint-disable-next-line no-unused-vars
type LoggerFunction = (message: string, properties?: AnnotationProperties) => void; type LoggerFunction = (message: string, properties?: AnnotationProperties) => void;
/** /**

View file

@ -16,7 +16,6 @@ import { join as pathjoin } from 'path';
import { import {
exportVariable, exportVariable,
getBooleanInput,
getIDToken, getIDToken,
getInput, getInput,
setFailed, setFailed,
@ -29,8 +28,10 @@ import {
isEmptyDir, isEmptyDir,
isPinnedToHead, isPinnedToHead,
parseMultilineCSV, parseMultilineCSV,
parseBoolean,
parseDuration, parseDuration,
pinnedToHeadWarning, pinnedToHeadWarning,
withRetries,
} from '@google-github-actions/actions-utils'; } from '@google-github-actions/actions-utils';
import { import {
@ -79,11 +80,12 @@ export async function run(logger: Logger) {
const oidcTokenAudience = const oidcTokenAudience =
getInput(`audience`) || `https://iam.googleapis.com/${workloadIdentityProvider}`; getInput(`audience`) || `https://iam.googleapis.com/${workloadIdentityProvider}`;
const credentialsJSON = getInput(`credentials_json`); const credentialsJSON = getInput(`credentials_json`);
const createCredentialsFile = getBooleanInput(`create_credentials_file`); const createCredentialsFile = parseBoolean(getInput(`create_credentials_file`));
const exportEnvironmentVariables = getBooleanInput(`export_environment_variables`); const exportEnvironmentVariables = parseBoolean(getInput(`export_environment_variables`));
const tokenFormat = getInput(`token_format`); const tokenFormat = getInput(`token_format`);
const delegates = parseMultilineCSV(getInput(`delegates`)); const delegates = parseMultilineCSV(getInput(`delegates`));
const universe = getInput(`universe`); const universe = getInput(`universe`);
const requestReason = getInput(`request_reason`);
// Ensure exactly one of workload_identity_provider and credentials_json was // Ensure exactly one of workload_identity_provider and credentials_json was
// provided. // provided.
@ -109,10 +111,16 @@ export async function run(logger: Logger) {
throw new Error(oidcWarning); 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({ client = new WorkloadIdentityFederationClient({
logger: logger, logger: logger,
universe: universe, universe: universe,
requestReason: requestReason,
githubOIDCToken: oidcToken, githubOIDCToken: oidcToken,
githubOIDCTokenRequestURL: oidcTokenRequestURL, githubOIDCTokenRequestURL: oidcTokenRequestURL,
@ -126,6 +134,7 @@ export async function run(logger: Logger) {
client = new ServiceAccountKeyClient({ client = new ServiceAccountKeyClient({
logger: logger, logger: logger,
universe: universe, universe: universe,
requestReason: requestReason,
serviceAccountKey: credentialsJSON, serviceAccountKey: credentialsJSON,
}); });
@ -163,8 +172,8 @@ export async function run(logger: Logger) {
// repository. // repository.
const githubWorkspaceIsEmpty = await isEmptyDir(githubWorkspace); const githubWorkspaceIsEmpty = await isEmptyDir(githubWorkspace);
if (githubWorkspaceIsEmpty) { if (githubWorkspaceIsEmpty) {
logger.warning( logger.info(
`The "create_credentials_file" option is true, but the current ` + `⚠️ The "create_credentials_file" option is true, but the current ` +
`GitHub workspace is empty. Did you forget to use ` + `GitHub workspace is empty. Did you forget to use ` +
`"actions/checkout" before this step? If you do not intend to ` + `"actions/checkout" before this step? If you do not intend to ` +
`share authentication with future steps in this job, set ` + `share authentication with future steps in this job, set ` +
@ -198,9 +207,11 @@ export async function run(logger: Logger) {
// Set the project ID environment variables to the computed values. // Set the project ID environment variables to the computed values.
if (!projectID) { if (!projectID) {
logger.warning( logger.info(
`Unable to compute project ID from inputs, skipping export. Please ` + `⚠️ Failed to compute a project ID from the given inputs. Neither the ` +
`specify the "project_id" input directly.`, `"project_id" output nor any environment variables will be ` +
`exported. If you require these values in other steps, specify the ` +
`"project_id" input directly.`,
); );
} else { } else {
setOutput('project_id', projectID); setOutput('project_id', projectID);
@ -296,7 +307,7 @@ export async function run(logger: Logger) {
logger.debug(`Creating id token`); logger.debug(`Creating id token`);
const idTokenAudience = getInput('id_token_audience', { required: true }); 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. // Ensure a service_account was provided if using WIF.
if (!serviceAccount) { if (!serviceAccount) {

View file

@ -12,21 +12,21 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // 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'; import { Logger } from './logger';
export async function run(logger: Logger) { export async function run(logger: Logger) {
try { try {
const createCredentials = getBooleanInput('create_credentials_file'); const createCredentials = parseBoolean(getInput('create_credentials_file'));
if (!createCredentials) { if (!createCredentials) {
logger.info(`Skipping credential cleanup - "create_credentials_file" is false.`); logger.info(`Skipping credential cleanup - "create_credentials_file" is false.`);
return; return;
} }
const cleanupCredentials = getBooleanInput('cleanup_credentials'); const cleanupCredentials = parseBoolean(getInput('cleanup_credentials'));
if (!cleanupCredentials) { if (!cleanupCredentials) {
logger.info(`Skipping credential cleanup - "cleanup_credentials" is false.`); logger.info(`Skipping credential cleanup - "cleanup_credentials" is false.`);
return; return;
@ -34,7 +34,7 @@ export async function run(logger: Logger) {
// Look up the credentials path, if one exists. Note that we only check the // Look up the credentials path, if one exists. Note that we only check the
// environment variable set by our action, since we don't want to // environment variable set by our action, since we don't want to
// accidentially clean up if someone set GOOGLE_APPLICATION_CREDENTIALS or // accidentally clean up if someone set GOOGLE_APPLICATION_CREDENTIALS or
// another environment variable manually. // another environment variable manually.
const credentialsPath = process.env['GOOGLE_GHA_CREDS_PATH']; const credentialsPath = process.env['GOOGLE_GHA_CREDS_PATH'];
if (!credentialsPath) { if (!credentialsPath) {

View file

@ -19,7 +19,6 @@ import {
} from '@google-github-actions/actions-utils'; } from '@google-github-actions/actions-utils';
// Do not listen to the linter - this can NOT be rewritten as an ES6 import statement. // Do not listen to the linter - this can NOT be rewritten as an ES6 import statement.
// eslint-disable-next-line @typescript-eslint/no-var-requires
export const { version: appVersion } = require('../package.json'); export const { version: appVersion } = require('../package.json');
// userAgent is the default user agent. // userAgent is the default user agent.

View file

@ -1,11 +1,9 @@
{ {
"compilerOptions": { "compilerOptions": {
"alwaysStrict": true, "alwaysStrict": true,
"target": "es6", "target": "es2022",
"module": "commonjs", "module": "commonjs",
"lib": [ "lib": ["es2022"],
"es6"
],
"outDir": "./dist", "outDir": "./dist",
"rootDir": "./src", "rootDir": "./src",
"strict": true, "strict": true,