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
43 changes: 37 additions & 6 deletions .github/workflows/security-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
set -euo pipefail
test "$(go env GOVERSION)" = go1.27.3
bash scripts/validate.sh
docker build --build-arg VERSION=0.1.2 --build-arg REVISION="$GITHUB_SHA" -f package/Dockerfile -t local/vault-secrets-bridge .
docker build --build-arg VERSION=0.1.3 --build-arg REVISION="$GITHUB_SHA" -f package/Dockerfile -t local/vault-secrets-bridge .
- name: Retain the exact verified runtime
shell: bash
run: |
Expand All @@ -52,14 +52,45 @@ jobs:
scanner=aquasec/trivy:0.74.0@sha256:62b1e65e8869bc4b4c6aa4fa2b21595256c7c2f6018a9d9ad61caf87187c1969
PYTHONDONTWRITEBYTECODE=1 python3 .github/scripts/test_runtime_vulnerability_policy.py
docker pull "$scanner"
cache="$RUNNER_TEMP/ubuntu-backports-trivy-cache"
mkdir -p "$cache"
docker run --rm -v "$cache:/root/.cache/trivy" "$scanner" image --download-db-only
for runtime in local/vault-secrets-bridge; do
name=${runtime##*/}; name=${name%%:*}
docker save "$runtime" --output "$RUNNER_TEMP/$name.tar"
docker run --rm -v "$RUNNER_TEMP/$name.tar:/image.tar:ro" -v "$PWD/dist/security-runtime:/evidence" "$scanner" image --input /image.tar --scanners vuln,secret --list-all-pkgs --format json --output "/evidence/$name-security.json"
python3 .github/scripts/enforce-runtime-vulnerabilities.py --repository PastureStack/vault-secrets-bridge < "dist/security-runtime/$name-security.json"
docker run --rm -v "$RUNNER_TEMP/$name.tar:/image.tar:ro" -v "$PWD/dist/security-runtime:/evidence" "$scanner" image --input /image.tar --format cyclonedx --output "/evidence/$name-sbom.cdx.json"
docker run --rm -v "$cache:/root/.cache/trivy" -v "$RUNNER_TEMP/$name.tar:/image.tar:ro" -v "$PWD/dist/security-runtime:/evidence" "$scanner" image --skip-db-update --input /image.tar --scanners vuln,secret --severity UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL --list-all-pkgs --format json --output "/evidence/$name-security.json"
docker run --rm -v "$cache:/root/.cache/trivy" -v "$RUNNER_TEMP/$name.tar:/image.tar:ro" -v "$PWD/dist/security-runtime:/evidence" "$scanner" image --skip-db-update --input /image.tar --format cyclonedx --output "/evidence/$name-sbom.cdx.json"
mkdir -p dist/security-runtime
consumer_container=$(docker create "$runtime" /bin/true)
if docker cp "$consumer_container:/usr/share/pasturestack/security/ubuntu-backports" dist/security-runtime/ubuntu-backports; then
docker rm "$consumer_container" >/dev/null
else
docker rm "$consumer_container" >/dev/null
exit 1
fi
(cd dist/security-runtime/ubuntu-backports && sha256sum --check SHA256SUMS)
bundle_image='ghcr.io/pasturestack/ubuntu-security-backports:v0.1.0@sha256:2742a3d429e4e14bc587f6dedc51ded4246cf90bbaedcd86c67d0885e32a6f2a'
mkdir -p dist/security-runtime/bundle-tools
bundle_container=$(docker create "$bundle_image" unused)
if docker cp "$bundle_container:/out/verify-consumer-evidence.py" dist/security-runtime/bundle-tools/verify-consumer-evidence.py && \
docker cp "$bundle_container:/out/SHA256SUMS" dist/security-runtime/bundle-tools/SHA256SUMS; then
docker rm "$bundle_container" >/dev/null
else
docker rm "$bundle_container" >/dev/null
exit 1
fi
(cd dist/security-runtime/bundle-tools && \
test "$(grep -Ec '^[0-9a-f]{64} verify-consumer-evidence\.py$' SHA256SUMS)" -eq 1 && \
grep -E '^[0-9a-f]{64} verify-consumer-evidence\.py$' SHA256SUMS | sha256sum --check -)
python3 dist/security-runtime/bundle-tools/verify-consumer-evidence.py \
--evidence-dir dist/security-runtime/ubuntu-backports --sbom "dist/security-runtime/$name-sbom.cdx.json" \
--bundle-checksums dist/security-runtime/bundle-tools/SHA256SUMS \
--expected-bundle-digest 'sha256:2742a3d429e4e14bc587f6dedc51ded4246cf90bbaedcd86c67d0885e32a6f2a' > dist/security-runtime/ubuntu-backports-validation.json
docker run --rm -v "$cache:/root/.cache/trivy" -v "$RUNNER_TEMP/$name.tar:/image.tar:ro" -v "$PWD/dist/security-runtime:/evidence" "$scanner" image --skip-db-update --input /image.tar --scanners vuln,secret --severity UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL --list-all-pkgs --vex /evidence/ubuntu-backports/openvex.json --format json --output "/evidence/$name-security-backports.json"
python3 .github/scripts/enforce-runtime-vulnerabilities.py --repository PastureStack/vault-secrets-bridge < "dist/security-runtime/$name-security-backports.json"
tar -cf dist/security-runtime/ubuntu-backports-evidence.tar -C dist/security-runtime ubuntu-backports ubuntu-backports-validation.json
done
(cd dist/security-runtime && sha256sum -- *.json images.tar.gz source-revision.txt > SHA256SUMS)
(cd dist/security-runtime && sha256sum -- *.json *.tar images.tar.gz source-revision.txt > SHA256SUMS)
- name: Upload verified runtime and checksums
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
Expand All @@ -80,7 +111,7 @@ jobs:
packages: write
env:
GH_TOKEN: ${{ github.token }}
RELEASE_TAG: v0.1.2
RELEASE_TAG: v0.1.3
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
Expand Down
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ PastureStack is an independent community effort to preserve, audit, and moderniz

# Vault Secrets Bridge

Linux runtime **`v0.1.3`** integrates shared Ubuntu 26.04 security backports for already-installed packages while preserving the selected coreutils provider.

The image retains bundle manifests, source inputs and installation receipts under `/usr/share/pasturestack/security/ubuntu-backports/`.

`vault-secrets-bridge` is the PastureStack host-authenticated broker for short-lived HashiCorp Vault leases. It accepts only fresh requests signed by an active host identity, enforces an explicit policy allowlist, asks Vault for a response-wrapped child token, encrypts that wrapping token to the requesting host, and tracks only the revocable accessor under a hashed host-and-volume key.

The current public release and Catalog image are `v0.1.2`. This repository does
not publish a mutable `latest` tag; future releases must use an unused pure
numeric version.
The Linux image is `ghcr.io/pasturestack/vault-secrets-bridge:v0.1.3`.
This repository uses unused pure numeric versions and does not publish a
mutable `latest` tag.

The companion `secrets-flexvolume-plugin` runs as a separate host-local Docker volume driver with `--provider vault`. It verifies and decrypts the returned envelope, writes the wrapping token to a read-only file in an isolated `tmpfs`, and asks this bridge to revoke the lease after the final workload unmounts the volume.

Expand Down Expand Up @@ -118,5 +122,4 @@ finding with an official fix blocks release, regardless of severity. Unknown
findings block unless a separately reviewed, exact not-affected statement is
proved by the actual product dependency graph. LOW/MEDIUM findings without an
official fix require the repository's exact CVE/package/version/PURL review ledger;
new or changed findings fail closed. This policy-only update does not replace any
already published immutable artifact.
new or changed findings fail closed. Each release must pass this policy against its exact image and package versions.
17 changes: 17 additions & 0 deletions package/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# syntax=docker/dockerfile:1.7
FROM ghcr.io/pasturestack/ubuntu-security-backports:v0.1.0@sha256:2742a3d429e4e14bc587f6dedc51ded4246cf90bbaedcd86c67d0885e32a6f2a AS ubuntu_security_backports
FROM golang:1.27.3-bookworm@sha256:972b4110ba0f47539a975c31e52c64765e1ff19f2d74469ae4a595c6676e80a5 AS build

ARG VERSION=dev
Expand Down Expand Up @@ -55,6 +56,22 @@ RUN set -eux; \

COPY --from=build /out/vault-secrets-bridge /usr/local/bin/vault-secrets-bridge

# Install qualified backports only for packages already in this runtime.
# The immutable read-only build mount adds no installer or interpreter to it.
RUN --mount=from=ubuntu_security_backports,source=/out,target=/opt/pasturestack/ubuntu-security-backports,ro \
set -eux; \
evidence=/usr/share/pasturestack/security/ubuntu-backports; \
mkdir -p "${evidence}"; \
/opt/pasturestack/ubuntu-security-backports/install-existing-backports --install-in-docker-build > "${evidence}/install.json"; \
/opt/pasturestack/ubuntu-security-backports/install-existing-backports --verify-installed > "${evidence}/verify.json"; \
for document in manifest.json qualification.json openvex.json source-inputs.lock.json; do \
cp "/opt/pasturestack/ubuntu-security-backports/${document}" "${evidence}/${document}"; \
done; \
printf '%s\n' 'ghcr.io/pasturestack/ubuntu-security-backports:v0.1.0@sha256:2742a3d429e4e14bc587f6dedc51ded4246cf90bbaedcd86c67d0885e32a6f2a' > "${evidence}/bundle-image.txt"; \
(cd "${evidence}" && sha256sum manifest.json qualification.json openvex.json source-inputs.lock.json install.json verify.json bundle-image.txt > SHA256SUMS); \
dpkg-query -W -f='${binary:Package}\t${Version}\n' | LC_ALL=C sort > /usr/share/pasturestack/ubuntu-security-packages.tsv; \
rm -f /var/cache/ldconfig/aux-cache

USER 65532:65532
EXPOSE 8080
ENTRYPOINT ["/usr/local/bin/vault-secrets-bridge"]
Expand Down
Loading