From 0f3af1c8888303bdccc64ac2a1c92d984a7e3ce2 Mon Sep 17 00:00:00 2001 From: Matthew Helmke Date: Fri, 8 May 2026 07:29:43 -0500 Subject: [PATCH 1/3] Update Artifactory packages pull-through guide to use Docker build secrets Replace hardcoded Artifactory tokens in /etc/apk/repositories with Docker build secrets, preventing tokens from being stored in image layers or build history. Resolves internal#5839. Co-Authored-By: Claude Sonnet 4.6 --- .../index.md | 52 +++++++++++++------ 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/content/chainguard/chainguard-images/chainguard-registry/pull-through-guides/artifactory/artifactory-packages-pull-through/index.md b/content/chainguard/chainguard-images/chainguard-registry/pull-through-guides/artifactory/artifactory-packages-pull-through/index.md index df1526760c..b042d17786 100644 --- a/content/chainguard/chainguard-images/chainguard-registry/pull-through-guides/artifactory/artifactory-packages-pull-through/index.md +++ b/content/chainguard/chainguard-images/chainguard-registry/pull-through-guides/artifactory/artifactory-packages-pull-through/index.md @@ -129,31 +129,41 @@ In this example, the Artifactory username is `linky` and the hostname is `exampl This section outlines how to build a container image using a Chainguard image as a base and configure it to pull packages from the private APK repositories through your remote Artifactory repository. -Open a terminal and create a Dockerfile: +Open a terminal and create a Dockerfile. Note the use of single quotes around `'EOF'` to prevent the shell from expanding the `$` variables — these will be processed by Docker during the build: ```shell -cat > Dockerfile < Dockerfile <<'EOF' FROM cgr.dev/chainguard/python:latest-dev USER root -RUN cp /etc/apk/repositories /etc/apk/repositories.disabled -RUN echo 'https://$ARTIFACTORY_USERNAME:$CG_PRIVATE_TOKEN@$ARTIFACTORY_SERVER_NAME.jfrog.io/artifactory/cg-private/' > /etc/apk/repositories -RUN apk add sed +ARG ARTIFACTORY_USERNAME +ARG ARTIFACTORY_SERVER_NAME +RUN --mount=type=secret,id=cg_private_token \ + cp /etc/apk/repositories /etc/apk/repositories.disabled && \ + echo "https://${ARTIFACTORY_USERNAME}:$(cat /run/secrets/cg_private_token)@${ARTIFACTORY_SERVER_NAME}.jfrog.io/artifactory/cg-private/" > /etc/apk/repositories && \ + apk add sed && \ + rm /etc/apk/repositories USER nonroot EOF ``` This Dockerfile uses the `python:latest-dev` image. You don't have to use this particular image, but because we are using the `apk` command to install a package from `cgr-private` in this Dockerfile, you should use a Chainguard container image that has this package manager available. -Note that this Dockerfile renames the default `/etc/apk/repositories` file. This isn't necessary, but doing so allows you to ensure that you're actually downloading packages from the remote Artifactory repositories instead of the default ones. +Note that this Dockerfile combines the repository configuration, package installation, and cleanup into a single `RUN` instruction. This is important because it ensures the Artifactory token is never stored in an image layer. The `--mount=type=secret` option mounts the token only for the duration of this `RUN` instruction and it is not written to the image or its history. The final `rm` removes the `/etc/apk/repositories` file, which contained the token in plain text for the duration of the step. Additionally, be aware that there are limitations to what packages are available from your organization's private APK repository. For instance, your organization may not have access to the `sed` package. Refer to our [private APK repository documentation](/chainguard/chainguard-images/features/private-apk-repos/#about-private-apk-repositories) for more information. -After creating the Dockerfile, build the image. Here, we tag the image `ar-build`: +After creating the Dockerfile, build the image. Here, we tag the image `ar-build` and pass the Artifactory token as a Docker build secret along with the username and server name as build arguments: ```shell -docker build -t ar-build . +docker build \ + --secret id=cg_private_token,env=CG_PRIVATE_TOKEN \ + --build-arg ARTIFACTORY_USERNAME=$ARTIFACTORY_USERNAME \ + --build-arg ARTIFACTORY_SERVER_NAME=$ARTIFACTORY_SERVER_NAME \ + -t ar-build . ``` +The `--secret` flag passes `CG_PRIVATE_TOKEN` as a build secret that is accessible only during the build and is never stored in the image or its history. + This command's output will show that the `sed` package was installed as expected: ```output @@ -214,23 +224,33 @@ Then for the `cg-extras` repo's token: export EXTRAS_TOKEN= ``` -Following that, you can use these environment variables, along with a few created earlier in the guide, to create a Dockerfile as you previously did for the `cg-private` repository: +Following that, you can create a Dockerfile for the public repositories. As before, use single quotes around `'EOF'` to prevent shell expansion: ```shell -cat > Dockerfile.repos < Dockerfile.repos <<'EOF' FROM cgr.dev/chainguard/python:latest-dev USER root -RUN cp /etc/apk/repositories /etc/apk/repositories.disabled -RUN echo 'https://$ARTIFACTORY_USERNAME:$CG_TOKEN@$ARTIFACTORY_SERVER_NAME.jfrog.io/artifactory/cg-chainguard/' > /etc/apk/repositories -RUN echo 'https://$ARTIFACTORY_USERNAME:$EXTRAS_TOKEN@$ARTIFACTORY_SERVER_NAME.jfrog.io/artifactory/cg-extras/' >> /etc/apk/repositories -RUN apk add c-ares +ARG ARTIFACTORY_USERNAME +ARG ARTIFACTORY_SERVER_NAME +RUN --mount=type=secret,id=cg_token \ + --mount=type=secret,id=extras_token \ + cp /etc/apk/repositories /etc/apk/repositories.disabled && \ + echo "https://${ARTIFACTORY_USERNAME}:$(cat /run/secrets/cg_token)@${ARTIFACTORY_SERVER_NAME}.jfrog.io/artifactory/cg-chainguard/" > /etc/apk/repositories && \ + echo "https://${ARTIFACTORY_USERNAME}:$(cat /run/secrets/extras_token)@${ARTIFACTORY_SERVER_NAME}.jfrog.io/artifactory/cg-extras/" >> /etc/apk/repositories && \ + apk add c-ares && \ + rm /etc/apk/repositories EOF ``` -Following that, build the image: +Following that, build the image, passing each Artifactory token as a Docker build secret: ```shell -docker build -t ar-repos -f Dockerfile.repos . +docker build \ + --secret id=cg_token,env=CG_TOKEN \ + --secret id=extras_token,env=EXTRAS_TOKEN \ + --build-arg ARTIFACTORY_USERNAME=$ARTIFACTORY_USERNAME \ + --build-arg ARTIFACTORY_SERVER_NAME=$ARTIFACTORY_SERVER_NAME \ + -t ar-repos -f Dockerfile.repos . ``` As this command runs, it installs the `c-ares` package into the image. From 0b89b6fa7f01c22176c48461b0a2052bf88aa60f Mon Sep 17 00:00:00 2001 From: Matthew Helmke Date: Fri, 8 May 2026 08:08:40 -0500 Subject: [PATCH 2/3] Clarify that GPOS SRG profile applies to both FIPS and non-FIPS images Addresses customer confusion around whether OpenSCAP/STIG validation is limited to FIPS images. Adds explicit callouts in the intro, Getting Started section, and Learn More section. Closes https://github.com/chainguard-dev/internal/issues/5820 Co-Authored-By: Claude Sonnet 4.6 --- .../chainguard-images/features/image-stigs.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/content/chainguard/chainguard-images/features/image-stigs.md b/content/chainguard/chainguard-images/features/image-stigs.md index ed05ecaedf..b79ca0debf 100644 --- a/content/chainguard/chainguard-images/features/image-stigs.md +++ b/content/chainguard/chainguard-images/features/image-stigs.md @@ -7,7 +7,7 @@ aliases: type: "article" description: "A conceptual overview of Security Technical Implementation Guides, which are available for Chainguard Containers." date: 2024-06-13T15:56:52-07:00 -lastmod: 2025-04-08T15:56:52-07:00 +lastmod: 2026-05-08T15:56:52-07:00 draft: false tags: ["Chainguard Containers"] images: [] @@ -20,7 +20,9 @@ toc: true The practice of using Security Technical Implementation Guides, or "STIGs," to secure various technologies originated with the United States Department of Defense (DoD). If an organization uses a certain kind of software, say MySQL 8.0, they must ensure that their implementation of it meets the requirements of the [associated Security Requirements Guides (SRG)](https://www.cyber.mil/stigs/) in order to qualify as a vendor for the DoD. More recently, other compliance frameworks have begun acknowledging the value of STIGS, with some going so far as to require the use of STIGs in their guidelines. -[Chainguard announced](https://www.chainguard.dev/unchained/stig-hardening-container-images) the release of a STIG for the [General Purpose Operating System (GPOS) SRG](https://stigviewer.com/stigs/general_purpose_operating_system_security_requirements_guide) — an SRG that specifies security requirements for general purpose operating systems running in a network. The goal for this new STIG is that it will help customers confidently and securely integrate Chainguard Containers into their workflows. This conceptual article aims to give a brief overview of what STIGs are and how they can be valuable in the context of container images. It also includes instructions on how to get started with Chainguard's STIG for the GPOS SRG. +[Chainguard announced](https://www.chainguard.dev/unchained/stig-hardening-container-images) the release of a STIG for the [General Purpose Operating System (GPOS) SRG](https://stigviewer.com/stigs/general_purpose_operating_system_security_requirements_guide) — an SRG that specifies security requirements for general purpose operating systems running in a network. The goal for this new STIG is that it will help customers confidently and securely integrate Chainguard Containers into their workflows. This conceptual article aims to give a brief overview of what STIGs are and how they can be valuable in the context of container images. It also includes instructions on how to get started with Chainguard's STIG for the GPOS SRG. + +The Chainguard GPOS SRG profile applies to all Chainguard Containers — including both FIPS and non-FIPS images. The [Getting Started](#getting-started) section demonstrates how to use OpenSCAP to validate hardening checks against any Chainguard Container. ## Getting Started @@ -39,7 +41,7 @@ curl -fsSLO https://raw.githubusercontent.com/chainguard-dev/stigs/main/gpos/xml The `-O` option in this example will redirect the file's contents into a local file also named `ssg-chainguard-gpos-ds.xml` in your working directory. You can then view the checklist locally. -We'll refer to Chainguard's `openscap` container image as the `scan` image, and the `target` image we'll be scanning will be: `cgr.dev/chainguard/wolfi-base:latest`. +We'll refer to Chainguard's `openscap` container image as the `scan` image, and the `target` image we'll be scanning will be: `cgr.dev/chainguard/wolfi-base:latest`. This is a non-FIPS image and is used as an example; you can substitute any Chainguard Container image as the target. The scan may be performed using one of two methods - we may either scan an image in a registry, or a running container. @@ -190,4 +192,4 @@ These containers can be validated against the General Purpose Operating System S ## Learn more -Chainguard's STIG hardened FIPS Containers are now generally available. You can check out our [STIG repo](https://github.com/chainguard-dev/stigs?utm_source=cg-academy&utm_medium=referral&utm_campaign=dev-enablement) or [contact us](https://get.chainguard.dev/simplify-fedramp-compliance-5?utm_source=cg-academy&utm_medium=referral&utm_campaign=dev-enablement) for more information. If you'd like to learn more about how Chainguard Containers can help you meet FedRAMP compliance, we encourage you to refer to our overview of [Chainguard's FIPS-ready container images](/chainguard/chainguard-images/working-with-images/fips-images/). +You can use OpenSCAP to validate hardening checks against any Chainguard Container, including both FIPS and non-FIPS images, using the process described in [Getting Started](#getting-started). Chainguard's STIG hardened FIPS Containers are also generally available. You can check out our [STIG repo](https://github.com/chainguard-dev/stigs?utm_source=cg-academy&utm_medium=referral&utm_campaign=dev-enablement) or [contact us](https://get.chainguard.dev/simplify-fedramp-compliance-5?utm_source=cg-academy&utm_medium=referral&utm_campaign=dev-enablement) for more information. If you'd like to learn more about how Chainguard Containers can help you meet FedRAMP compliance, we encourage you to refer to our overview of [Chainguard's FIPS-ready container images](/chainguard/chainguard-images/working-with-images/fips-images/). From e218bfe709cda728032dca50ac906abb134d9439 Mon Sep 17 00:00:00 2001 From: Matthew Helmke Date: Fri, 8 May 2026 08:13:57 -0500 Subject: [PATCH 3/3] Revert accidental inclusion of Artifactory pull-through change This commit restores the Artifactory packages pull-through guide to its state on main. The Docker build secrets update was merged separately in the previous PR and should not be part of this branch. Co-Authored-By: Claude Sonnet 4.6 --- .../index.md | 52 ++++++------------- 1 file changed, 16 insertions(+), 36 deletions(-) diff --git a/content/chainguard/chainguard-images/chainguard-registry/pull-through-guides/artifactory/artifactory-packages-pull-through/index.md b/content/chainguard/chainguard-images/chainguard-registry/pull-through-guides/artifactory/artifactory-packages-pull-through/index.md index b042d17786..df1526760c 100644 --- a/content/chainguard/chainguard-images/chainguard-registry/pull-through-guides/artifactory/artifactory-packages-pull-through/index.md +++ b/content/chainguard/chainguard-images/chainguard-registry/pull-through-guides/artifactory/artifactory-packages-pull-through/index.md @@ -129,41 +129,31 @@ In this example, the Artifactory username is `linky` and the hostname is `exampl This section outlines how to build a container image using a Chainguard image as a base and configure it to pull packages from the private APK repositories through your remote Artifactory repository. -Open a terminal and create a Dockerfile. Note the use of single quotes around `'EOF'` to prevent the shell from expanding the `$` variables — these will be processed by Docker during the build: +Open a terminal and create a Dockerfile: ```shell -cat > Dockerfile <<'EOF' +cat > Dockerfile < /etc/apk/repositories && \ - apk add sed && \ - rm /etc/apk/repositories +RUN cp /etc/apk/repositories /etc/apk/repositories.disabled +RUN echo 'https://$ARTIFACTORY_USERNAME:$CG_PRIVATE_TOKEN@$ARTIFACTORY_SERVER_NAME.jfrog.io/artifactory/cg-private/' > /etc/apk/repositories +RUN apk add sed USER nonroot EOF ``` This Dockerfile uses the `python:latest-dev` image. You don't have to use this particular image, but because we are using the `apk` command to install a package from `cgr-private` in this Dockerfile, you should use a Chainguard container image that has this package manager available. -Note that this Dockerfile combines the repository configuration, package installation, and cleanup into a single `RUN` instruction. This is important because it ensures the Artifactory token is never stored in an image layer. The `--mount=type=secret` option mounts the token only for the duration of this `RUN` instruction and it is not written to the image or its history. The final `rm` removes the `/etc/apk/repositories` file, which contained the token in plain text for the duration of the step. +Note that this Dockerfile renames the default `/etc/apk/repositories` file. This isn't necessary, but doing so allows you to ensure that you're actually downloading packages from the remote Artifactory repositories instead of the default ones. Additionally, be aware that there are limitations to what packages are available from your organization's private APK repository. For instance, your organization may not have access to the `sed` package. Refer to our [private APK repository documentation](/chainguard/chainguard-images/features/private-apk-repos/#about-private-apk-repositories) for more information. -After creating the Dockerfile, build the image. Here, we tag the image `ar-build` and pass the Artifactory token as a Docker build secret along with the username and server name as build arguments: +After creating the Dockerfile, build the image. Here, we tag the image `ar-build`: ```shell -docker build \ - --secret id=cg_private_token,env=CG_PRIVATE_TOKEN \ - --build-arg ARTIFACTORY_USERNAME=$ARTIFACTORY_USERNAME \ - --build-arg ARTIFACTORY_SERVER_NAME=$ARTIFACTORY_SERVER_NAME \ - -t ar-build . +docker build -t ar-build . ``` -The `--secret` flag passes `CG_PRIVATE_TOKEN` as a build secret that is accessible only during the build and is never stored in the image or its history. - This command's output will show that the `sed` package was installed as expected: ```output @@ -224,33 +214,23 @@ Then for the `cg-extras` repo's token: export EXTRAS_TOKEN= ``` -Following that, you can create a Dockerfile for the public repositories. As before, use single quotes around `'EOF'` to prevent shell expansion: +Following that, you can use these environment variables, along with a few created earlier in the guide, to create a Dockerfile as you previously did for the `cg-private` repository: ```shell -cat > Dockerfile.repos <<'EOF' +cat > Dockerfile.repos < /etc/apk/repositories && \ - echo "https://${ARTIFACTORY_USERNAME}:$(cat /run/secrets/extras_token)@${ARTIFACTORY_SERVER_NAME}.jfrog.io/artifactory/cg-extras/" >> /etc/apk/repositories && \ - apk add c-ares && \ - rm /etc/apk/repositories +RUN cp /etc/apk/repositories /etc/apk/repositories.disabled +RUN echo 'https://$ARTIFACTORY_USERNAME:$CG_TOKEN@$ARTIFACTORY_SERVER_NAME.jfrog.io/artifactory/cg-chainguard/' > /etc/apk/repositories +RUN echo 'https://$ARTIFACTORY_USERNAME:$EXTRAS_TOKEN@$ARTIFACTORY_SERVER_NAME.jfrog.io/artifactory/cg-extras/' >> /etc/apk/repositories +RUN apk add c-ares EOF ``` -Following that, build the image, passing each Artifactory token as a Docker build secret: +Following that, build the image: ```shell -docker build \ - --secret id=cg_token,env=CG_TOKEN \ - --secret id=extras_token,env=EXTRAS_TOKEN \ - --build-arg ARTIFACTORY_USERNAME=$ARTIFACTORY_USERNAME \ - --build-arg ARTIFACTORY_SERVER_NAME=$ARTIFACTORY_SERVER_NAME \ - -t ar-repos -f Dockerfile.repos . +docker build -t ar-repos -f Dockerfile.repos . ``` As this command runs, it installs the `c-ares` package into the image.