Skip to content

Commit e9f09b5

Browse files
committed
build/bake,build: add Chainguard OIDC keyless cgr.dev auth (opt-in)
Add four opt-in inputs to bake.yml and build.yml: chainguard-identity, chainguard-registry, chainguard-apk-host, chainguard-libraries-host. When chainguard-identity is set, the build and finalize jobs install chainctl via chainguard-dev/setup-chainctl@v0.5.1 and register it as a Docker credential helper for cgr.dev. The Chainguard pull token is minted inside the build/finalize job runners and never crosses the workflow_call boundary into the caller's registry-auths secret, where it would be silently stripped by GitHub's cross-job output masker (#146 documents the equivalent GCP WIF failure mode). No existing input changes; registry-auths continues to handle every static-credential registry as before and can be combined with chainguard-identity for multi-registry builds. Refs: #146
1 parent c2782c5 commit e9f09b5

3 files changed

Lines changed: 111 additions & 0 deletions

File tree

.github/workflows/bake.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,25 @@ on:
126126
type: string
127127
description: "Bake target name for metadata (defaults to docker-metadata-action)"
128128
required: false
129+
chainguard-identity:
130+
type: string
131+
description: "UIDP of a Chainguard identity to assume via GitHub OIDC for keyless cgr.dev authentication"
132+
required: false
133+
chainguard-registry:
134+
type: string
135+
description: "Chainguard OCI registry host"
136+
required: false
137+
default: cgr.dev
138+
chainguard-apk-host:
139+
type: string
140+
description: "Hostname for APK-related Chainguard authentication (passed through to chainguard-dev/setup-chainctl)"
141+
required: false
142+
default: apk.cgr.dev
143+
chainguard-libraries-host:
144+
type: string
145+
description: "Hostname for Chainguard Libraries authentication (passed through to chainguard-dev/setup-chainctl)"
146+
required: false
147+
default: libraries.cgr.dev
129148
secrets:
130149
registry-auths:
131150
description: "Raw authentication to registries, defined as YAML objects (for image output)"
@@ -907,6 +926,14 @@ jobs:
907926
core.info(JSON.stringify(bakeOverrides, null, 2));
908927
core.setOutput('overrides', bakeOverrides.join(os.EOL));
909928
});
929+
-
930+
name: Set up chainctl
931+
if: ${{ inputs.chainguard-identity != '' && inputs.push && inputs.output == 'image' }}
932+
uses: chainguard-dev/setup-chainctl@2cddd35a2f120d9973e58094dc6878c93cf58c28 # v0.5.1
933+
with:
934+
identity: ${{ inputs.chainguard-identity }}
935+
apk-host: ${{ inputs.chainguard-apk-host }}
936+
libraries-host: ${{ inputs.chainguard-libraries-host }}
910937
-
911938
name: Login to registry
912939
if: ${{ inputs.push && inputs.output == 'image' }}
@@ -1091,6 +1118,14 @@ jobs:
10911118
labels: ${{ inputs.meta-labels }}
10921119
annotations: ${{ inputs.meta-annotations }}
10931120
bake-target: ${{ inputs.meta-bake-target }}
1121+
-
1122+
name: Set up chainctl
1123+
if: ${{ inputs.chainguard-identity != '' && inputs.push && inputs.output == 'image' }}
1124+
uses: chainguard-dev/setup-chainctl@2cddd35a2f120d9973e58094dc6878c93cf58c28 # v0.5.1
1125+
with:
1126+
identity: ${{ inputs.chainguard-identity }}
1127+
apk-host: ${{ inputs.chainguard-apk-host }}
1128+
libraries-host: ${{ inputs.chainguard-libraries-host }}
10941129
-
10951130
name: Login to registry
10961131
if: ${{ inputs.push && inputs.output == 'image' }}

.github/workflows/build.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,25 @@ on:
129129
type: string
130130
description: "Flavor defines a global behavior for meta-tags"
131131
required: false
132+
chainguard-identity:
133+
type: string
134+
description: "UIDP of a Chainguard identity to assume via GitHub OIDC for keyless cgr.dev authentication"
135+
required: false
136+
chainguard-registry:
137+
type: string
138+
description: "Chainguard OCI registry host"
139+
required: false
140+
default: cgr.dev
141+
chainguard-apk-host:
142+
type: string
143+
description: "Hostname for APK-related Chainguard authentication (passed through to chainguard-dev/setup-chainctl)"
144+
required: false
145+
default: apk.cgr.dev
146+
chainguard-libraries-host:
147+
type: string
148+
description: "Hostname for Chainguard Libraries authentication (passed through to chainguard-dev/setup-chainctl)"
149+
required: false
150+
default: libraries.cgr.dev
132151
secrets:
133152
registry-auths:
134153
description: "Raw authentication to registries, defined as YAML objects (for image output)"
@@ -766,6 +785,14 @@ jobs:
766785
// for a public repository, we set max provenance mode
767786
core.setOutput('provenance', Build.resolveProvenanceAttrs(`mode=max,version=v1`));
768787
}
788+
-
789+
name: Set up chainctl
790+
if: ${{ inputs.chainguard-identity != '' && inputs.push && inputs.output == 'image' }}
791+
uses: chainguard-dev/setup-chainctl@2cddd35a2f120d9973e58094dc6878c93cf58c28 # v0.5.1
792+
with:
793+
identity: ${{ inputs.chainguard-identity }}
794+
apk-host: ${{ inputs.chainguard-apk-host }}
795+
libraries-host: ${{ inputs.chainguard-libraries-host }}
769796
-
770797
name: Login to registry
771798
if: ${{ inputs.push && inputs.output == 'image' }}
@@ -946,6 +973,14 @@ jobs:
946973
flavor: ${{ inputs.meta-flavor }}
947974
labels: ${{ inputs.meta-labels }}
948975
annotations: ${{ inputs.meta-annotations }}
976+
-
977+
name: Set up chainctl
978+
if: ${{ inputs.chainguard-identity != '' && inputs.push && inputs.output == 'image' }}
979+
uses: chainguard-dev/setup-chainctl@2cddd35a2f120d9973e58094dc6878c93cf58c28 # v0.5.1
980+
with:
981+
identity: ${{ inputs.chainguard-identity }}
982+
apk-host: ${{ inputs.chainguard-apk-host }}
983+
libraries-host: ${{ inputs.chainguard-libraries-host }}
949984
-
950985
name: Login to registry
951986
if: ${{ inputs.push && inputs.output == 'image' }}

