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
10 changes: 10 additions & 0 deletions .github/dapper-headers.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"repository": "PastureStack/kubernetes-agent",
"package": "linux-libc-dev",
"version": "7.0.0-38.38",
"purl": "pkg:deb/ubuntu/linux-libc-dev@7.0.0-38.38?arch=amd64&distro=ubuntu-26.04",
"justification": "vulnerable_code_not_present",
"reason": "No linux-libc-dev package or findings exist in the current Go-only Dapper image. No header CVE is permitted by this empty set.",
"checkedAt": "2026-10-23",
"ids": []
}
709 changes: 709 additions & 0 deletions .github/dapper-unfixed.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions .github/runtime-unfixed.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"repository": "PastureStack/kubernetes-agent",
"unfixed": []
}
28 changes: 28 additions & 0 deletions .github/scripts/check-builder-header-boundary.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env bash
set -euo pipefail
test "$#" -eq 1
if ! docker run --rm --entrypoint sh "$1" -ec 'dpkg-query -W -f="\${Status}" linux-libc-dev 2>/dev/null | grep -Fxq "install ok installed"'; then
printf '%s\n' '{"package":null}'
exit 0
fi
docker run --rm --entrypoint sh "$1" -ec '
test "$(dpkg-query -W -f="\${Version}" linux-libc-dev)" = 7.0.0-38.38
if dpkg-query -W -f="\${db:Status-Abbrev} \${binary:Package}\\n" |
awk "\$1 == \"ii\" {print \$2}" | grep -Eq "^linux-(image|modules)([-:]|$)"; then
echo "Unexpected kernel runtime package" >&2; exit 1
fi
for directory in /boot /lib/modules /usr/lib/modules; do
if test -d "$directory" && test -n "$(find "$directory" -type f -print -quit)"; then
echo "Unexpected kernel runtime file" >&2; exit 1
fi
done
dpkg-query -L linux-libc-dev | while IFS= read -r path; do
if test -f "$path"; then
case "$path" in
/usr/include/*|/usr/share/doc/linux-libc-dev/*|/usr/share/lintian/overrides/linux-libc-dev) ;;
*) echo "Unexpected linux-libc-dev payload: $path" >&2; exit 1 ;;
esac
fi
done
'
printf '%s\n' '{"package":"linux-libc-dev","version":"7.0.0-38.38","kernel_images":false,"kernel_modules":false}'
159 changes: 159 additions & 0 deletions .github/scripts/enforce-runtime-vulnerabilities.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
"""Enforce release findings; only exact, reviewed unfixed low/medium entries may pass."""
import argparse
import json
import sys
from pathlib import Path


def violations(report, ledger, repository):
if (not isinstance(report, dict) or report.get("SchemaVersion") != 2
or not isinstance(report.get("Results"), list) or not report["Results"]):
raise ValueError("missing or malformed Trivy scan results")
for result in report["Results"]:
if not isinstance(result, dict) or not isinstance(result.get("Target"), str):
raise ValueError("malformed Trivy result")
for key in ("Vulnerabilities", "Secrets"):
if key in result and result[key] is not None and not isinstance(result[key], list):
raise ValueError("malformed Trivy findings")
if ledger.get("repository") != repository:
raise ValueError("allowlist repository mismatch")
reviewed = {}
for entry in ledger.get("unfixed", []):
key = (entry["id"], entry["package"], entry["version"], entry.get("purl", ""))
if key in reviewed:
raise ValueError("duplicate reviewed finding")
if (entry.get("severity") not in ("LOW", "MEDIUM")
or entry.get("status") != "no_official_fix"
or not entry.get("officialEvidence", "").startswith("https://")
or not entry.get("reason") or not entry.get("checkedAt")):
raise ValueError("incomplete official no-fix evidence")
reviewed[key] = entry
errors = []
for result in report.get("Results") or []:
if result.get("Secrets"):
errors.append("secret findings remain")
for finding in result.get("Vulnerabilities") or []:
severity = finding.get("Severity", "UNKNOWN")
key = (finding.get("VulnerabilityID"), finding.get("PkgName"),
finding.get("InstalledVersion"),
(finding.get("PkgIdentifier") or {}).get("PURL", ""))
entry = reviewed.get(key)
fixed = str(finding.get("FixedVersion") or "").strip()
if (severity not in ("LOW", "MEDIUM") or fixed
or entry is None or entry["severity"] != severity):
errors.append("%s %s@%s severity=%s fixed=%s" % (
key[0], key[1], key[2], severity, fixed or "none"))
return errors



def builder_violations(report, ledger, repository, header_boundary, header_ledger,
package_graphs=None, docker_proof=None):
# The complete raw scan is required; never infer safety from missing analysis.
if not isinstance(report, dict) or report.get("SchemaVersion") != 2:
raise ValueError("malformed complete builder report")
results = report.get("Results")
if not isinstance(results, list) or not results:
raise ValueError("missing builder analysis")
expected = ["usr/local/go/bin/go"]
if repository == "PastureStack/ecr-credential-sync":
expected += ["usr/bin/docker", "usr/libexec/docker/cli-plugins/docker-buildx"]
if repository == "PastureStack/kubernetes-authentication-bridge":
expected += ["usr/bin/docker", "usr/local/libexec/docker/cli-plugins/docker-buildx"]
binaries = {r.get("Target"): r for r in results if r.get("Type") == "gobinary"}
for target in expected:
if not binaries.get(target, {}).get("Packages"):
raise ValueError("missing nonempty binary analysis: " + target)
if any(not result.get("Packages") for result in binaries.values()):
raise ValueError("incomplete Go binary package analysis")
has_headers = any(f.get("PkgName") == "linux-libc-dev" for r in results for f in (r.get("Vulnerabilities") or []))
if has_headers and header_boundary != {"package": "linux-libc-dev", "version": "7.0.0-38.38",
"kernel_images": False, "kernel_modules": False}:
raise ValueError("missing exact installed-header boundary proof")
if header_ledger.get("repository") != repository:
raise ValueError("header review repository mismatch")
if (header_ledger.get("package") != "linux-libc-dev"
or header_ledger.get("version") != "7.0.0-38.38"
or header_ledger.get("purl") != "pkg:deb/ubuntu/linux-libc-dev@7.0.0-38.38?arch=amd64&distro=ubuntu-26.04"):
raise ValueError("changed header review boundary")
header_keys = {(identifier, header_ledger["package"], header_ledger["version"], header_ledger["purl"])
for identifier in header_ledger.get("ids", [])}
expected_purl = "pkg:deb/ubuntu/linux-libc-dev@7.0.0-38.38?arch=amd64&distro=ubuntu-26.04"
openpgp_absent = False
if package_graphs:
if repository not in ("PastureStack/kubernetes-authentication-bridge", "PastureStack/ecr-credential-sync"):
raise ValueError("unexpected OpenPGP proof consumer")
expected_roots = {"buildx": "github.com/docker/buildx/cmd/buildx"}
if repository == "PastureStack/ecr-credential-sync":
expected_roots["docker"] = "github.com/docker/cli/cmd/docker"
if set(package_graphs) != set(expected_roots):
raise ValueError("unexpected source package graph set")
for name, root in expected_roots.items():
packages = set(package_graphs[name].splitlines())
if root not in packages or any(
p == "golang.org/x/crypto/openpgp" or
p.startswith("golang.org/x/crypto/openpgp/") for p in packages):
raise ValueError("OpenPGP package boundary not proved")
openpgp_absent = True
retained = []
for result in results:
copied = dict(result)
copied["Vulnerabilities"] = []
for finding in result.get("Vulnerabilities") or []:
key = (finding.get("VulnerabilityID"), finding.get("PkgName"),
finding.get("InstalledVersion"),
(finding.get("PkgIdentifier") or {}).get("PURL", ""))
is_header = (key in header_keys and key[1] == "linux-libc-dev"
and key[2] == "7.0.0-38.38" and key[3] == expected_purl)
unfixed = not str(finding.get("FixedVersion") or "").strip()
if is_header and unfixed:
continue
if (unfixed and openpgp_absent and key == (
"GO-2026-5932", "golang.org/x/crypto", "v0.57.0",
"pkg:golang/golang.org/x/crypto@v0.57.0")):
continue
if (unfixed and repository == "PastureStack/ecr-credential-sync"
and key == ("CVE-2026-85747", "github.com/docker/distribution",
"v2.8.3+incompatible",
"pkg:golang/github.com/docker/distribution@v2.8.3%2Bincompatible")
and docker_proof and len(docker_proof.get("cases", [])) == 7
and all(c.get("passed") is True for c in docker_proof["cases"])
and {c.get("case") for c in docker_proof["cases"]} == {
"valid_schema2", "forged_schema2", "valid_oci", "forged_oci",
"valid_list", "forged_list_parent", "forged_list_child"}
and docker_proof.get("sourceCommit") == "a7dcaa6fdb6ed04aacbfdc76357fdae01605609e"
and len(docker_proof.get("binarySha256", "")) == 64):
continue
copied["Vulnerabilities"].append(finding)
retained.append(copied)
return violations(dict(report, Results=retained), ledger, repository)

if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--repository", required=True)
parser.add_argument("--scope", choices=("runtime", "builder"), default="runtime")
args = parser.parse_args()
repo_root = Path(__file__).resolve().parents[2]
report = json.load(sys.stdin)
ledger_name = "runtime-unfixed.json" if args.scope == "runtime" else "dapper-unfixed.json"
ledger = json.loads((repo_root / ".github" / ledger_name).read_text(encoding="utf-8"))
if args.scope == "runtime":
failures = violations(report, ledger, args.repository)
else:
evidence_dir = "dist" if args.repository in (
"PastureStack/kubernetes-agent",
"PastureStack/kubernetes-authentication-bridge") else "evidence"
boundary = json.loads((repo_root / evidence_dir / "dapper-header-boundary.json").read_text(encoding="utf-8"))
headers = json.loads((repo_root / ".github" / "dapper-headers.json").read_text(encoding="utf-8"))
graphs = None
docker_proof = None
if args.repository in ("PastureStack/kubernetes-authentication-bridge",
"PastureStack/ecr-credential-sync"):
graphs = {"buildx": (repo_root / evidence_dir / "buildx-package-graph.txt").read_text(encoding="utf-8")}
if args.repository == "PastureStack/ecr-credential-sync":
graphs["docker"] = (repo_root / evidence_dir / "docker-package-graph.txt").read_text(encoding="utf-8")
docker_proof = json.loads((repo_root / evidence_dir / "docker-manifest-digest-proof.json").read_text(encoding="utf-8"))
failures = builder_violations(report, ledger, args.repository, boundary, headers, graphs, docker_proof)
if failures:
raise SystemExit("Release vulnerability policy failed:\n" + "\n".join(failures))
print("RELEASE_VULNERABILITY_POLICY_OK")
70 changes: 70 additions & 0 deletions .github/scripts/test_builder_vulnerability_policy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import copy
import importlib.util
from pathlib import Path
import unittest

spec = importlib.util.spec_from_file_location("policy", Path(__file__).with_name("enforce-runtime-vulnerabilities.py"))
policy = importlib.util.module_from_spec(spec)
spec.loader.exec_module(policy)
REPO = "PastureStack/authentication-service"
PURL = "pkg:deb/ubuntu/linux-libc-dev@7.0.0-38.38?arch=amd64&distro=ubuntu-26.04"

class BuilderPolicy(unittest.TestCase):
def setUp(self):
self.report = {"SchemaVersion": 2, "Results": [
{"Target": "usr/local/go/bin/go", "Type": "gobinary", "Packages": [{"Name": "stdlib", "Version": "v1.27.3"}]},
{"Target": "os", "Vulnerabilities": []}]}
self.ledger = {"repository": REPO, "unfixed": []}
self.boundary = {"package": "linux-libc-dev", "version": "7.0.0-38.38", "kernel_images": False, "kernel_modules": False}
self.headers = {"repository": REPO, "package": "linux-libc-dev", "version": "7.0.0-38.38", "purl": PURL, "ids": ["HEADER-1"]}
def check(self):
return policy.builder_violations(self.report, self.ledger, REPO, self.boundary, self.headers)
def finding(self, severity="LOW", fixed=""):
item = {"VulnerabilityID": "HEADER-1", "PkgName": "linux-libc-dev", "InstalledVersion": "7.0.0-38.38",
"PkgIdentifier": {"PURL": PURL}, "Severity": severity, "FixedVersion": fixed}
self.report["Results"][1]["Vulnerabilities"] = [item]
return item
def test_complete_clean_scan(self):
self.assertEqual(self.check(), [])
def test_missing_expected_binary(self):
self.report["Results"] = self.report["Results"][1:]
with self.assertRaises(ValueError): self.check()
def test_empty_binary_packages(self):
self.report["Results"][0]["Packages"] = []
with self.assertRaises(ValueError): self.check()
def test_other_binary_missing_analysis(self):
self.report["Results"].append({"Target":"other", "Type":"gobinary"})
with self.assertRaises(ValueError): self.check()
def test_exact_nonexecuted_header(self):
self.finding("HIGH")
self.assertEqual(self.check(), [])
def test_fixed_header_is_never_exempt(self):
self.finding("LOW", "7.0.0-99")
self.assertTrue(self.check())
def test_new_header_advisory_blocks(self):
self.finding()["VulnerabilityID"] = "HEADER-NEW"
self.assertTrue(self.check())
def test_header_purl_drift_blocks(self):
self.finding()["PkgIdentifier"]["PURL"] += "-different"
self.assertTrue(self.check())
def test_missing_header_boundary_blocks(self):
self.finding()
self.boundary = {}
with self.assertRaises(ValueError): self.check()
def test_unregistered_low_medium_unknown_block(self):
for severity in ("LOW", "MEDIUM", "HIGH", "CRITICAL", "UNKNOWN"):
self.finding(severity)["PkgName"] = "other"
self.assertTrue(self.check())
def test_secrets_block(self):
self.report["Results"][1]["Secrets"] = [{"RuleID": "test"}]
self.assertTrue(self.check())
def test_nofix_ledger_does_not_exempt_fixed_finding(self):
finding = self.finding("LOW", "2")
finding.update(PkgName="test", InstalledVersion="1", PkgIdentifier={"PURL":"pkg:test/test@1"})
self.ledger["unfixed"] = [{"id":"HEADER-1", "package":"test", "version":"1", "purl":"pkg:test/test@1",
"severity":"LOW", "status":"no_official_fix", "officialEvidence":"https://fixture.invalid/test",
"reason":"test", "checkedAt":"2026-10-23"}]
self.assertTrue(self.check())

if __name__ == "__main__":
unittest.main()
77 changes: 77 additions & 0 deletions .github/scripts/test_runtime_vulnerability_policy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import copy
import importlib.util
import pathlib
import unittest

PATH = pathlib.Path(__file__).with_name('enforce-runtime-vulnerabilities.py')
SPEC = importlib.util.spec_from_file_location('gate', PATH)
GATE = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(GATE)
REPO = 'PastureStack/network-policy-manager'


class RuntimePolicy(unittest.TestCase):
def setUp(self):
self.finding = {'VulnerabilityID': 'TEST-1', 'PkgName': 'lib', 'InstalledVersion': '1',
'Severity': 'MEDIUM', 'FixedVersion': '',
'PkgIdentifier': {'PURL': 'pkg:test/lib@1'}}
self.report = {'SchemaVersion': 2, 'Results': [{'Target': 'fixture', 'Vulnerabilities': [self.finding]}]}
self.ledger = {'repository': REPO, 'unfixed': [{'id': 'TEST-1', 'package': 'lib',
'version': '1', 'severity': 'MEDIUM', 'purl': 'pkg:test/lib@1',
'status': 'no_official_fix', 'officialEvidence': 'https://fixture.invalid/advisory',
'reason': 'Test fixture only', 'checkedAt': '2026-10-23'}]}

def test_exact_reviewed_unfixed_medium_passes(self):
self.assertEqual(GATE.violations(self.report, self.ledger, REPO), [])

def test_clean_scan_passes(self):
self.assertEqual(GATE.violations({'SchemaVersion': 2, 'Results': [{'Target': 'fixture'}]},
{'repository': REPO, 'unfixed': []}, REPO), [])

def test_missing_or_malformed_scan_fails_closed(self):
for report in ({}, {'Results': []}, {'SchemaVersion': 2, 'Results': []},
{'SchemaVersion': 2, 'Results': [{}]},
{'SchemaVersion': 2, 'Results': [{'Target': 'fixture', 'Vulnerabilities': {}}]}):
with self.assertRaises(ValueError):
GATE.violations(report, self.ledger, REPO)

def test_unregistered_medium_blocks(self):
self.ledger['unfixed'] = []
self.assertTrue(GATE.violations(self.report, self.ledger, REPO))

def test_fixed_medium_blocks(self):
self.finding['FixedVersion'] = '2'
self.assertTrue(GATE.violations(self.report, self.ledger, REPO))

def test_fixed_low_blocks(self):
self.finding['Severity'] = 'LOW'
self.ledger['unfixed'][0]['severity'] = 'LOW'
self.finding['FixedVersion'] = '2'
self.assertTrue(GATE.violations(self.report, self.ledger, REPO))

def test_high_critical_and_unknown_always_block(self):
for severity in ('HIGH', 'CRITICAL', 'UNKNOWN'):
self.finding['Severity'] = severity
self.assertTrue(GATE.violations(self.report, self.ledger, REPO))

def test_version_or_purl_drift_blocks(self):
for key in ('version', 'purl'):
ledger = copy.deepcopy(self.ledger)
ledger['unfixed'][0][key] = 'different'
self.assertTrue(GATE.violations(self.report, ledger, REPO))

def test_secrets_always_block(self):
self.report['Results'][0]['Secrets'] = [{'RuleID': 'test'}]
self.assertTrue(GATE.violations(self.report, self.ledger, REPO))

def test_repository_drift_fails_closed(self):
with self.assertRaises(ValueError):
GATE.violations(self.report, self.ledger, 'another/repo')

def test_incomplete_evidence_fails_closed(self):
del self.ledger['unfixed'][0]['checkedAt']
with self.assertRaises(ValueError):
GATE.violations(self.report, self.ledger, REPO)

if __name__ == '__main__':
unittest.main()
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ jobs:
env:
GH_TOKEN: ${{ github.token }}
PRODUCER_RUN: ${{ inputs.producer_run }}
RELEASE_TAG: v0.7.3
RELEASE_TAG: v0.7.4
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: v0.7.3
ref: v0.7.4
fetch-depth: 0
persist-credentials: false
- name: Verify immutable tag and successful producer
Expand All @@ -47,7 +47,7 @@ jobs:
gzip -dc dist/security-runtime/images.tar.gz | docker load
printf '%s' "$GH_TOKEN" | docker login ghcr.io -u "$GITHUB_ACTOR" --password-stdin
trap 'docker logout ghcr.io >/dev/null 2>&1 || true' EXIT
source_image='pasturestack/kubernetes-agent:v0.7.3'
source_image='pasturestack/kubernetes-agent:v0.7.4'
remote_image="ghcr.io/pasturestack/kubernetes-agent:$RELEASE_TAG"
if docker manifest inspect "$remote_image" >/dev/null 2>"$RUNNER_TEMP/manifest-error"; then
echo "Refusing to replace an existing immutable image tag: $remote_image" >&2; exit 1
Expand Down
Loading
Loading