# github-builder-experimental **Repository Path**: mirrors_docker/github-builder-experimental ## Basic Information - **Project Name**: github-builder-experimental - **Description**: Official Docker-maintained reusable GitHub Actions workflows - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-11-15 - **Last Updated**: 2026-10-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README [![Test build workflow](https://img.shields.io/github/actions/workflow/status/docker/github-builder/.test-build.yml?label=test%20build&logo=github&style=flat-square)](https://github.com/docker/github-builder/actions?workflow=.test-build) [![Test bake workflow](https://img.shields.io/github/actions/workflow/status/docker/github-builder/.test-bake.yml?label=test%20bake&logo=github&style=flat-square)](https://github.com/docker/github-builder/actions?workflow=.test-bake) ___ * [Overview](#overview) * [Key Advantages](#key-advantages) * [Performance](#performance) * [Security](#security) * [Isolation & Reliability](#isolation--reliability) * [Build reusable workflow](#build-reusable-workflow) * [Inputs](#inputs) * [Secrets](#secrets) * [Outputs](#outputs) * [Bake reusable workflow](#bake-reusable-workflow) * [Inputs](#inputs-1) * [Secrets](#secrets-1) * [Outputs](#outputs-1) * [Notes](#notes) * [BuildKit proxy network](#buildkit-proxy-network) * [Build secrets](#build-secrets) * [Signed GitHub Actions cache](#signed-github-actions-cache) * [Registry identities](#registry-identities) * [Docker Hub OIDC](#docker-hub-oidc) * [AWS ECR](#aws-ecr) * [Google Artifact Registry](#google-artifact-registry) * [Azure Container Registry](#azure-container-registry) * [Chainguard](#chainguard) * [Runner mapping](#runner-mapping) * [Registry login](#registry-login) * [Metadata templates](#metadata-templates) ## Overview This repository provides official Docker-maintained [reusable GitHub Actions workflows](https://docs.github.com/en/actions/how-tos/reuse-automations/reuse-workflows) to securely build container images and artifacts using Docker best practices. The reusable workflows incorporate functionality from our GitHub Actions like [`docker/build-push-action`](https://github.com/docker/build-push-action/), [`docker/metadata-action`](https://github.com/docker/metadata-action/), etc., into a single workflow: ```yaml name: ci permissions: contents: read on: push: branches: - 'main' tags: - 'v*' pull_request: jobs: build: uses: docker/github-builder/.github/workflows/build.yml@v1 permissions: contents: read # to fetch the repository content id-token: write # for signing attestations and cache entries with GitHub OIDC with: output: image push: ${{ github.event_name != 'pull_request' }} meta-images: name/app secrets: registry-auths: | - registry: docker.io username: ${{ vars.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} ``` This workflow provides a trusted BuildKit instance and generates signed SLSA-compliant provenance attestations, guaranteeing the build happened from the source commit and all build steps ran in isolated sandboxed environments from immutable sources. This enables GitHub projects to follow a seamless path toward higher levels of security and trust. ## Key Advantages ### Performance * **Native parallelization for multi-platform builds.** Workflows can automatically distribute builds across runners based on target platform to be built, improving throughput for other architectures without requiring emulation or [custom CI logic](https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners) or self-managed runners. * **Optimized cache warming & reuse.** The builder can use the GitHub Actions cache backend to persist layers across branches, PRs, and rebuilds. This significantly reduces cold-start times and avoids repeating expensive dependency installations. With GitHub OIDC available, cache entries are signed and verified before reuse so warm-cache builds do not accept unauthenticated cache contents as build inputs. See [Signed GitHub Actions cache](#signed-github-actions-cache). * **Centralized build configuration.** Repositories no longer need to configure buildx drivers, tune storage, or adjust resource limits. The reusable workflows encapsulate the recommended configuration, providing fast, consistent builds across any project that opts in. ### Security * **Trusted workflows in the Docker organization.** Builds are executed by reusable workflows defined in the [**@docker**](https://github.com/docker) organization, not by arbitrary user-defined workflow steps. Consumers can rely on GitHub's trust model and repository protections on the Docker side (branch protection, code review, signing, etc.) to reason about who controls the build logic. * **Verifiable, immutable sources.** The workflows use the GitHub OIDC token and the exact commit SHA to obtain source and to bind it into SLSA provenance. This ensures that the build is tied to the repository contents as checked in—no additional CI step can silently swap out what is being built. * **Signed SLSA provenance for every build.** BuildKit generates [SLSA-compliant provenance attestation](https://docs.docker.com/build/metadata/attestations/slsa-provenance/) artifacts that are signed with an identity bound to the GitHub workflow. Downstream consumers can verify: - which builder commit produced the image - which source code commit produced the image - which workflow and job executed the build - what inputs and build parameters were used * **Protection from user workflow tampering.** The build steps are pre-defined and optimized in the reusable workflow, and cannot be altered by user configuration. This protects against tampering: preventing untrusted workflow steps from modifying build logic, injecting unexpected flags, or producing misleading provenance. * **Signed cache reuse.** With GitHub OIDC available, all GitHub Actions cache entries produced by these reusable workflows are signed and verified before import. This prevents cache entries produced outside the trusted workflow from being restored while still allowing cache warming and reuse. See [Signed GitHub Actions cache](#signed-github-actions-cache). ### Isolation & Reliability * **Separation between user CI logic and build logic.** The user's workflow orchestrates *when* to build but not *how* to build. The actual build steps live in the Docker-maintained reusable workflows, which cannot be modified from the consuming repository. * **Immutable, reproducible build pipeline.** Builds are driven by declarative inputs (repository commit, build configuration, workflow version). This leads to: - reproducibility (same workflow + same inputs → same outputs) - auditability (inputs and workflow identity recorded in provenance) - reliability (less dependence on ad-hoc per-repo CI scripting) * **Reduced CI variability and config drift.** By reusing the same workflows, projects avoid maintaining custom build logic per repository. Caching, provenance, SBOM generation, and build settings behave uniformly across all adopters. * **Higher assurance for downstream consumers.** Because artifacts are produced by a workflow in the [**@docker**](https://github.com/docker) organization, with SLSA provenance attached, consumers can verify both the *source commit* and the *builder identity* before trusting or promoting an image, an essential part of supply-chain hardening. ## Build reusable workflow The [`build.yml` reusable workflow](.github/workflows/build.yml) lets you build container images and artifacts from a Dockerfile with a user experience similar to [`docker/build-push-action`](https://github.com/docker/build-push-action/). It provides a Docker-maintained, opinionated build pipeline that applies best practices for security, performance, and reliability by default, including isolated execution and signed SLSA provenance while keeping per-repository configuration minimal. ```yaml name: ci permissions: contents: read on: push: branches: - 'main' tags: - 'v*' pull_request: jobs: build: uses: docker/github-builder/.github/workflows/build.yml@v1 permissions: contents: read # to fetch the repository content id-token: write # for signing attestations and cache entries with GitHub OIDC with: output: image push: ${{ github.event_name != 'pull_request' }} platforms: linux/amd64,linux/arm64 meta-images: name/app meta-tags: | type=ref,event=branch type=ref,event=pr type=semver,pattern={{version}} secrets: registry-auths: | - registry: docker.io username: ${{ vars.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} ``` ### Inputs > [!NOTE] > `List` type is a newline-delimited string > ```yaml > cache-from: | > user/app:cache > type=local,src=path/to/dir > ``` > > `CSV` type is a comma-delimited string > ```yaml > tags: name/app:latest,name/app:1.0.0 > ``` | Name | Type | Default | Description | |---------------------------|----------|---------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `runner` | String | See [Runner mapping](#runner-mapping) | GitHub-hosted Linux runner label or platform mapping to build on. See [Runner mapping](#runner-mapping). | | `distribute` | Bool | `true` | Whether to distribute the build across multiple runners (one platform per runner) | | `fail-fast` | Bool | `false` | Whether to cancel all in-progress and queued jobs in the matrix if any job fails | | `job-name-prefix` | String | | Prefix to include in reusable workflow job matrix names in the GitHub Actions UI | | `setup-qemu` | Bool | `false` | Runs the `setup-qemu-action` step to install QEMU static binaries | | `artifact-name` | String | `docker-github-builder-assets` | Name of the uploaded GitHub artifact (for `local` output) | | `artifact-upload` | Bool | `false` | Upload build output GitHub artifact (for `local` output) | | `artifact-retention-days` | Number | `0` | Duration after which artifact will expire in days. `0` means using default retention | | `annotations` | List | | List of annotations to set to the image (for `image` output) | | `build-args` | List | `auto` | List of [build-time variables](https://docs.docker.com/engine/reference/commandline/buildx_build/#build-arg). If you want to set a build-arg through an environment variable, use the `envs` input | | `cache` | Bool | `false` | Enable [GitHub Actions cache](https://docs.docker.com/build/cache/backends/gha/) exporter | | `cache-scope` | String | target name or `buildkit` | Which [scope cache object belongs to](https://docs.docker.com/build/cache/backends/gha/#scope) if `cache` is enabled. This is the cache blob prefix name used when pushing cache to GitHub Actions cache backend | | `cache-mode` | String | `min` | [Cache layers to export](https://docs.docker.com/build/cache/backends/#cache-mode) if cache enabled (`min` or `max`). In `min` cache mode, only layers that are exported into the resulting image are cached, while in `max` cache mode, all layers are cached, even those of intermediate steps | | `context` | String | `.` | Context to build from in the Git working tree | | `file` | String | `{context}/Dockerfile` | Path to the Dockerfile | | `labels` | List | | List of labels for an image (for `image` output) | | `output` | String | | Build output destination (one of [`image`](https://docs.docker.com/build/exporters/image-registry/) or [`local`](https://docs.docker.com/build/exporters/local-tar/)). Unlike the `build-push-action`, it only accepts `image` or `local`. The reusable workflow takes care of setting the `outputs` attribute | | `platforms` | List/CSV | | List of [target platforms](https://docs.docker.com/engine/reference/commandline/buildx_build/#platform) to build | | `push` | Bool | `false` | [Push](https://docs.docker.com/engine/reference/commandline/buildx_build/#push) image to the registry (for `image` output) | | `registry-identities` | YAML | | Keyless registry identity configuration. See [Registry identities](#registry-identities). | | `registry-login` | String | `auto` | [Login to registry](#registry-login) before build (one of `auto`, `true` or `false`) | | `sbom` | Bool | `false` | Generate [SBOM](https://docs.docker.com/build/attestations/sbom/) attestation for the build | | `shm-size` | String | | Size of [`/dev/shm`](https://docs.docker.com/engine/reference/commandline/buildx_build/#shm-size) (e.g., `2g`) | | `sign` | String | `auto` | Sign attestation manifest for `image` output or artifacts for `local` output, can be one of `auto`, `true` or `false`. The `auto` mode will enable signing if `push` is enabled for pushing the `image` or if `artifact-upload` is enabled for uploading the `local` build output as GitHub Artifact | | `target` | String | | Sets the target stage to build | | `ulimit` | List | | [Ulimit](https://docs.docker.com/engine/reference/commandline/buildx_build/#ulimit) options (e.g., `nofile=1024:1024`) | | `set-meta-annotations` | Bool | `false` | Append OCI Image Format Specification annotations generated by `docker/metadata-action` | | `set-meta-labels` | Bool | `false` | Append OCI Image Format Specification labels generated by `docker/metadata-action` | | `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) | | `meta-tags` | List | | [List of tags](https://github.com/docker/metadata-action?tab=readme-ov-file#tags-input) as key-value pair attributes | | `meta-labels` | List | | [List of custom labels](https://github.com/docker/metadata-action?tab=readme-ov-file#overwrite-labels-and-annotations) | | `meta-annotations` | List | | [List of custom annotations](https://github.com/docker/metadata-action?tab=readme-ov-file#overwrite-labels-and-annotations) | | `meta-flavor` | List | | [Flavor](https://github.com/docker/metadata-action?tab=readme-ov-file#flavor-input) defines a global behavior for `meta-tags` | | `buildkit-proxy-network` | Bool | `false` | Enable BuildKit proxy network mode for default Dockerfile `RUN` networking. See [BuildKit proxy network](#buildkit-proxy-network). | ### Secrets | Name | Default | Description | |------------------|-----------------------|--------------------------------------------------------------------------| | `registry-auths` | | Raw authentication to registries, defined as YAML objects | | `build-secrets` | | YAML object mapping BuildKit secret IDs to secret values | | `github-token` | `${{ github.token }}` | GitHub Token used to authenticate against the repository for Git context | ### Outputs These outputs are available as `needs..outputs.*` and can be passed directly to the [`verify.yml` reusable workflow](.github/workflows/verify.yml) with `builder-outputs: ${{ toJSON(needs..outputs) }}`. | Name | Type | Description | |--------------------------|--------|------------------------------------------------------------------------------| | `meta-json` | JSON | Metadata JSON output from `docker/metadata-action` (for `image` output) | | `cosign-version` | String | Cosign version used for verification | | `cosign-verify-commands` | List | Newline-delimited `cosign verify` commands generated when signing is enabled | | `artifact-name` | String | Name of the uploaded merged artifact (for `local` output) | | `digest` | String | Digest of the image pushed or artifact uploaded | | `output-type` | String | Output type selected for the workflow (`image` or `local`) | | `signed` | Bool | Whether attestation manifests or local artifacts were signed | ## Bake reusable workflow The [`bake.yml` reusable workflow](.github/workflows/bake.yml) lets you build container images and artifacts from a [Bake definition](https://docs.docker.com/build/bake/) with a user experience similar to [`docker/bake-action`](https://github.com/docker/bake-action/). It provides a Docker-maintained, opinionated build pipeline that applies best practices for security, performance, and reliability by default, including isolated execution and signed SLSA provenance while keeping per-repository configuration minimal. ```yaml name: ci permissions: contents: read on: push: branches: - 'main' tags: - 'v*' pull_request: jobs: bake: uses: docker/github-builder/.github/workflows/bake.yml@v1 permissions: contents: read # to fetch the repository content id-token: write # for signing attestations and cache entries with GitHub OIDC with: output: image push: ${{ github.event_name != 'pull_request' }} meta-images: name/app meta-tags: | type=ref,event=branch type=ref,event=pr type=semver,pattern={{version}} secrets: registry-auths: | - registry: docker.io username: ${{ vars.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} ``` ### Inputs > [!NOTE] > `List` type is a newline-delimited string > ```yaml > set: target.args.mybuildarg=value > ``` > ```yaml > set: | > target.args.mybuildarg=value > foo*.args.mybuildarg=value > ``` | Name | Type | Default | Description | |---------------------------|--------|---------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `runner` | String | See [Runner mapping](#runner-mapping) | GitHub-hosted Linux runner label or platform mapping to build on. See [Runner mapping](#runner-mapping). | | `distribute` | Bool | `true` | Whether to distribute the build across multiple runners (one platform per runner) | | `fail-fast` | Bool | `false` | Whether to cancel all in-progress and queued jobs in the matrix if any job fails | | `job-name-prefix` | String | | Prefix to include in reusable workflow job matrix names in the GitHub Actions UI | | `setup-qemu` | Bool | `false` | Runs the `setup-qemu-action` step to install QEMU static binaries | | `artifact-name` | String | `docker-github-builder-assets` | Name of the uploaded GitHub artifact (for `local` output) | | `artifact-upload` | Bool | `false` | Upload build output GitHub artifact (for `local` output) | | `artifact-retention-days` | Number | `0` | Duration after which artifact will expire in days. `0` means using default retention | | `cache` | Bool | `false` | Enable [GitHub Actions cache](https://docs.docker.com/build/cache/backends/gha/) exporter | | `cache-scope` | String | target name or `buildkit` | Which [scope cache object belongs to](https://docs.docker.com/build/cache/backends/gha/#scope) if `cache` is enabled. This is the cache blob prefix name used when pushing cache to GitHub Actions cache backend | | `cache-mode` | String | `min` | [Cache layers to export](https://docs.docker.com/build/cache/backends/#cache-mode) if cache enabled (`min` or `max`). In `min` cache mode, only layers that are exported into the resulting image are cached, while in `max` cache mode, all layers are cached, even those of intermediate steps | | `context` | String | `.` | Context to build from in the Git working tree | | `files` | List | `{context}/docker-bake.hcl` | List of bake definition files | | `output` | String | | Build output destination (one of [`image`](https://docs.docker.com/build/exporters/image-registry/) or [`local`](https://docs.docker.com/build/exporters/local-tar/)). | | `push` | Bool | `false` | Push image to the registry (for `image` output) | | `registry-identities` | YAML | | Keyless registry identity configuration. See [Registry identities](#registry-identities). | | `registry-login` | String | `auto` | [Login to registry](#registry-login) before build (one of `auto`, `true` or `false`) | | `sbom` | Bool | `false` | Generate [SBOM](https://docs.docker.com/build/attestations/sbom/) attestation for the build | | `set` | List | | List of [target values to override](https://docs.docker.com/engine/reference/commandline/buildx_bake/#set) (e.g., `targetpattern.key=value`) | | `sign` | String | `auto` | Sign attestation manifest for `image` output or artifacts for `local` output, can be one of `auto`, `true` or `false`. The `auto` mode will enable signing if `push` is enabled for pushing the `image` or if `artifact-upload` is enabled for uploading the `local` build output as GitHub Artifact | | `target` | String | `default` | Bake target to build | | `vars` | List | | [Variables](https://docs.docker.com/build/bake/variables/) to set in the Bake definition as list of key-value pair | | `set-meta-annotations` | Bool | `false` | Append OCI Image Format Specification annotations generated by `docker/metadata-action` | | `set-meta-labels` | Bool | `false` | Append OCI Image Format Specification labels generated by `docker/metadata-action` | | `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) | | `meta-tags` | List | | [List of tags](https://github.com/docker/metadata-action?tab=readme-ov-file#tags-input) as key-value pair attributes | | `meta-labels` | List | | [List of custom labels](https://github.com/docker/metadata-action?tab=readme-ov-file#overwrite-labels-and-annotations) | | `meta-annotations` | List | | [List of custom annotations](https://github.com/docker/metadata-action?tab=readme-ov-file#overwrite-labels-and-annotations) | | `meta-flavor` | List | | [Flavor](https://github.com/docker/metadata-action?tab=readme-ov-file#flavor-input) defines a global behavior for `meta-tags` | | `buildkit-proxy-network` | Bool | `false` | Enable BuildKit proxy network mode for default Dockerfile `RUN` networking. See [BuildKit proxy network](#buildkit-proxy-network). | ### Secrets | Name | Default | Description | |------------------|-----------------------|-----------------------------------------------------------------------------------------| | `registry-auths` | | Raw authentication to registries, defined as YAML objects | | `build-secrets` | | YAML object mapping BuildKit secret IDs to values, with optional nested target mappings | | `github-token` | `${{ github.token }}` | GitHub Token used to authenticate against the repository for Git context | ### Outputs These outputs are available as `needs..outputs.*` and can be passed directly to the [`verify.yml` reusable workflow](.github/workflows/verify.yml) with `builder-outputs: ${{ toJSON(needs..outputs) }}`. | Name | Type | Description | |--------------------------|--------|------------------------------------------------------------------------------| | `meta-json` | JSON | Metadata JSON output from `docker/metadata-action` (for `image` output) | | `cosign-version` | String | Cosign version used for verification | | `cosign-verify-commands` | List | Newline-delimited `cosign verify` commands generated when signing is enabled | | `artifact-name` | String | Name of the uploaded merged artifact (for `local` output) | | `digest` | String | Digest of the image pushed or artifact uploaded | | `output-type` | String | Output type selected for the workflow (`image` or `local`) | | `signed` | Bool | Whether attestation manifests or local artifacts were signed | ## Notes ### BuildKit proxy network The `buildkit-proxy-network` input enables BuildKit proxy network mode for Dockerfile `RUN` steps with network access. `RUN --network=none` stays offline, but default-network `RUN` steps are routed through BuildKit's internal HTTP(S) proxy. When enabled, BuildKit rewrites `HTTP_PROXY`, `HTTPS_PROXY`, `http_proxy`, and `https_proxy` inside affected `RUN` operations to point at that internal proxy. It also injects a generated CA certificate into common Linux system trust bundle locations for the duration of the operation. HTTPS clients that use separate or embedded trust stores may fail TLS verification, and applications that ignore proxy environment variables or open raw TCP connections cannot bypass the proxy. Direct DNS and non-HTTP(S) protocols, such as Git-over-SSH, are not available through this mode. BuildKit logs proxy network requests. Successful GET responses can be captured as build materials and included in provenance dependency metadata when provenance is requested. When `cache` is enabled, these workflows append `-proxy-network` to the GitHub Actions cache scope while proxy network mode is enabled, so unproxied cache entries are not imported into a proxied build. A cache hit that was originally produced under proxy mode still does not execute the network step again, so it does not emit a fresh request log or add new provenance material. BuildKit does not chain the internal proxy through a caller-provided upstream proxy. Enabling `buildkit-proxy-network` replaces Docker's predefined proxy build arguments for affected `RUN` operations and can bypass an application-level organizational proxy. See BuildKit's [proxy network documentation](https://github.com/moby/buildkit/blob/master/docs/proxy.md). ### Build secrets Both workflows accept `build-secrets` as a YAML object mapping BuildKit secret IDs to values, not caller workspace paths. Bake requires matching secrets to be declared in `docker-bake.hcl`: ```hcl target "default" { secret = [ "id=npm.token,env=NPM_TOKEN", "id=aws.credentials,src=./aws-credentials", "id=inline_config,env=INLINE_CONFIG", ] } ``` Then pass their values to the reusable workflow: ```yaml secrets: build-secrets: | npm.token: ${{ toJSON(secrets.NPM_TOKEN) }} aws.credentials: ${{ toJSON(secrets.AWS_CREDENTIALS) }} inline_config: | first line second line ``` Use `toJSON(...)` for GitHub secrets to preserve multiline values and YAML-sensitive characters. For literal values with trailing blank lines, use `|+` on both the outer `build-secrets` block and the inner value. In Bake, string values apply to the selected `target`. Nested mappings explicitly select a target in the resolved build graph. For the same definition above: ```yaml with: target: default secrets: build-secrets: | npm.token: ${{ toJSON(secrets.NPM_TOKEN) }} default: aws.credentials: ${{ toJSON(secrets.AWS_CREDENTIALS) }} ``` Dots are always part of the secret ID, never target separators. Nested target mappings are only supported by the bake workflow. IDs cannot be empty or contain line breaks or `=`; the build workflow also rejects commas, double quotes, and leading or trailing whitespace. Values are passed through private temporary files, not the job environment. For Bake, these override the declared file or environment sources without adding new secrets. Files are created after registry authentication and cleaned up after the build, including on failure. Abrupt runner termination can prevent cleanup. ### Signed GitHub Actions cache When the workflow has GitHub OIDC available through `id-token: write`, BuildKit signs cache entries with Cosign and requires restored cache entries to match the expected workflow identity and source repository policy before import. This verification matters because GitHub Actions cache is scoped to a repository, but repository writers can still create cache entries. For these reusable workflows, the Docker-owned workflow is the trusted build boundary. Without verification, a poisoned BuildKit cache could influence a later trusted build, which is the SLSA isolation concern described in [docker/github-builder#56](https://github.com/docker/github-builder/issues/56). ### Registry identities The `registry-identities` input configures keyless registry authentication from non-secret identity metadata. Do not put passwords, tokens, client secrets, private keys, raw cloud credential JSON, or other secret values in this input. When an image push or verification needs registry access, the workflow validates the YAML before any build work starts. `registry-identities` can be combined with the existing `registry-auths` secret. Provider-specific authentication steps are pinned in these reusable workflows; callers can only select supported provider types and pass identity configuration. The `build.yml`, `bake.yml`, and `verify.yml` reusable workflows accept this input. Use the same identity configuration with `verify.yml` when signature verification needs access to a private registry image. #### Docker Hub OIDC Docker Hub registry authentication can be configured with `type: dockerhub`. Callers must grant `id-token: write` so `docker/login-action` can exchange the GitHub OIDC token through the configured [Docker Hub OIDC connection](https://docs.docker.com/enterprise/security/oidc-connections/): ```yaml jobs: build: uses: docker/github-builder/.github/workflows/build.yml@v1 permissions: contents: read # to fetch the repository content id-token: write # for signing attestations, cache entries with GitHub OIDC and logging in to Docker Hub with: output: image push: ${{ github.event_name != 'pull_request' }} meta-images: | docker.io/my-organization/test-github-builder registry-identities: | - type: dockerhub username: my-organization connection_id: 123e4567-e89b-42d3-a456-426614174000 ``` | Name | Type | Required | Description | |-----------------|--------|----------|-----------------------------------------------------------------------------------------------------------------------------------| | `type` | String | Yes | Registry identity provider type. Must be `dockerhub`. | | `registry` | String | No | Registry hostname passed to `docker/login-action`. Defaults to `docker.io`. | | `username` | String | Yes | Docker Hub username or organization passed to `docker/login-action`. | | `connection_id` | String | Yes | Docker Hub OIDC connection ID passed to `docker/login-action` in each job. | | `scope` | String | No | [Authentication scope](https://github.com/docker/login-action#set-scopes-for-the-authentication-token) for `docker/login-action`. | The workflow mints the Docker Hub access token inside each reusable workflow job that needs Docker Hub registry access. The token is not accepted as an input and is not passed across the reusable workflow boundary. If you call `verify.yml` for a private Docker Hub image, pass the same `registry-identities` value to that workflow instead of using a Docker Hub PAT. #### AWS ECR Amazon ECR registry authentication is configured with `type: aws-ecr`. Callers must grant `id-token: write` so the AWS credential step can assume the role through GitHub OIDC: ```yaml jobs: build: uses: docker/github-builder/.github/workflows/build.yml@v1 permissions: contents: read # to fetch the repository content id-token: write # for signing attestations, cache entries with GitHub OIDC and log in to AWS ECR with: output: image push: ${{ github.event_name != 'pull_request' }} meta-images: | 123456789100.dkr.ecr.us-east-1.amazonaws.com/sandbox/test-github-builder registry-identities: | - type: aws-ecr registry: 123456789100.dkr.ecr.us-east-1.amazonaws.com role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role region: us-east-1 account_ids: 123456789101,123456789102 ``` | Name | Type | Required | Description | |------------------|--------|----------|---------------------------------------------------------------------------------------------------------------------------------| | `type` | String | Yes | Registry identity provider type. Must be `aws-ecr`. | | `registry` | String | Yes | Registry server passed to `docker/login-action`, such as `public.ecr.aws` for public ECR or a private ECR host for private ECR. | | `role-to-assume` | String | Yes | IAM role ARN assumed through GitHub OIDC. | | `region` | String | Yes | AWS region passed to `aws-actions/configure-aws-credentials` when assuming the role. Use `us-east-1` for ECR Public. | | `account_ids` | String | No | Comma-separated additional private ECR account IDs to log in to with the assumed role. | The `registry` value is required for AWS ECR. Use the registry server that `docker/login-action` should log in to, such as `public.ecr.aws` for public ECR or `123456789100.dkr.ecr.us-east-1.amazonaws.com` for private ECR. The account ID in the private ECR registry is always included. Set `account_ids` to log in to additional accounts in the same region. The assumed role must have permission to retrieve authorization tokens for those accounts. This setting does not apply to ECR Public. #### Google Artifact Registry Google Artifact Registry authentication is configured with `type: gcp-wif`. Callers must grant `id-token: write` so `google-github-actions/auth` can exchange the GitHub OIDC token through GCP Workload Identity Federation: ```yaml jobs: build: uses: docker/github-builder/.github/workflows/build.yml@v1 permissions: contents: read # to fetch the repository content id-token: write # for signing attestations, cache entries with GitHub OIDC and log in to Google Artifact Registry with: output: image push: ${{ github.event_name != 'pull_request' }} meta-images: | us-docker.pkg.dev/my-project/sandbox/test-github-builder registry-identities: | - type: gcp-wif registry: us-docker.pkg.dev workload_identity_provider: projects/123456789/locations/global/workloadIdentityPools/github/providers/provider service_account: builder@my-project.iam.gserviceaccount.com project_id: my-project ``` | Name | Type | Required | Description | |------------------------------|--------|----------|------------------------------------------------------------------------------------------------------------------------------------------------| | `type` | String | Yes | Registry identity provider type. Must be `gcp-wif`. | | `registry` | String | Yes | Google Artifact Registry host passed to `docker/login-action`, such as `us-docker.pkg.dev`. Do not use the full repository path. | | `workload_identity_provider` | String | Yes | Workload Identity Provider resource name passed to `google-github-actions/auth`. | | `service_account` | String | Yes | Service account email passed to `google-github-actions/auth` for Workload Identity Federation. | | `project_id` | String | No | Google Cloud project ID passed to `google-github-actions/auth` when provided. | The `registry` value is required for GCP WIF. Use the Artifact Registry host that `docker/login-action` should log in to, such as `us-docker.pkg.dev`, not the full repository path. The workflow requests an access token from `google-github-actions/auth` and passes it directly to `docker/login-action` with the `oauth2accesstoken` username inside the same job. #### Azure Container Registry Azure Container Registry authentication is configured with `type: azure-acr`. Grant `id-token: write` and configure a federated credential for the GitHub workflow on the Azure identity. The identity also needs permission to pull or push images in the registry: ```yaml jobs: build: uses: docker/github-builder/.github/workflows/build.yml@v1 permissions: contents: read id-token: write with: output: image push: true meta-images: myregistry.azurecr.io/my-image registry-identities: | - type: azure-acr registry: myregistry.azurecr.io client_id: 00000000-0000-0000-0000-000000000000 tenant_id: 00000000-0000-0000-0000-000000000000 subscription_id: 00000000-0000-0000-0000-000000000000 ``` | Name | Type | Required | Description | |-------------------|--------|----------|----------------------------------------------------| | `type` | String | Yes | Must be `azure-acr`. | | `registry` | String | Yes | ACR login server, such as `myregistry.azurecr.io`. | | `client_id` | String | Yes | Federated identity client ID. | | `tenant_id` | String | Yes | Azure tenant ID. | | `subscription_id` | String | Yes | Azure subscription ID. | The `registry` value must be an ACR login server ending in `.azurecr.io`; the workflow removes that suffix to obtain the name for `az acr login`. It logs in with `azure/login` first, inside each job that needs the registry. No client secret crosses the reusable workflow boundary. #### Chainguard Chainguard authentication is configured with `type: chainguard`. Grant `id-token: write` and configure the identity to trust the GitHub workflow: ```yaml jobs: bake: uses: docker/github-builder/.github/workflows/bake.yml@v1 permissions: contents: read id-token: write with: output: image push: true meta-images: cgr.dev/my-organization/my-image registry-identities: | - type: chainguard identity: my-organization/my-identity ``` | Name | Type | Required | Description | |------------------|--------|----------|--------------------------------------------------| | `type` | String | Yes | Must be `chainguard`. | | `identity` | String | Yes | Chainguard identity to assume. | | `apk_host` | String | No | APK host. Defaults to `apk.cgr.dev`. | | `libraries_host` | String | No | Libraries host. Defaults to `libraries.cgr.dev`. | The workflow runs `chainguard-dev/setup-chainctl` inside each job that needs registry access. The identity must be authorized for the configured APK and Libraries hosts as well as the target registry. ### Runner mapping The `runner` input accepts either a single GitHub-hosted Linux runner label or a newline-delimited platform mapping. A single label is used for every build: ```yaml runner: ubuntu-24.04 ``` The default value uses the standard GitHub-hosted Ubuntu runners: ```yaml runner: | default=ubuntu-24.04 linux/arm=ubuntu-24.04-arm linux/arm64=ubuntu-24.04-arm ``` A mapping must define a `default` runner. Additional keys are platform prefixes, and the most specific matching prefix wins. For example: ```yaml runner: | default=ubuntu-24.04 linux=ubuntu-24.04 linux/arm=ubuntu-24.04-arm ``` For example, `linux` matches all Linux platforms, `linux/arm` matches variants such as `linux/arm/v7`, and `linux/arm64` is separate from `linux/arm`. ### Registry login The `registry-login` input controls whether the workflows run a registry login before the build step. `auto` preserves the existing behavior and enables login only when `output=image` and `push=true`. When `registry-login=true`, the workflow always attempts pre-build login. If credentials resolve to empty values, for example on forked pull requests where secrets are not exposed, login fails. Gate the input at the caller side for fork-safe workflows: ```yaml registry-login: ${{ github.event_name != 'pull_request' || !github.event.pull_request.head.repo.fork }} ``` ### Metadata templates When `output=image`, some inputs support Handlebars templates rendered from selected `docker/metadata-action` outputs. The template context is exposed as `meta` with `meta.version` and `meta.tags`. For the build workflow, the `annotations`, `build-args`, and `labels` inputs support metadata templates: ```yaml jobs: build: uses: docker/github-builder/.github/workflows/build.yml@v1 with: output: image build-args: | VERSION={{meta.version}} meta-images: name/app ``` For the bake workflow, the `set` input supports metadata templates: ```yaml jobs: bake: uses: docker/github-builder/.github/workflows/bake.yml@v1 with: output: image set: | *.args.VERSION={{meta.version}} meta-images: name/app ``` > [!NOTE] > The `meta-labels` and `meta-annotations` inputs are passed to > `docker/metadata-action`, so their templates follow `docker/metadata-action` > behavior. Enable `set-meta-labels` or `set-meta-annotations` to apply those > generated values to the image. In the build workflow, generated values are > appended to any `labels` or `annotations` already set.