README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ ___
1919
* [Notes](#notes)
2020
* [Runner mapping](#runner-mapping)
2121
* [Metadata templates](#metadata-templates)
22+
* [Chainguard keyless authentication](#chainguard-keyless-authentication)
2223

2324
## Overview
2425

@@ -233,6 +234,10 @@ jobs:
233234
| `meta-images` | List | | [List of images](https://github.com/docker/metadata-action?tab=readme-ov-file#images-input) to use as base name for tags (required for image output) |
234235
| `meta-tags` | List | | [List of tags](https://github.com/docker/metadata-action?tab=readme-ov-file#tags-input) as key-value pair attributes |
235236
| `meta-flavor` | List | | [Flavor](https://github.com/docker/metadata-action?tab=readme-ov-file#flavor-input) defines a global behavior for `meta-tags` |
237+
| `chainguard-identity` | String | | UIDP of a Chainguard identity to assume via GitHub OIDC for keyless `cgr.dev` authentication. See [Chainguard keyless authentication](#chainguard-keyless-authentication) |
238+
| `chainguard-registry` | String | `cgr.dev` | Chainguard OCI registry host |
239+
| `chainguard-apk-host` | String | `apk.cgr.dev` | Hostname for APK-related Chainguard authentication. Passed through to `chainguard-dev/setup-chainctl` |
240+
| `chainguard-libraries-host` | String | `libraries.cgr.dev` | Hostname for Chainguard Libraries authentication. Passed through to `chainguard-dev/setup-chainctl` |
236241

237242
### Secrets
238243

@@ -342,6 +347,10 @@ jobs:
342347
| `meta-labels` | List | | [List of custom labels](https://github.com/docker/metadata-action?tab=readme-ov-file#overwrite-labels-and-annotations) |
343348
| `meta-annotations` | List | | [List of custom annotations](https://github.com/docker/metadata-action?tab=readme-ov-file#overwrite-labels-and-annotations) |
344349
| `meta-flavor` | List | | [Flavor](https://github.com/docker/metadata-action?tab=readme-ov-file#flavor-input) defines a global behavior for `meta-tags` |
350+
| `chainguard-identity` | String | | UIDP of a Chainguard identity to assume via GitHub OIDC for keyless `cgr.dev` authentication. See [Chainguard keyless authentication](#chainguard-keyless-authentication) |
351+
| `chainguard-registry` | String | `cgr.dev` | Chainguard OCI registry host |
352+
| `chainguard-apk-host` | String | `apk.cgr.dev` | Hostname for APK-related Chainguard authentication. Passed through to `chainguard-dev/setup-chainctl` |
353+
| `chainguard-libraries-host` | String | `libraries.cgr.dev` | Hostname for Chainguard Libraries authentication. Passed through to `chainguard-dev/setup-chainctl` |
345354

346355
### Secrets
347356

@@ -431,3 +440,35 @@ jobs:
431440
*.args.VERSION={{meta.version}}
432441
meta-images: name/app
433442
```
443+
444+
### Chainguard keyless authentication
445+
446+
Setting `chainguard-identity` authenticates to `cgr.dev` via GitHub
447+
OIDC, avoiding a static credential. The workflow runs
448+
[`chainguard-dev/setup-chainctl`](https://github.com/chainguard-dev/setup-chainctl)
449+
inside the `build` and `finalize` jobs so the token is minted on the
450+
build runner and never crosses the `workflow_call` boundary (see
451+
[`docker/github-builder#146`](https://github.com/docker/github-builder/issues/146)).
452+
453+
```yaml
454+
jobs:
455+
bake:
456+
uses: docker/github-builder/.github/workflows/bake.yml@v1
457+
permissions:
458+
contents: read
459+
id-token: write
460+
with:
461+
output: image
462+
push: true
463+
meta-images: cgr.dev/your-org/your-image
464+
chainguard-identity: 70e4ec6.../79304d...
465+
```
466+
467+
`chainguard-identity` can be combined with `registry-auths` for
468+
multi-registry pushes.
469+
470+
> [!IMPORTANT]
471+
> `chainguard-dev/setup-chainctl` also authenticates against
472+
> `apk.cgr.dev` and `libraries.cgr.dev`. The assumed identity must be
473+
> claim-matched for those audiences, or `chainguard-apk-host` /
474+
> `chainguard-libraries-host` must be redirected.

0 commit comments

Comments
 (0)