Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/scripts/check-image-policies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ run_scan() {
for tool in HELM KUBECTL; do
docker run --rm --entrypoint /usr/bin/cat "$image" "/licenses/$tool-PACKAGES.txt" > "dist/$tool-PACKAGES.txt"
test -s "dist/$tool-PACKAGES.txt"
! grep -Eq '^golang.org/x/crypto/openpgp(/|$)' "dist/$tool-PACKAGES.txt"
if grep -Eq '^golang.org/x/crypto/openpgp(/|$)' "dist/$tool-PACKAGES.txt"; then echo 'Forbidden OpenPGP dependency' >&2; exit 1; fi
done
for tool in DOCKER BUILDX TRIVY; do
docker run --rm --entrypoint /usr/bin/cat "$DAPPER_IMAGE" "/licenses/$tool-PACKAGES.txt" > "dist/$tool-PACKAGES.txt"
test -s "dist/$tool-PACKAGES.txt"
! grep -Eq '^golang.org/x/crypto/openpgp(/|$)' "dist/$tool-PACKAGES.txt"
if grep -Eq '^golang.org/x/crypto/openpgp(/|$)' "dist/$tool-PACKAGES.txt"; then echo 'Forbidden OpenPGP dependency' >&2; exit 1; fi
done

for binary in helm kubectl; do
for binary in helm kubectl kubectl-service; do
jq -e --arg binary "$binary" 'any(.Results[]?;
.Type == "gobinary" and (.Target | split("/") | last) == $binary
and (.Packages | length > 0))' dist/kubectl-service.security-raw.json >/dev/null
Expand Down
46 changes: 46 additions & 0 deletions .github/scripts/test_negative_package_guards.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""Exercise the actual shell guards, including commands after a rejected match."""
import pathlib
import re
import subprocess
import tempfile
import unittest

ROOT = pathlib.Path(__file__).resolve().parents[2]


class NegativePackageGuards(unittest.TestCase):
def test_all_package_guards_fail_before_the_next_command(self):
count = 0
for relative in ('Dockerfile.dapper', 'package/Dockerfile',
'.github/scripts/check-image-policies.sh'):
lines = (ROOT / relative).read_text().splitlines()
self.assertFalse(any(re.search(r'^\s*! grep', line) for line in lines))
for line in lines:
if 'if grep' not in line:
continue
count += 1
command = line.strip().removesuffix('\\').strip().rstrip(';')
command = re.sub(r'(/(?:licenses|out|tmp)/[^; ]+|"dist/\$tool-PACKAGES.txt")',
'"$fixture"', command)
forbidden = ('dep\tgithub.com/docker/docker\tv1\n'
if 'build metadata' in command else
'github.com/docker/docker/client\n'
if 'upstream Docker dependency' in command else
'golang.org/x/crypto/openpgp/packet\n')
with tempfile.TemporaryDirectory() as temp:
fixture = pathlib.Path(temp) / 'packages.txt'
for contents, expected in ((forbidden, 1), ('fmt\n', 0)):
fixture.write_text(contents)
result = subprocess.run(['bash', '-c',
'set -euo pipefail; fixture="$1"; ' + command +
'; echo NEXT_COMMAND', 'guard-test', str(fixture)],
capture_output=True, text=True)
self.assertEqual(result.returncode, expected, result.stderr)
self.assertEqual('NEXT_COMMAND' in result.stdout, expected == 0)
if expected:
self.assertIn('Forbidden', result.stderr)
self.assertEqual(count, 9)


if __name__ == '__main__':
unittest.main()
2 changes: 2 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ jobs:
test "$(git rev-list -n 1 "$RELEASE_TAG")" = "$(git rev-parse HEAD)"
test -z "$(git status --porcelain)"
python3 .github/scripts/test_runtime_vulnerability_policy.py
python3 .github/scripts/test_negative_package_guards.py

- name: Build verification environment and vulnerability database
shell: bash
Expand Down Expand Up @@ -116,6 +117,7 @@ jobs:
dist/dapper.raw.json dist/dapper.effective.json dist/dapper.cdx.json \
dist/dapper-policy.json dist/dapper.accepted-build-header-findings.json \
dist/runtime-openvex.json dist/*-PACKAGES.txt \
dist/dapper-ubuntu-apt-packages.tsv dist/ubuntu-apt.lock dist/ubuntu-security-packages.lock \
dist/SHA256SUMS

- name: Clean run-owned resources
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/security-release-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ jobs:
docker version
docker buildx version
python3 .github/scripts/test_runtime_vulnerability_policy.py
python3 .github/scripts/test_negative_package_guards.py

- name: Build the checksum-locked verification environment
shell: bash
Expand Down
10 changes: 5 additions & 5 deletions Dockerfile.dapper
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ RUN set -eux; \
GOFLAGS=-mod=mod GOWORK=off GOPROXY=https://proxy.golang.org GOSUMDB=sum.golang.org GOMODCACHE=/tmp/docker-go-mod go list -deps ./cmd/docker > /tmp/docker-resolved-packages.txt; \
GOFLAGS=-mod=mod GOWORK=off GOPROXY=off GOSUMDB=sum.golang.org GOMODCACHE=/tmp/docker-go-mod go mod verify; \
GOFLAGS=-mod=mod GOWORK=off GOPROXY=off GOSUMDB=sum.golang.org GOMODCACHE=/tmp/docker-go-mod go list -deps ./cmd/docker > /licenses/DOCKER-PACKAGES.txt; \
! grep -Eq '^golang.org/x/crypto/openpgp(/|$)' /licenses/DOCKER-PACKAGES.txt; \
if grep -Eq '^golang.org/x/crypto/openpgp(/|$)' /licenses/DOCKER-PACKAGES.txt; then echo 'Forbidden OpenPGP dependency' >&2; exit 1; fi; \
docker_build_time="$(date -u --date="@${DOCKER_SOURCE_DATE_EPOCH}" +'%Y-%m-%dT%H:%M:%SZ')"; \
SOURCE_DATE_EPOCH="${DOCKER_SOURCE_DATE_EPOCH}" CGO_ENABLED=0 GOFLAGS=-mod=mod GOWORK=off GOPROXY=off GOSUMDB=sum.golang.org GOMODCACHE=/tmp/docker-go-mod GOOS=linux GOARCH="${DAPPER_HOST_ARCH}" \
go build -trimpath -buildvcs=false -tags 'grpcnotrace osusergo netgo' \
Expand Down Expand Up @@ -180,8 +180,8 @@ RUN set -eux; \
test "$(GOFLAGS=-mod=mod GOWORK=off GOPROXY=off GOSUMDB=sum.golang.org GOMODCACHE=/tmp/buildx-go-mod go list -m -f '{{.Version}}' golang.org/x/mod)" = "${BUILDX_X_MOD_VERSION}"; \
test "$(GOFLAGS=-mod=mod GOWORK=off GOPROXY=off GOSUMDB=sum.golang.org GOMODCACHE=/tmp/buildx-go-mod go list -m -f '{{.Version}}' google.golang.org/grpc)" = "${BUILDX_GRPC_VERSION}"; \
GOFLAGS=-mod=mod GOWORK=off GOPROXY=off GOSUMDB=sum.golang.org GOMODCACHE=/tmp/buildx-go-mod go list -deps ./cmd/buildx > /tmp/buildx-deps.txt; \
! grep '^github.com/docker/docker/' /tmp/buildx-deps.txt; \
! grep -Eq '^golang.org/x/crypto/openpgp(/|$)' /tmp/buildx-deps.txt; \
if grep '^github.com/docker/docker/' /tmp/buildx-deps.txt; then echo 'Forbidden upstream Docker dependency' >&2; exit 1; fi; \
if grep -Eq '^golang.org/x/crypto/openpgp(/|$)' /tmp/buildx-deps.txt; then echo 'Forbidden OpenPGP dependency' >&2; exit 1; fi; \
cp /tmp/buildx-deps.txt /licenses/BUILDX-PACKAGES.txt; \
SOURCE_DATE_EPOCH="${BUILDX_SOURCE_DATE_EPOCH}" CGO_ENABLED=0 GOFLAGS=-mod=mod GOWORK=off GOPROXY=off GOSUMDB=sum.golang.org GOMODCACHE=/tmp/buildx-go-mod GOOS=linux GOARCH="${DAPPER_HOST_ARCH}" \
go build -trimpath -buildvcs=false \
Expand All @@ -191,7 +191,7 @@ RUN set -eux; \
docker buildx version | grep -F "github.com/docker/buildx v${BUILDX_VERSION} ${BUILDX_GIT_COMMIT}"; \
go version -m /usr/libexec/docker/cli-plugins/docker-buildx > /licenses/BUILDX-GO-VERSION.txt; \
test "$(awk 'NR == 1 { print $NF }' /licenses/BUILDX-GO-VERSION.txt)" = "go${GO_VERSION}"; \
! grep -F $'dep\tgithub.com/docker/docker\t' /licenses/BUILDX-GO-VERSION.txt; \
if grep -F $'dep\tgithub.com/docker/docker\t' /licenses/BUILDX-GO-VERSION.txt; then echo 'Forbidden upstream Docker build metadata' >&2; exit 1; fi; \
grep -F $'dep\tgithub.com/moby/go-archive\t'"${BUILDX_GO_ARCHIVE_VERSION}"$'\t' /licenses/BUILDX-GO-VERSION.txt; \
grep -F $'dep\tgolang.org/x/mod\t'"${BUILDX_X_MOD_VERSION}"$'\t' /licenses/BUILDX-GO-VERSION.txt; \
grep -F $'dep\tgoogle.golang.org/grpc\t'"${BUILDX_GRPC_VERSION}"$'\t' /licenses/BUILDX-GO-VERSION.txt; \
Expand Down Expand Up @@ -232,7 +232,7 @@ RUN set -eux; \
GOFLAGS=-mod=mod GOWORK=off GOPROXY=https://proxy.golang.org GOSUMDB=sum.golang.org GOMODCACHE=/tmp/trivy-go-mod go list -deps ./cmd/trivy > /tmp/trivy-resolved-packages.txt; \
GOFLAGS=-mod=mod GOWORK=off GOPROXY=off GOSUMDB=sum.golang.org GOMODCACHE=/tmp/trivy-go-mod go mod verify; \
GOFLAGS=-mod=mod GOWORK=off GOPROXY=off GOSUMDB=sum.golang.org GOMODCACHE=/tmp/trivy-go-mod go list -deps ./cmd/trivy > /licenses/TRIVY-PACKAGES.txt; \
! grep -Eq '^golang.org/x/crypto/openpgp(/|$)' /licenses/TRIVY-PACKAGES.txt; \
if grep -Eq '^golang.org/x/crypto/openpgp(/|$)' /licenses/TRIVY-PACKAGES.txt; then echo 'Forbidden OpenPGP dependency' >&2; exit 1; fi; \
SOURCE_DATE_EPOCH="${TRIVY_SOURCE_DATE_EPOCH}" CGO_ENABLED=0 GOEXPERIMENT=jsonv2 GOFLAGS=-mod=mod GOWORK=off GOPROXY=off GOSUMDB=sum.golang.org GOMODCACHE=/tmp/trivy-go-mod GOOS=linux GOARCH="${DAPPER_HOST_ARCH}" \
go build -trimpath -buildvcs=false \
-ldflags "-s -w -buildid= -X=github.com/aquasecurity/trivy/pkg/version/app.ver=${TRIVY_VERSION}" \
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ non-root read-only smoke run, a client-side Helm render, full-severity Trivy
reports, and a CycloneDX SBOM. Release gates reject all available fixes,
unreviewed findings, and High/Critical findings. Only exact Low/Medium entries
with official no-fix evidence may remain. The sole OpenVEX statement covers
the absent OpenPGP package; source dependency graphs enforce that boundary.
the absent OpenPGP package; source dependency graphs enforce that boundary
with fail-closed checks. Raw scans must include package inventories for the
service executable, Helm, kubectl, and each bundled Go build tool.

See [COMPATIBILITY.md](COMPATIBILITY.md), [SECURITY.md](SECURITY.md), and
[ORIGIN.md](ORIGIN.md).
Expand Down
4 changes: 2 additions & 2 deletions package/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ RUN set -eux; \
go get "golang.org/x/net@v${HELM_X_NET_VERSION}" "golang.org/x/crypto@v${HELM_X_CRYPTO_VERSION}"; \
go mod verify; \
go list -deps ./cmd/helm > /out/HELM-PACKAGES.txt; \
! grep -Eq '^golang.org/x/crypto/openpgp(/|$)' /out/HELM-PACKAGES.txt; \
if grep -Eq '^golang.org/x/crypto/openpgp(/|$)' /out/HELM-PACKAGES.txt; then echo 'Forbidden OpenPGP dependency' >&2; exit 1; fi; \
test "$(go list -m -f '{{.Version}}' oras.land/oras-go/v2)" = "v${HELM_ORAS_GO_VERSION}"; \
test "$(go list -m -f '{{.Version}}' golang.org/x/crypto)" = "v${HELM_X_CRYPTO_VERSION}"; \
test "$(go list -m -f '{{.Version}}' golang.org/x/net)" = "v${HELM_X_NET_VERSION}"; \
Expand Down Expand Up @@ -82,7 +82,7 @@ RUN set -eux; \
GOWORK=off go mod vendor; \
test "$(GOWORK=off go list -m -f '{{.Version}}' golang.org/x/net)" = "${KUBERNETES_X_NET_VERSION}"; \
GOWORK=off go list -deps ./cmd/kubectl > /out/KUBECTL-PACKAGES.txt; \
! grep -Eq '^golang.org/x/crypto/openpgp(/|$)' /out/KUBECTL-PACKAGES.txt; \
if grep -Eq '^golang.org/x/crypto/openpgp(/|$)' /out/KUBECTL-PACKAGES.txt; then echo 'Forbidden OpenPGP dependency' >&2; exit 1; fi; \
GOWORK=off GO_VERSION=1.27.3 FORCE_HOST_GO=1 KUBE_BUILD_PLATFORMS=linux/amd64 \
KUBE_GIT_VERSION="${KUBERNETES_VERSION}" KUBE_GIT_COMMIT="${KUBERNETES_GIT_COMMIT}" \
KUBE_GIT_TREE_STATE=clean KUBE_GIT_MAJOR=1 KUBE_GIT_MINOR=36 \
Expand Down
Loading