Skip to content

Add buildSecrets config for passing secrets to image builds#486

Merged
ianpittwood merged 15 commits into
mainfrom
feature/build-secrets
Apr 28, 2026
Merged

Add buildSecrets config for passing secrets to image builds#486
ianpittwood merged 15 commits into
mainfrom
feature/build-secrets

Conversation

@ianpittwood
Copy link
Copy Markdown
Contributor

@ianpittwood ianpittwood commented Apr 24, 2026

Summary

  • Adds Image.buildSecrets — a list of {id, envVar} entries — that is translated into --secret id=<id>,env=<envVar> options for sequential docker buildx build and into {type: env, id, env} per-target entries for Docker Bake plans.
  • BuildSecret.id and BuildSecret.envVar are pattern-validated to safe character sets (alphanumerics + _/./- for ids; POSIX env-var names for envVar) to prevent CLI argument injection like id=foo,src=/etc/passwd.
  • Resolution lives in a single ImageTarget.resolved_build_secrets property; sequential and bake paths call as_cli_option() / as_bake_json() on the resolved entries.
  • Secrets whose envVar is unset are skipped with a warning; required-secret enforcement stays with Docker via RUN --mount=type=secret,id=<id>[,required=true] in the Containerfile.
  • Addresses Mount github token as a secret to builds #483 — enables product repos to inject GITHUB_TOKEN into quarto install tinytex (and similar) to avoid unauthenticated GitHub API rate limiting.

Example config

images:
  - name: connect-content
    buildSecrets:
      - id: github_token
        envVar: GITHUB_TOKEN

Containerfile usage:

RUN --mount=type=secret,id=github_token,required=false \
    GH_TOKEN="\$(cat /run/secrets/github_token 2>/dev/null || true)" \
    quarto install tinytex

Test plan

  • Unit tests cover the BuildSecret model (incl. pattern rejection of injection-flavored values), Image.buildSecrets parsing, and resolution behavior on both build paths.
  • Verify sequential build in a product repo with `GITHUB_TOKEN` set — secret appears in `docker buildx build --secret ...` args.
  • Verify bake plan JSON includes per-target `secret: [{type: env, id: ..., env: ...}]` entries.
  • Verify a missing `envVar` logs a warning and does not break the build (when the Containerfile mount uses `required=false`).

🤖 Generated with Claude Code

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 24, 2026

Test Results

1 444 tests  +47   1 444 ✅ +47   8m 33s ⏱️ +13s
    1 suites ± 0       0 💤 ± 0 
    1 files   ± 0       0 ❌ ± 0 

Results for commit d2856d4. ± Comparison against base commit d10580c.

♻️ This comment has been updated with latest results.

@ianpittwood ianpittwood marked this pull request as ready for review April 24, 2026 19:21
@ianpittwood ianpittwood requested a review from bschwedler as a code owner April 24, 2026 19:21
@ianpittwood
Copy link
Copy Markdown
Contributor Author

CI is a flaky failure, this should be good to go.

Comment thread posit-bakery/posit_bakery/config/image/build_secret.py
@ianpittwood ianpittwood requested a review from bschwedler April 24, 2026 22:07
@ianpittwood ianpittwood force-pushed the feature/build-secrets branch from 6ea6ae7 to 7f512ed Compare April 27, 2026 14:12
ianpittwood and others added 3 commits April 27, 2026 10:19
Introduces an Image.buildSecrets list of {id, envVar} entries that are
translated into --secret options for both sequential docker builds and
bake plans. Missing envVars are skipped with a warning, deferring any
required-secret enforcement to Docker via the Containerfile mount.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Covers the BuildSecret model, Image.buildSecrets parsing, env resolution
into `--secret` options (including the unset-envVar warning path), and
that resolved secrets flow through to both docker.build's `secrets`
kwarg and the bake target's `secret` field.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds pattern validators so BuildSecret rejects values containing CLI
metacharacters (commas, equals, whitespace, shell specials) that could
otherwise inject extra `--secret` sub-options like `src=/etc/passwd`.
The id pattern allows alphanumerics, underscores, dots, and hyphens
(disallowing leading `-`/`.`); envVar enforces POSIX env-var naming.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ianpittwood ianpittwood force-pushed the feature/build-secrets branch from 7f512ed to 0d05011 Compare April 27, 2026 16:19
Pulls the env-var resolution + warning logic into a single
ImageTarget.resolved_build_secrets property, and adds
BuildSecret.as_bake_json() to mirror as_cli_option(). Each build path
now just maps the resolved secrets through the matching formatter,
keeping bake.py free of os/logging concerns.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ianpittwood and others added 10 commits April 27, 2026 10:30
Add an optional build secret (`github_token`) to the `RUN` step that
installs TinyTeX, and export it as `GH_TOKEN` when present. Quarto's
TinyTeX installer uses this token to avoid GitHub API rate limits when
resolving release metadata.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Move the --mount=type=secret,id=github_token,required=false flag into a
dedicated macro so the mount option can be referenced consistently and
documented alongside the shell-side read in install_tinytex_command.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Align the expected Containerfile in test_patch_version_with_dependencies_macros
with the new github_token secret mount and GH_TOKEN export emitted by the
Quarto install macro.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the shell `if [ -s ... ]; then export GH_TOKEN=...; fi` block
with an inline `GH_TOKEN="$([ -s ... ] && cat ...)"` prefix on the
`quarto install tinytex` command so the variable is scoped to that one
process and not exported into the surrounding shell. When the secret is
not mounted the substitution yields an empty string, which Quarto
treats the same as an unset token.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Introduces an Image.buildSecrets list of {id, envVar} entries that are
translated into --secret options for both sequential docker builds and
bake plans. Missing envVars are skipped with a warning, deferring any
required-secret enforcement to Docker via the Containerfile mount.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Covers the BuildSecret model, Image.buildSecrets parsing, env resolution
into `--secret` options (including the unset-envVar warning path), and
that resolved secrets flow through to both docker.build's `secrets`
kwarg and the bake target's `secret` field.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds pattern validators so BuildSecret rejects values containing CLI
metacharacters (commas, equals, whitespace, shell specials) that could
otherwise inject extra `--secret` sub-options like `src=/etc/passwd`.
The id pattern allows alphanumerics, underscores, dots, and hyphens
(disallowing leading `-`/`.`); envVar enforces POSIX env-var naming.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pulls the env-var resolution + warning logic into a single
ImageTarget.resolved_build_secrets property, and adds
BuildSecret.as_bake_json() to mirror as_cli_option(). Each build path
now just maps the resolved secrets through the matching formatter,
keeping bake.py free of os/logging concerns.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ianpittwood ianpittwood force-pushed the feature/build-secrets branch from 721c8c6 to f480e7a Compare April 28, 2026 14:32
…ecret

Mount GitHub token secret for Quarto TinyTeX install
@ianpittwood ianpittwood enabled auto-merge April 28, 2026 14:34
@ianpittwood ianpittwood added this pull request to the merge queue Apr 28, 2026
Merged via the queue into main with commit beb1764 Apr 28, 2026
23 checks passed
@ianpittwood ianpittwood deleted the feature/build-secrets branch April 28, 2026 14:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants