Skip to content

[Security] Add BuildKit secret support to the shared Docker build action #2

Description

@infin1t3

Context

The shared composite action at .github/actions/docker/build_and_push/action.yml currently forwards only build_args to docker/build-push-action.

pubky/pubky-app needs a Sentry token during the builder stage to upload source maps. It currently passes that credential through the shared action as:

build_args: |
  SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}

The consuming Dockerfile then declares ARG SENTRY_AUTH_TOKEN and uses it in a RUN instruction.

Docker explicitly recommends that credentials are not passed through ARG/ENV; BuildKit secret mounts should be used instead. The current multi-stage Dockerfile does not copy the builder filesystem into the final runner image, so this issue is not reporting a confirmed token in the published runtime image. The problem is that the credential is sent through the non-secret build-argument channel and may be exposed through build metadata, cache/provenance, build records, or any Dockerfile instruction executed for that build.

Proposed change

Extend the shared build_and_push action with a generic BuildKit secret interface, preferably secret_envs and optionally secrets/secret_files, and forward it to docker/build-push-action.

Example consumer API:

- name: Build and push image
  uses: pubky/ci-workflows/.github/actions/docker/build_and_push@main
  env:
    SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
  with:
    # Existing non-sensitive values remain build args.
    build_args: |
      SENTRY_ORG=synonym-52
      SENTRY_PROJECT=pubky-app
    secret_envs: |
      SENTRY_AUTH_TOKEN=SENTRY_AUTH_TOKEN

The consumer Dockerfile can then read the token only for the source-map upload instruction using RUN --mount=type=secret, without declaring ARG SENTRY_AUTH_TOKEN.

Acceptance criteria

  • build_and_push exposes a documented, generic BuildKit secret input.
  • The input is forwarded to the corresponding docker/build-push-action secret mechanism, not build-args.
  • Secret values are not printed by the composite action or copied into outputs.
  • Existing consumers that do not use build secrets remain backward compatible.
  • Add an example showing how a caller maps a GitHub secret to a BuildKit secret.
  • Migrate pubky/pubky-app Sentry source-map upload to the new interface.
  • Remove SENTRY_AUTH_TOKEN from build_args and remove ARG SENTRY_AUTH_TOKEN from the app Dockerfile.
  • Verify that the source-map upload still runs for trusted builds and is skipped cleanly when the token is absent.
  • Verify that the token is absent from Docker build args, image metadata/history, exported cache/provenance, build records, and logs.

References

Out of scope

This issue is specifically about the secure transport of credentials consumed during Docker builds. Action ref pinning, preview GCP IAM policy, image digest pinning, and Docker build-context policy are separate organizational hardening decisions.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions