From 5c603b1a0cb8ec023604ee0d5d645d717062048a Mon Sep 17 00:00:00 2001 From: butschster Date: Fri, 27 Mar 2026 01:03:39 +0400 Subject: [PATCH] Fix GitHub token leak in Docker image builds The GH_TOKEN was passed as a build-arg and stored via ENV in image layers, making it visible through docker history/inspect to anyone pulling the published image. Switch to BuildKit secrets: - Dockerfile: use RUN --mount=type=secret,id=gh_token so the token is only available in memory during the RUN command and never persisted in any layer - GitHub Actions workflows: pass token via secrets instead of build-args - docker-compose.yaml: use secrets definition sourced from environment variable Co-Authored-By: Claude Opus 4.6 (1M context) --- .docker/Dockerfile | 10 +++++----- .github/workflows/docker-dev-image.yml | 3 ++- .github/workflows/docker-image.yml | 3 ++- docker-compose.yaml | 8 +++++++- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/.docker/Dockerfile b/.docker/Dockerfile index 14336a95..7a8d2ee4 100644 --- a/.docker/Dockerfile +++ b/.docker/Dockerfile @@ -2,7 +2,6 @@ ARG ROAD_RUNNER_IMAGE=2024.2.1 ARG CENTRIFUGO_IMAGE=v4 ARG DOLT_IMAGE=1.42.8 ARG FRONTEND_IMAGE_TAG=latest -ARG GH_TOKEN # Build centrifugo binary FROM centrifugo/centrifugo:$CENTRIFUGO_IMAGE as centrifugo @@ -16,7 +15,6 @@ FROM golang:1.25-alpine as rr ARG APP_VERSION="2025.1.1" ARG VELOX_CONFIG="velox.toml" -ARG GH_TOKEN # copy required files from builder image COPY --from=velox /usr/bin/vx /usr/bin/vx @@ -24,13 +22,15 @@ COPY ${VELOX_CONFIG} . # we don't need CGO ENV CGO_ENABLED=0 -ENV RT_TOKEN=${GH_TOKEN} ARG CACHE_BUST=1 RUN echo $CACHE_BUST -# RUN build -RUN vx build -c velox.toml -o /usr/bin/ +# Build RoadRunner with velox. The GitHub token is mounted as a secret +# and never stored in image layers. +RUN --mount=type=secret,id=gh_token \ + RT_TOKEN=$(cat /run/secrets/gh_token) \ + vx build -c velox.toml -o /usr/bin/ # Build JS files FROM ghcr.io/buggregator/frontend:$FRONTEND_IMAGE_TAG as frontend diff --git a/.github/workflows/docker-dev-image.yml b/.github/workflows/docker-dev-image.yml index 580abbd2..5a9f8741 100644 --- a/.github/workflows/docker-dev-image.yml +++ b/.github/workflows/docker-dev-image.yml @@ -45,7 +45,8 @@ jobs: APP_VERSION=${{ steps.previoustag.outputs.tag }} FRONTEND_IMAGE_TAG=latest BRANCH=${{ steps.previoustag.outputs.tag }} - GH_TOKEN=${{ secrets.GHCR_PASSWORD }} VELOX_CONFIG=./.docker/velox.toml + secrets: | + gh_token=${{ secrets.GHCR_PASSWORD }} tags: ghcr.io/${{ github.repository }}:dev, ghcr.io/${{ github.repository }}:${{ steps.previoustag.outputs.tag }} diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index a4427db6..15cfec96 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -99,8 +99,9 @@ jobs: APP_VERSION=${{ github.ref_name }} FRONTEND_IMAGE_TAG=${{ secrets.FRONTEND_IMAGE_TAG }} BRANCH=${{ github.ref_name }} - GH_TOKEN=${{ secrets.GHCR_PASSWORD }} VELOX_CONFIG=./.docker/velox.toml + secrets: | + gh_token=${{ secrets.GHCR_PASSWORD }} tags: ${{ steps.docker_meta.outputs.tags }} labels: ${{ steps.docker_meta.outputs.labels }} cache-from: type=gha diff --git a/docker-compose.yaml b/docker-compose.yaml index 5f32c782..10c70069 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -28,8 +28,10 @@ services: build: dockerfile: Dockerfile context: .docker + secrets: + - gh_token args: - GH_TOKEN: "${GH_TOKEN}" + VELOX_CONFIG: velox.toml environment: # RR_LOG_LEVEL: debug # RR_LOG_TCP_LEVEL: debug @@ -119,6 +121,10 @@ services: networks: - buggregator-network +secrets: + gh_token: + environment: "GH_TOKEN" + networks: buggregator-network: ipam: