Skip to main content

Documentation Index

Fetch the complete documentation index at: https://tally.wharflab.com/llms.txt

Use this file to discover all available pages before exploring further.

A Ruby-shaped Dockerfile declares a build-time credential (Bundler host token, NPM/Yarn auth, RubyGems API key) via ARG or ENV. The credential ends up in image cache key data and image history. BuildKit’s secret-mount syntax is the supported alternative.
PropertyValue
SeverityInfo
CategorySecurity
DefaultEnabled (advisory)
Auto-fixFixSuggestion (no-edit)

Description

Build-time credentials passed via ARG or ENV end up in two places that the user generally doesn’t want:
  • Image cache key data. ARGs become part of the cache key BuildKit uses to deduplicate build steps. Different secret values produce different cache keys, leaking the credential into anyone with read access to the cache.
  • Image history. Once the credential is consumed via RUN or referenced from ENV, it ends up in docker history --no-trunc <image> for anyone who can pull the image.
BuildKit’s RUN --mount=type=secret,id=<id>,env=<VAR> is the documented production pattern: the secret is exposed only inside the one RUN and never reaches the image cache key or layer content. This is the constructive companion to tally/ruby/secrets-in-arg-or-env, which catches the same class of issue for Rails-app secrets at error severity. This rule covers Ruby-ecosystem build-time credentials specifically:
  • BUNDLE_GITHUB__COM, BUNDLE_BITBUCKET__ORG, BUNDLE_GITLAB__COM — Bundler host tokens.
  • BUNDLE_<HOST>__<TLD> — the generic Bundler host-credential pattern (host names use __ for .). Compound TLDs are supported (BUNDLE_GEMS__ACME__CO__UK). Bundler’s non-host config namespaces (BUNDLE_LOCAL__<gem>, BUNDLE_BUILD__<gem>) are excluded because they encode gem identity rather than a hostname.
  • GEM_HOST_API_KEY — RubyGems push key.
  • NPM_TOKEN, YARN_AUTH_TOKEN — npm/yarn auth tokens, commonly used during bin/rails assets:precompile to fetch private packages.
The corpus shows only 1 of 196 Dockerfiles using RUN --mount=type=secret. This rule’s job is to surface the supported alternative at the moment a user reaches for ARG/ENV. The rule only fires on Ruby-shaped Dockerfiles — non-Ruby Dockerfiles that happen to use one of these env-var names (e.g. a Node.js Dockerfile with NPM_TOKEN) are ignored. A meta-ARG (declared before any FROM) also requires at least one Ruby stage somewhere in the file. Stages explicitly named dev/development/test/testing/ci/debug are skipped.

Examples

Before

FROM ruby:3.3-slim
ARG BUNDLE_GITHUB__COM
ENV BUNDLE_GITHUB__COM=$BUNDLE_GITHUB__COM
RUN bundle install

After

FROM ruby:3.3-slim
RUN --mount=type=secret,id=github_token,env=BUNDLE_GITHUB__COM \
    bundle install
Pass the secret at build time:
docker buildx build --secret id=github_token,src=$HOME/.netrc-github .
The secret exists for the duration of that one RUN and never reaches image content or cache key data.

Auto-fix

FixSuggestion (no-edit). The exact rewrite depends on the user’s CI / vault / secret-injection setup, so the rule cannot auto-apply. Description names the canonical form including the secret_id it suggests.

References