From e8f4b36c52fe5c26342322e0e2a1ab34b3e1ea9e Mon Sep 17 00:00:00 2001 From: Vipin Sharma Date: Wed, 29 Apr 2026 16:27:27 -0700 Subject: [PATCH 1/4] PE-8578 Use earthly secrets to pass pro key --- .arg.template | 11 +++++++++-- Earthfile | 44 +++++++++++++++++++++++++++++++++++++------- 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/.arg.template b/.arg.template index a27d42bd..c60a71f5 100644 --- a/.arg.template +++ b/.arg.template @@ -20,8 +20,15 @@ FORCE_INTERACTIVE_INSTALL=false # Interactive Install Configuration # FORCE_INTERACTIVE_INSTALL=true # Set to true to choose interactive install as the default boot option and launch the Interactive Install TUI -# If you have Ubuntu Pro, use the UBUNTU_PRO_KEY variable to activate it as part of the image build -# UBUNTU_PRO_KEY=your-key +# Ubuntu Pro (optional) +# Do NOT put your Pro token in this file or in any build arg - it would end up +# in `docker history`, the Earthly build cache, and shell history. Instead: +# 1. Store the token once as an Earthly secret (paste interactively): +# earthly secrets set UBUNTU_PRO_KEY +# For Earthly Cloud, also pass --org/--project to scope the secret. +# Or pass it ad-hoc on the CLI: --secret UBUNTU_PRO_KEY= +# 2. Enable attach during the base-image build by uncommenting the line below. +# UBUNTU_PRO_ATTACH=true # For enabling Secure Boot with Full Disk Encryption # IS_UKI=true diff --git a/Earthfile b/Earthfile index 24059a9d..215dbf30 100644 --- a/Earthfile +++ b/Earthfile @@ -49,7 +49,13 @@ ARG EDGE_CUSTOM_CONFIG=.edge-custom-config.yaml ARG ARCH ARG DISABLE_SELINUX=true ARG CIS_HARDENING=false -ARG UBUNTU_PRO_KEY +# Ubuntu Pro toggle. The token itself is NEVER passed as a build arg. +# Set UBUNTU_PRO_ATTACH=true and provide the token via an Earthly secret, e.g.: +# earthly secrets set UBUNTU_PRO_KEY # paste token interactively +# earthly --secret UBUNTU_PRO_KEY=... +base-image --UBUNTU_PRO_ATTACH=true +# This keeps the token out of `docker history`, build-arg metadata, and the +# build cache. +ARG UBUNTU_PRO_ATTACH=false # DRBD version for Piraeus pack ARG DRBD_VERSION="9.2.13" @@ -710,10 +716,27 @@ base-image: # OS == Ubuntu IF [ "$OS_DISTRIBUTION" = "ubuntu" ] && [ "$ARCH" = "amd64" ] - IF [ ! -z "$UBUNTU_PRO_KEY" ] - RUN sed -i '/^[[:space:]]*$/d' /etc/os-release && \ - apt update && apt-get install -y snapd && \ - pro attach $UBUNTU_PRO_KEY + IF [ "$UBUNTU_PRO_ATTACH" = "true" ] + # The token is mounted via Earthly's secret store as an env var + # that lives only for the duration of this RUN. It is materialized + # into an attach-config file using the shell builtin `printf`, so + # the value never appears in any process argv (/proc//cmdline), + # docker build history, or shell history. The env var is unset and + # the temp file shredded before the RUN exits, so nothing about the + # token survives in the resulting layer. + RUN --secret UBUNTU_PRO_KEY \ + set +o history 2>/dev/null || true; \ + if [ -z "${UBUNTU_PRO_KEY:-}" ]; then \ + echo "UBUNTU_PRO_ATTACH=true but secret UBUNTU_PRO_KEY is not set." >&2; \ + echo "Provide it via 'earthly secrets set UBUNTU_PRO_KEY' or '--secret UBUNTU_PRO_KEY=...'." >&2; \ + exit 1; \ + fi && \ + sed -i '/^[[:space:]]*$/d' /etc/os-release && \ + apt update && apt-get install -y snapd && \ + ( umask 077 && printf 'token: %s\n' "$UBUNTU_PRO_KEY" > /tmp/.pro-attach.yaml ) && \ + unset UBUNTU_PRO_KEY && \ + pro attach --attach-config /tmp/.pro-attach.yaml && \ + { command -v shred >/dev/null 2>&1 && shred -uz /tmp/.pro-attach.yaml; } || rm -f /tmp/.pro-attach.yaml END RUN apt-get update && \ @@ -785,8 +808,15 @@ base-image: RUN /tmp/harden.sh && rm /tmp/harden.sh END - IF [ ! -z "$UBUNTU_PRO_KEY" ] - RUN pro detach --assume-yes + IF [ "$UBUNTU_PRO_ATTACH" = "true" ] + # Detach the entitlement, then scrub any on-disk traces. `pro` may + # echo or log token fragments under /var/log/ubuntu-advantage* and + # leave private state under /var/lib/ubuntu-advantage/private; we + # truncate those so the resulting image carries no residue. + RUN pro detach --assume-yes && \ + find /var/log -maxdepth 3 -name 'ubuntu-advantage*' -type f -exec sh -c ': > "$1"' _ {} \; 2>/dev/null || true && \ + rm -rf /var/lib/ubuntu-advantage/private 2>/dev/null || true && \ + rm -f /tmp/.pro-attach.yaml 2>/dev/null || true END # OS == Opensuse From 067608b517583d3f627fedc446e459886606d46c Mon Sep 17 00:00:00 2001 From: Vipin Sharma Date: Thu, 30 Apr 2026 16:37:44 -0700 Subject: [PATCH 2/4] Pass the secret from earthly.sh --- .arg.template | 17 +++++++++----- Earthfile | 12 +++++++--- earthly.sh | 65 +++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 83 insertions(+), 11 deletions(-) diff --git a/.arg.template b/.arg.template index c60a71f5..fa782ff3 100644 --- a/.arg.template +++ b/.arg.template @@ -22,12 +22,17 @@ FORCE_INTERACTIVE_INSTALL=false # Ubuntu Pro (optional) # Do NOT put your Pro token in this file or in any build arg - it would end up -# in `docker history`, the Earthly build cache, and shell history. Instead: -# 1. Store the token once as an Earthly secret (paste interactively): -# earthly secrets set UBUNTU_PRO_KEY -# For Earthly Cloud, also pass --org/--project to scope the secret. -# Or pass it ad-hoc on the CLI: --secret UBUNTU_PRO_KEY= -# 2. Enable attach during the base-image build by uncommenting the line below. +# in `docker history`, the Earthly build cache, and shell history. +# Recommended flow (local, no Earthly Cloud needed): +# read -rs UBUNTU_PRO_KEY # paste token, press Enter; nothing echoes +# export UBUNTU_PRO_KEY +# earthly --secret UBUNTU_PRO_KEY +base-image --UBUNTU_PRO_ATTACH=true +# unset UBUNTU_PRO_KEY +# Or load from a file: earthly --secret-file UBUNTU_PRO_KEY=/path/to/token ... +# (avoid --secret UBUNTU_PRO_KEY= directly - that lands in shell history) +# If you use Earthly Cloud: `earthly account login`, then +# `earthly secret set /user/UBUNTU_PRO_KEY`. +# Then uncomment the toggle below (or pass --UBUNTU_PRO_ATTACH=true on the CLI): # UBUNTU_PRO_ATTACH=true # For enabling Secure Boot with Full Disk Encryption diff --git a/Earthfile b/Earthfile index 215dbf30..583b6e2d 100644 --- a/Earthfile +++ b/Earthfile @@ -50,9 +50,15 @@ ARG ARCH ARG DISABLE_SELINUX=true ARG CIS_HARDENING=false # Ubuntu Pro toggle. The token itself is NEVER passed as a build arg. -# Set UBUNTU_PRO_ATTACH=true and provide the token via an Earthly secret, e.g.: -# earthly secrets set UBUNTU_PRO_KEY # paste token interactively -# earthly --secret UBUNTU_PRO_KEY=... +base-image --UBUNTU_PRO_ATTACH=true +# Set UBUNTU_PRO_ATTACH=true and supply the token via an Earthly secret. The +# recommended local flow (no Earthly Cloud needed): +# read -rs UBUNTU_PRO_KEY # paste token, press Enter; no echo +# export UBUNTU_PRO_KEY +# earthly --secret UBUNTU_PRO_KEY +base-image --UBUNTU_PRO_ATTACH=true +# unset UBUNTU_PRO_KEY +# Or load from a file: earthly --secret-file UBUNTU_PRO_KEY=/path/to/token ... +# If you use Earthly Cloud, `earthly account login` then +# `earthly secret set /user/UBUNTU_PRO_KEY` works too. # This keeps the token out of `docker history`, build-arg metadata, and the # build cache. ARG UBUNTU_PRO_ATTACH=false diff --git a/earthly.sh b/earthly.sh index 9c50e22d..0601a04d 100755 --- a/earthly.sh +++ b/earthly.sh @@ -53,10 +53,11 @@ function build_with_proxy() { -e HTTP_PROXY="$HTTP_PROXY" \ -e NO_PROXY="$NO_PROXY" \ -e no_proxy="$NO_PROXY" \ + "${DOCKER_SECRET_ENV[@]}" \ -v "$(pwd)":/workspace \ -v "$(pwd)/certs:/usr/local/share/ca-certificates:ro" \ --entrypoint /workspace/earthly-entrypoint.sh \ - "$SPECTRO_PUB_REPO"/third-party/edge/earthly/earthly:"$EARTHLY_VERSION" --allow-privileged "$@" + "$SPECTRO_PUB_REPO"/third-party/edge/earthly/earthly:"$EARTHLY_VERSION" --allow-privileged "${EARTHLY_SECRET_ARGS[@]}" "$@" } function build_without_proxy() { @@ -67,7 +68,7 @@ function build_without_proxy() { fi # Run Earthly in Docker to create artifacts Variables are passed from the .arg file - docker run --privileged ${DOCKER_CONFIG_MOUNT:+"$DOCKER_CONFIG_MOUNT"} -v /var/run/docker.sock:/var/run/docker.sock --rm --env EARTHLY_BUILD_ARGS -t -e GLOBAL_CONFIG="$global_config" -v "$(pwd)":/workspace "$SPECTRO_PUB_REPO"/third-party/edge/earthly/earthly:"$EARTHLY_VERSION" --allow-privileged "$@" + docker run --privileged ${DOCKER_CONFIG_MOUNT:+"$DOCKER_CONFIG_MOUNT"} -v /var/run/docker.sock:/var/run/docker.sock --rm --env EARTHLY_BUILD_ARGS -t -e GLOBAL_CONFIG="$global_config" "${DOCKER_SECRET_ENV[@]}" -v "$(pwd)":/workspace "$SPECTRO_PUB_REPO"/third-party/edge/earthly/earthly:"$EARTHLY_VERSION" --allow-privileged "${EARTHLY_SECRET_ARGS[@]}" "$@" } function print_os_pack() { @@ -108,6 +109,66 @@ SPECTRO_PUB_REPO=us-docker.pkg.dev/palette-images EARTHLY_VERSION=v0.8.15 source .arg +# --------------------------------------------------------------------------- +# Secret handling +# +# Some build inputs (currently only the Ubuntu Pro token) must NEVER appear in +# `docker history`, Earthly build-arg metadata, the build cache, shell history, +# or any process argv. We collect them here, prompt for any that aren't +# pre-exported, and forward them into the build via: +# - `docker run -e NAME` (no =value) -> passthrough into the earthly +# container's env +# - `earthly --secret NAME` (no =value) -> Earthly reads the value from +# its env and hands it to +# BuildKit as a secret, which +# the Earthfile consumes via +# `RUN --secret NAME ...` +# Both forms keep the value off the command line. +# --------------------------------------------------------------------------- +EARTHLY_SECRET_ARGS=() +DOCKER_SECRET_ENV=() + +if [ "${UBUNTU_PRO_ATTACH:-false}" = "true" ]; then + # Catch the legacy pattern (token sitting in `.arg`) early - that's the + # exact thing we're trying to avoid. + if [ -f .arg ] && grep -qE '^[[:space:]]*UBUNTU_PRO_KEY[[:space:]]*=' .arg; then + echo >&2 "WARNING: UBUNTU_PRO_KEY is set in .arg. Remove it - tokens placed there" + echo >&2 " leak via the build cache and process listings. Provide it via" + echo >&2 " the UBUNTU_PRO_KEY env var or the interactive prompt instead." + fi + + if [ -z "${UBUNTU_PRO_KEY:-}" ]; then + # Prompt without echoing. Prefer /dev/tty so the prompt works even when + # stdin has been redirected (common in CI wrappers). + if [ -r /dev/tty ] && [ -w /dev/tty ]; then + printf "Enter Ubuntu Pro token (input hidden): " >/dev/tty + stty -echo /dev/tty + elif [ -t 0 ]; then + read -rs -p "Enter Ubuntu Pro token (input hidden): " UBUNTU_PRO_KEY + echo + else + echo >&2 "Error: UBUNTU_PRO_ATTACH=true but UBUNTU_PRO_KEY is not set and" + echo >&2 " no terminal is available to prompt for it. Export" + echo >&2 " UBUNTU_PRO_KEY before invoking earthly.sh, e.g.:" + echo >&2 " read -rs UBUNTU_PRO_KEY && export UBUNTU_PRO_KEY" + echo >&2 " ./earthly.sh +iso" + exit 1 + fi + fi + + if [ -z "${UBUNTU_PRO_KEY:-}" ]; then + echo >&2 "Error: Empty Ubuntu Pro token. Aborting." + exit 1 + fi + + export UBUNTU_PRO_KEY + DOCKER_SECRET_ENV=(-e UBUNTU_PRO_KEY) + EARTHLY_SECRET_ARGS=(--secret UBUNTU_PRO_KEY) +fi + # Workaround to support deprecated field PROXY_CERT_PATH if [ -n "$PROXY_CERT_PATH" ]; then echo "PROXY_CERT_PATH is deprecated. Please place your certificates in the certs directory." From 4882299184223efed357ea4d92ac797e9e7483dc Mon Sep 17 00:00:00 2001 From: Vipin Sharma Date: Thu, 30 Apr 2026 16:59:22 -0700 Subject: [PATCH 3/4] Fix --- Earthfile | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/Earthfile b/Earthfile index 583b6e2d..f2a34fd5 100644 --- a/Earthfile +++ b/Earthfile @@ -726,23 +726,19 @@ base-image: # The token is mounted via Earthly's secret store as an env var # that lives only for the duration of this RUN. It is materialized # into an attach-config file using the shell builtin `printf`, so - # the value never appears in any process argv (/proc//cmdline), - # docker build history, or shell history. The env var is unset and - # the temp file shredded before the RUN exits, so nothing about the - # token survives in the resulting layer. + # the value never appears in any process argv (/proc//cmdline) + # or in docker build history. The env var is unset and the temp + # file removed before the RUN exits, so nothing about the token + # survives in the resulting layer. If `--secret UBUNTU_PRO_KEY` + # is not supplied, Earthly aborts before this RUN is invoked. RUN --secret UBUNTU_PRO_KEY \ - set +o history 2>/dev/null || true; \ - if [ -z "${UBUNTU_PRO_KEY:-}" ]; then \ - echo "UBUNTU_PRO_ATTACH=true but secret UBUNTU_PRO_KEY is not set." >&2; \ - echo "Provide it via 'earthly secrets set UBUNTU_PRO_KEY' or '--secret UBUNTU_PRO_KEY=...'." >&2; \ - exit 1; \ - fi && \ sed -i '/^[[:space:]]*$/d' /etc/os-release && \ - apt update && apt-get install -y snapd && \ - ( umask 077 && printf 'token: %s\n' "$UBUNTU_PRO_KEY" > /tmp/.pro-attach.yaml ) && \ + apt-get update && apt-get install -y snapd && \ + umask 077 && \ + printf 'token: %s\n' "$UBUNTU_PRO_KEY" > /tmp/.pro-attach.yaml && \ unset UBUNTU_PRO_KEY && \ pro attach --attach-config /tmp/.pro-attach.yaml && \ - { command -v shred >/dev/null 2>&1 && shred -uz /tmp/.pro-attach.yaml; } || rm -f /tmp/.pro-attach.yaml + rm -f /tmp/.pro-attach.yaml END RUN apt-get update && \ From f132ac91ae770c15e50dc4c1d14ece0419099da1 Mon Sep 17 00:00:00 2001 From: Vipin Sharma Date: Fri, 1 May 2026 13:17:45 -0700 Subject: [PATCH 4/4] Fix the guidelines for PRO TOKEN use --- .arg.template | 30 ++++++++++++++++++++---------- Earthfile | 23 ++++++++++++----------- 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/.arg.template b/.arg.template index fa782ff3..cc400181 100644 --- a/.arg.template +++ b/.arg.template @@ -23,16 +23,26 @@ FORCE_INTERACTIVE_INSTALL=false # Ubuntu Pro (optional) # Do NOT put your Pro token in this file or in any build arg - it would end up # in `docker history`, the Earthly build cache, and shell history. -# Recommended flow (local, no Earthly Cloud needed): -# read -rs UBUNTU_PRO_KEY # paste token, press Enter; nothing echoes -# export UBUNTU_PRO_KEY -# earthly --secret UBUNTU_PRO_KEY +base-image --UBUNTU_PRO_ATTACH=true -# unset UBUNTU_PRO_KEY -# Or load from a file: earthly --secret-file UBUNTU_PRO_KEY=/path/to/token ... -# (avoid --secret UBUNTU_PRO_KEY= directly - that lands in shell history) -# If you use Earthly Cloud: `earthly account login`, then -# `earthly secret set /user/UBUNTU_PRO_KEY`. -# Then uncomment the toggle below (or pass --UBUNTU_PRO_ATTACH=true on the CLI): +# +# Recommended flow (use the earthly.sh wrapper): +# 1. Uncomment the toggle below: +# UBUNTU_PRO_ATTACH=true +# 2. Run the build as usual: +# ./earthly.sh +iso # or +base-image, +build-all-images, etc. +# The script will prompt for the token (input hidden, no echo) and forward +# it to Earthly as a secret. The token never lands in `.arg`, on the +# earthly command line, in `docker history`, or in shell history. +# 3. For non-interactive runs (CI), export UBUNTU_PRO_KEY before invoking the +# script and the prompt is skipped: +# read -rs UBUNTU_PRO_KEY && export UBUNTU_PRO_KEY +# ./earthly.sh +iso +# unset UBUNTU_PRO_KEY +# +# Note: `earthly secret set ...` requires Earthly Cloud (`earthly account login`) +# and is NOT available on a stock CLI install - use the earthly.sh flow above. +# Avoid `earthly --secret UBUNTU_PRO_KEY=` on the command line: the token +# lands in your shell history and /proc//cmdline. +# # UBUNTU_PRO_ATTACH=true # For enabling Secure Boot with Full Disk Encryption diff --git a/Earthfile b/Earthfile index f2a34fd5..6ed99489 100644 --- a/Earthfile +++ b/Earthfile @@ -50,17 +50,18 @@ ARG ARCH ARG DISABLE_SELINUX=true ARG CIS_HARDENING=false # Ubuntu Pro toggle. The token itself is NEVER passed as a build arg. -# Set UBUNTU_PRO_ATTACH=true and supply the token via an Earthly secret. The -# recommended local flow (no Earthly Cloud needed): -# read -rs UBUNTU_PRO_KEY # paste token, press Enter; no echo -# export UBUNTU_PRO_KEY -# earthly --secret UBUNTU_PRO_KEY +base-image --UBUNTU_PRO_ATTACH=true -# unset UBUNTU_PRO_KEY -# Or load from a file: earthly --secret-file UBUNTU_PRO_KEY=/path/to/token ... -# If you use Earthly Cloud, `earthly account login` then -# `earthly secret set /user/UBUNTU_PRO_KEY` works too. -# This keeps the token out of `docker history`, build-arg metadata, and the -# build cache. +# Recommended flow: use the earthly.sh wrapper. Set UBUNTU_PRO_ATTACH=true in +# .arg (or pass --UBUNTU_PRO_ATTACH=true on the CLI), then run e.g. +# ./earthly.sh +iso +# The wrapper prompts for the token without echoing it and forwards it as an +# Earthly --secret, so the value never lands in .arg, in `docker history`, +# in build-arg metadata, in the build cache, or in shell history. +# For non-interactive (CI) runs, export UBUNTU_PRO_KEY before invoking the +# script and the prompt is skipped: +# read -rs UBUNTU_PRO_KEY && export UBUNTU_PRO_KEY +# ./earthly.sh +iso +# Note: `earthly secret set ...` requires Earthly Cloud (earthly account login) +# and is not available on a stock CLI install - use the earthly.sh flow above. ARG UBUNTU_PRO_ATTACH=false # DRBD version for Piraeus pack