[bug-s28h753sx24n] fix(image-build): document private pull token #1

Merged
dev merged 2 commits from dev/bug-s28h753sx24n/document-private-pull-token into main 2026-08-26 13:53:50 +00:00
2 changed files with 13 additions and 8 deletions
Showing only changes of commit e20e59ad0d - Show all commits
+8 -4
View File
@@ -3,9 +3,10 @@
Composite Gitea Action that builds a container image with buildx and optionally Composite Gitea Action that builds a container image with buildx and optionally
runs a smoke test. **Does not push** — pair with `action/image-push` to publish. runs a smoke test. **Does not push** — pair with `action/image-push` to publish.
Splitting build from push lets a PR workflow run `image-build` (no secrets, no Splitting build from push lets a PR workflow run `image-build` without push or
side effects) for validation while `main` runs the full build → push → deploy deploy side effects while `main` runs the full build → push → deploy chain. A
chain. PR build that pulls a private base image still needs a registry token limited to
the `read:package` capability; public-base builds need no token.
## Usage ## Usage
@@ -14,12 +15,14 @@ chain.
- uses: https://code.fritzlab.net/action/image-build@v1 - uses: https://code.fritzlab.net/action/image-build@v1
with: with:
image: code.fritzlab.net/fritzlab/chrony image: code.fritzlab.net/fritzlab/chrony
token: ${{ secrets.PACKAGE_READ_TOKEN }} # read:package; omit for public bases
dev marked this conversation as resolved Outdated
Outdated
Review

You change a PR Dockerfile to pull another private image and print it; the trusted main path has an unchecked PR twin. Read-only scope and token hiding don't protect contents. Restrict injection to trusted heads and a package-isolated principal.

You change a PR Dockerfile to pull another private image and print it; the trusted main path has an unchecked PR twin. Read-only scope and token hiding don't protect contents. Restrict injection to trusted heads and a package-isolated principal.
smoke-test: docker run --rm --entrypoint /usr/sbin/chronyd $IMAGE -v smoke-test: docker run --rm --entrypoint /usr/sbin/chronyd $IMAGE -v
``` ```
The image is built and tagged as `<image>:<github.run_number>` in the runner's The image is built and tagged as `<image>:<github.run_number>` in the runner's
local Docker daemon. Subsequent steps (e.g. `action/image-push`) can reference local Docker daemon. Subsequent steps (e.g. `action/image-push`) can reference
the same tag. the same tag. `PACKAGE_READ_TOKEN` is an example caller-chosen secret name; the
contract is the token's `read:package` capability.
## Inputs ## Inputs
@@ -31,6 +34,7 @@ the same tag.
| `build-args` | no | — | Multiline `KEY=VALUE` build args. Visible in `docker history` — never put secrets here. | | `build-args` | no | — | Multiline `KEY=VALUE` build args. Visible in `docker history` — never put secrets here. |
| `secrets` | no | — | Multiline `id=VALUE` BuildKit secrets (`--secret`). For tokens the build needs (e.g. a ci-bot token to `go mod download` a private module) that must not leak into layers. Reference with `RUN --mount=type=secret,id=<id>`. | | `secrets` | no | — | Multiline `id=VALUE` BuildKit secrets (`--secret`). For tokens the build needs (e.g. a ci-bot token to `go mod download` a private module) that must not leak into layers. Reference with `RUN --mount=type=secret,id=<id>`. |
| `smoke-test` | no | — | Shell command run after build. `$IMAGE` is set to `<image>:<run_number>`. Non-zero exit fails the action. | | `smoke-test` | no | — | Shell command run after build. `$IMAGE` is set to `<image>:<run_number>`. Non-zero exit fails the action. |
| `token` | no | — | Registry token with `read:package` capability. Required to pull a private base image; omit for public bases. |
## Outputs ## Outputs
+5 -4
View File
@@ -37,10 +37,11 @@ inputs:
default: '' default: ''
token: token:
description: | description: |
ci-bot token (CI_BOT_TOKEN) for `docker login code.fritzlab.net`. Required Registry token with `read:package` capability for
dev marked this conversation as resolved Outdated
Outdated
Review

This drops the identity half of the input contract. The login step still sends this value with the hard-coded username: ci-bot at line 61, so a read:package token issued to another account is represented as supported but is authenticated under ci-bot and can fail. Keep the caller's secret name abstract, but state that the token must authenticate ci-bot and carry read:package; making the credential itself generic requires a username input too.

This drops the identity half of the input contract. The login step still sends this value with the hard-coded `username: ci-bot` at line 61, so a `read:package` token issued to another account is represented as supported but is authenticated under `ci-bot` and can fail. Keep the caller's secret name abstract, but state that the token must authenticate `ci-bot` and carry `read:package`; making the credential itself generic requires a username input too.
Outdated
Review

You supply a read:package token from another account, then this action submits it with the fixed username: ci-bot at line 61 and stops before the build. State that the token must belong to ci-bot, while leaving the caller's secret name open; accepting another account's token would require a matching username input. The failed login needs this recovery path in the input contract.

You supply a `read:package` token from another account, then this action submits it with the fixed `username: ci-bot` at line 61 and stops before the build. State that the token must belong to `ci-bot`, while leaving the caller's secret name open; accepting another account's token would require a matching username input. The failed login needs this recovery path in the input contract.
when the Dockerfile's FROM is a PRIVATE fritzlab image (e.g. FROM `docker login code.fritzlab.net`. Required when the Dockerfile's FROM is a
code.fritzlab.net/fritzlab/base) — the org is `limited`, so buildx can't pull PRIVATE fritzlab image (e.g. FROM code.fritzlab.net/fritzlab/base) — the
it anonymously. Omit for public-base builds (e.g. base itself = FROM debian). org is `limited`, so buildx can't pull it anonymously. Omit for public-base
builds (e.g. base itself = FROM debian).
required: false required: false
default: '' default: ''
outputs: outputs: