Docker build arguments (--build-arg) are embedded in the image layer metadata. Anyone who pulls the image can extract them with docker history or docker inspect. Passing secrets as build args makes them permanently visible in the image.
- uses: docker/build-push-action@v5
with:
build-args: |
NPM_TOKEN=${{ secrets.NPM_TOKEN }}
After pulling the image:
docker history --no-trunc <image> | grep NPM_TOKEN
The secret is visible in plaintext in the build history.
Use Docker BuildKit secrets instead of build args:
# Before (secret in image layers)
- uses: docker/build-push-action@v5
with:
build-args: |
NPM_TOKEN=${{ secrets.NPM_TOKEN }}
# After (secret mounted at build time only)
- uses: docker/build-push-action@v5
with:
secrets: |
npm_token=${{ secrets.NPM_TOKEN }}
In the Dockerfile, access the secret via mount:
RUN --mount=type=secret,id=npm_token \
NPM_TOKEN=$(cat /run/secrets/npm_token) npm ci
Build args are not secret -- they are recorded in image metadata. Anyone with access to the image (public registry, compromised pull) can extract every build arg value.