Publish curated ITWorx_MCP_Hub source from 2aa63ba527a98b38b4d28f2a1bb85b1b1dbe7f6d

This commit is contained in:
Public Source Publisher committed 2026-10-02 22:43:53 +00:00
1 parent 49627c7a7c
commit 378ae83d30
22 files changed
+4055 -81

No files matched your search

+3
View File
@@ -22,3 +22,6 @@ INSPECTOR_BIND_IP=127.0.0.1
COMPOSE_PROFILES=observability
DEMO_TOKEN_REVOCATIONS_DIR_HOST=/tmp
APPOPS_BUILD_DATE=2026-10-01T18:00:00Z
APPOPS_SOURCE_TREE=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
APPOPS_BUILD_ID=aaaaaaaaaaaa
SOURCE_DATE_EPOCH=1790888863
+33
View File
@@ -259,16 +259,43 @@ class ComposeContractTests(unittest.TestCase):
arguments.get("BUILD_DATE"),
"${APPOPS_BUILD_DATE:?APPOPS_BUILD_DATE is required}",
)
for argument, value in {
"GIT_SOURCE_TREE": "${APPOPS_SOURCE_TREE:?APPOPS_SOURCE_TREE is required}",
"IMAGE_VERSION": "${APPOPS_BUILD_ID:?APPOPS_BUILD_ID is required}",
"SOURCE_DATE_EPOCH": "${SOURCE_DATE_EPOCH:?SOURCE_DATE_EPOCH is required}",
}.items():
self.assertEqual(arguments.get(argument), value, name)
original_arguments = self.document["services"][name]["build"].get("args", {})
for key, value in original_arguments.items():
self.assertEqual(arguments.get(key), value)
def test_build_dockerfiles_emit_controller_tree_version_and_epoch_labels(self) -> None:
dockerfiles = (
"infrastructure/images/python-service/Dockerfile",
"infrastructure/images/docker-read-broker/Dockerfile",
"infrastructure/images/observability/Dockerfile",
)
expected_labels = {
"org.opencontainers.image.source-tree": "GIT_SOURCE_TREE",
"org.opencontainers.image.version": "IMAGE_VERSION",
"org.opencontainers.image.source-date-epoch": "SOURCE_DATE_EPOCH",
}
for relative_path in dockerfiles:
text = (ROOT / relative_path).read_text(encoding="utf-8")
with self.subTest(dockerfile=relative_path):
for label, argument in expected_labels.items():
self.assertIn(f"ARG {argument}", text)
self.assertIn(f'{label}="${{{argument}}}"', text)
def test_real_autodeploy_preserves_intake_digest_and_owned_build_revision(self) -> None:
docker = shutil.which("docker")
if docker is None:
self.skipTest("docker CLI is not available in this environment")
revision = "a" * 40
built_at = "2026-10-01T18:00:00Z"
source_tree = "b" * 40
image_version = revision[:12]
source_date_epoch = "1790888863"
with tempfile.TemporaryDirectory() as secrets_dir:
for name in self.document["secrets"]:
(Path(secrets_dir) / name).write_text("test-fixture-secret\n", encoding="utf-8")
@@ -301,6 +328,9 @@ class ComposeContractTests(unittest.TestCase):
"CONNECTOR_INGESTION_IMAGE": f"registry.example.test/intake@sha256:{'b' * 64}",
"GITEA_COMMIT_SHA": revision,
"APPOPS_BUILD_DATE": built_at,
"APPOPS_SOURCE_TREE": source_tree,
"APPOPS_BUILD_ID": image_version,
"SOURCE_DATE_EPOCH": source_date_epoch,
},
)
self.assertEqual(completed.returncode, 0, completed.stderr)
@@ -316,6 +346,9 @@ class ComposeContractTests(unittest.TestCase):
continue
self.assertEqual(service["build"]["args"]["GIT_REVISION"], revision, name)
self.assertEqual(service["build"]["args"]["BUILD_DATE"], built_at, name)
self.assertEqual(service["build"]["args"]["GIT_SOURCE_TREE"], source_tree, name)
self.assertEqual(service["build"]["args"]["IMAGE_VERSION"], image_version, name)
self.assertEqual(service["build"]["args"]["SOURCE_DATE_EPOCH"], source_date_epoch, name)
self.assertTrue(service["image"].endswith(f":{revision}"), name)
def test_unraid_folder_view_groups_the_complete_production_stack(self) -> None:
+386
View File
@@ -0,0 +1,386 @@
# The upstream TOML fixture retains exact source formatting.
# ruff: noqa: E501
from __future__ import annotations
import hashlib
import json
import re
import sys
from pathlib import Path
import pytest
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "scripts"))
import contextforge_candidate_recipe as recipe # noqa: E402 - script path added above
LOCK_DIR = ROOT / "infrastructure" / "images" / "contextforge" / "candidate"
def _hash(data: bytes) -> str:
return hashlib.sha256(data).hexdigest()
def _containerfile_fixture() -> bytes:
return (
b"FROM base\n"
b'RUN if [ "$ENABLE_RUST" = "true" ]; then \\\n dnf upgrade -y; fi\n'
b"RUN set -euo pipefail \\\n && dnf install -y python3.12\n"
b"RUN microdnf upgrade -y \\\n && microdnf install -y python3.12\n"
b'RUN if [ "$ENABLE_FIPS" = "true" ]; then \\\n microdnf install -y crypto-policies; fi\n'
b"COPY pyproject.toml /app/\n"
+ recipe.INSTALL_START.encode("utf-8")
+ b"\n && /app/.venv/bin/uv pip install unpinned\n"
+ recipe.INSTALL_END.encode("utf-8")
+ b"COPY source /app\n"
)
def _source_fixture(tmp_path: Path, containerfile: bytes) -> tuple[Path, dict[str, str]]:
source = tmp_path / "upstream"
source.mkdir()
contents = {
"Containerfile": containerfile,
"pyproject.toml": b"[project]\nname='fixture'\n",
"uv.lock": b"version = 1\n",
}
expected = {name: _hash(value) for name, value in contents.items()}
for name, value in contents.items():
(source / name).write_bytes(value)
return source, expected
def _copy_candidate_locks(destination: Path) -> dict[str, str]:
destination.mkdir(parents=True)
requirements: dict[str, str] = {}
for name in ("production-requirements.lock", "build-tools.lock"):
data = (LOCK_DIR / name).read_bytes()
(destination / name).write_bytes(data)
requirements[name] = _hash(data)
return requirements
def test_candidate_lock_exports_are_hash_complete_and_exclude_build_tools() -> None:
manifest = json.loads((LOCK_DIR / "locks.json").read_text(encoding="utf-8"))
production = (LOCK_DIR / "production-requirements.lock").read_text(encoding="utf-8")
build_tools = (LOCK_DIR / "build-tools.lock").read_text(encoding="utf-8")
assert manifest["upstreamCommit"] == recipe.UPSTREAM_COMMIT
assert manifest["uvVersion"] == recipe.UV_VERSION == "0.12.10"
assert manifest["globalExcludeNewerUtc"] == "2026-09-22T00:00:00Z"
assert manifest["freshnessOverrideUtc"] == "2026-10-02T00:00:00Z"
assert manifest["extras"] == list(recipe.EXTRAS)
assert manifest["constraints"] == list(recipe.CONSTRAINTS)
for name in ("production-requirements.lock", "build-tools.lock"):
assert _hash((LOCK_DIR / name).read_bytes()) == manifest["requirements"][name]
for requirement in recipe.CONSTRAINTS:
package, version = requirement.split("==", 1)
assert re.search(rf"(?im)^{re.escape(package)}=={re.escape(version)}\s*\\", production)
for requirement in recipe.BUILD_TOOLS:
package, version = requirement.split("==", 1)
assert re.search(rf"(?im)^{re.escape(package)}=={re.escape(version)}\s*\\", build_tools)
package_blocks = re.split(r"(?m)(?=^[A-Za-z0-9_.-]+==)", production)
package_blocks = [
block for block in package_blocks if re.match(r"(?m)^[A-Za-z0-9_.-]+==", block)
]
assert len(package_blocks) > 100
assert all(re.search(r"--hash=sha256:[0-9a-f]{64}", block) for block in package_blocks)
assert not re.search(r"(?im)^(pip|setuptools|wheel|uv)==", production)
build_blocks = re.split(r"(?m)(?=^[A-Za-z0-9_.-]+==)", build_tools)
build_blocks = [block for block in build_blocks if re.match(r"(?m)^[A-Za-z0-9_.-]+==", block)]
assert all(re.search(r"--hash=sha256:[0-9a-f]{64}", block) for block in build_blocks)
assert "pip==26.2.1" in build_tools
def test_candidate_pyproject_freezes_relative_freshness_and_preserves_project_metadata() -> None:
source = """[tool.uv]
exclude-newer = "10 days"
[tool.uv.exclude-newer-package]
known-safe-package = "2026-07-01T00:00:00Z"
[tool.uv.sources]
compliance-reference-server = { path = "mcp-servers/python/compliance_reference_server", editable = true }
# Project table follows the local source table.
[project]
name = "contextforge"
dependencies = ["httpx>=0.27"]
[dependency-groups]
dev = ["pytest>=8"]
"""
generated = recipe.candidate_pyproject(source)
import tomllib
parsed = tomllib.loads(generated)
assert parsed["project"] == {
"name": "contextforge",
"dependencies": ["httpx>=0.27"],
}
assert "sources" not in parsed["tool"]["uv"]
assert parsed["tool"]["uv"]["exclude-newer"] == "2026-09-22T00:00:00Z"
assert parsed["tool"]["uv"]["constraint-dependencies"] == list(recipe.CONSTRAINTS)
assert parsed["tool"]["uv"]["exclude-newer-package"]["known-safe-package"] == (
"2026-07-01T00:00:00Z"
)
assert parsed["tool"]["uv"]["exclude-newer-package"]["pyjwt"] == "2026-10-02T00:00:00Z"
assert parsed["dependency-groups"]["build-tools"] == list(recipe.BUILD_TOOLS)
assert "dev" not in parsed["dependency-groups"]
def test_candidate_transform_is_exact_and_uses_hash_locked_runtime_install() -> None:
original = _containerfile_fixture()
transformed = recipe.transform_containerfile(original, expected_hash=_hash(original)).decode()
assert transformed.count("COPY contextforge-candidate-production-requirements.txt") == 1
assert transformed.count("COPY contextforge-candidate-build-tools.txt") == 1
assert (
"--require-hashes --only-binary=:all: -r /tmp/contextforge-production-requirements.txt"
in transformed
)
assert (
"--require-hashes --only-binary=:all: -r /tmp/contextforge-build-tools.txt" in transformed
)
assert (
'--no-deps --no-build-isolation ".[redis,postgres,observability,granian,plugins,llmchat]"'
in transformed
)
assert "uv pip install unpinned" not in transformed
assert "COPY source /app" in transformed
assert not re.search(r"\b(?:dnf|microdnf) (?:upgrade|install)\b", transformed)
assert 'test "$ENABLE_RUST" = "false"' in transformed
assert 'test "$ENABLE_FIPS" = "false"' in transformed
assert 'test "$ENABLE_PROFILING" = "false"' in transformed
assert 'test "$(id -u app):$(id -g app)" = "10001:10001"' in transformed
def test_candidate_os_freeze_rejects_missing_or_additional_transactions() -> None:
original = _containerfile_fixture().decode()
for changed in (
original.replace("dnf upgrade -y", "echo changed", 1),
original + "\nRUN dnf install -y unexpected\n",
):
with pytest.raises(recipe.CandidateRecipeError, match="RPM transaction count"):
recipe.freeze_os_layers(changed)
def test_candidate_transform_rejects_source_drift_and_unexpected_anchor_counts() -> None:
original = _containerfile_fixture()
digest = _hash(original)
with pytest.raises(recipe.CandidateRecipeError, match="Containerfile hash mismatch"):
recipe.transform_containerfile(original + b"# drift\n", expected_hash=digest)
with pytest.raises(recipe.CandidateRecipeError, match="anchor count changed"):
recipe.transform_containerfile(
original.replace(b"COPY pyproject.toml /app/\n", b""),
expected_hash=_hash(original.replace(b"COPY pyproject.toml /app/\n", b"")),
)
def test_source_verification_rejects_missing_and_tampered_pinned_inputs(tmp_path: Path) -> None:
source, expected = _source_fixture(tmp_path, _containerfile_fixture())
assert recipe.verify_upstream_source(source, expected) == {
name: (source / name).read_bytes() for name in expected
}
(source / "uv.lock").write_bytes(b"changed lock")
with pytest.raises(recipe.CandidateRecipeError, match="uv.lock hash mismatch"):
recipe.verify_upstream_source(source, expected)
(source / "uv.lock").unlink()
with pytest.raises(recipe.CandidateRecipeError, match="missing: uv.lock"):
recipe.verify_upstream_source(source, expected)
def test_prepare_copies_verified_locks_and_fails_before_writing_on_missing_lock(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
source, source_hashes = _source_fixture(tmp_path, _containerfile_fixture())
lock_dir = tmp_path / "candidate-locks"
lock_hashes = _copy_candidate_locks(lock_dir)
manifest = recipe._make_manifest(
source_hashes=source_hashes,
production_hash=lock_hashes["production-requirements.lock"],
build_tools_hash=lock_hashes["build-tools.lock"],
)
(lock_dir / "locks.json").write_bytes(recipe._canonical_json(manifest))
monkeypatch.setattr(recipe, "SOURCE_HASHES", source_hashes)
monkeypatch.setattr(recipe, "LOCK_DIR", lock_dir)
monkeypatch.setattr(recipe, "LOCK_MANIFEST", lock_dir / "locks.json")
recipe.prepare_source(source)
assert (source / "Containerfile.itworx-candidate").exists()
for name, target in recipe.LOCK_OUTPUT_NAMES.items():
assert (source / target).read_bytes() == (lock_dir / name).read_bytes()
(source / "Containerfile.itworx-candidate").unlink()
(lock_dir / "build-tools.lock").unlink()
with pytest.raises(recipe.CandidateRecipeError, match="missing: build-tools.lock"):
recipe.prepare_source(source)
assert not (source / "Containerfile.itworx-candidate").exists()
def test_candidate_build_args_pin_every_base_and_disable_optional_builds() -> None:
args = recipe.candidate_build_args()
assert set(args) == {
"UBI_BASE",
"NODEJS_IMAGE",
"UBI_MINIMAL",
"WHEELS_REF",
"PYTHON_VERSION",
"ENABLE_RUST",
"ENABLE_RUST_MCP_RMCP",
"ENABLE_PROFILING",
"ENABLE_FIPS",
}
assert all("@sha256:" in args[key] for key in ("UBI_BASE", "NODEJS_IMAGE", "UBI_MINIMAL"))
assert args["UBI_BASE"] == (
"gitea.example.com/jens/itworx-mcp-hub/contextforge-os-builder@"
"sha256:e23a733abd28376eb3328676a3ab1e6d153122228110de0c881bb5f3c38a4483"
)
assert args["UBI_MINIMAL"] == (
"gitea.example.com/jens/itworx-mcp-hub/contextforge-os-runtime@"
"sha256:9b23d8152f253b10e47ce077bb9c5f8c3c370f3e0d5533f8a4a0e986ff176236"
)
assert args["NODEJS_IMAGE"] == (
"registry.access.redhat.com/ubi10/nodejs-24@"
"sha256:0f110e68682f4a49188ba4db786eb4f207b119420913fc76bb5ba9512ffbef06"
)
assert args["WHEELS_REF"] == args["UBI_MINIMAL"]
assert args["PYTHON_VERSION"] == "3.12"
assert (
args["ENABLE_RUST"] == args["ENABLE_RUST_MCP_RMCP"] == args["ENABLE_PROFILING"] == "false"
)
assert args["ENABLE_FIPS"] == "false"
def test_frozen_base_manifest_binds_published_digests_and_rpm_inventories() -> None:
manifest = json.loads((LOCK_DIR / "locks.json").read_text(encoding="utf-8"))
bases = {item["arg"]: item for item in manifest["baseImages"]}
assert set(bases) == {"UBI_BASE", "NODEJS_IMAGE", "UBI_MINIMAL"}
assert bases["UBI_BASE"] == {
"arg": "UBI_BASE",
"sourceTag": (
"gitea.example.com/jens/itworx-mcp-hub/contextforge-os-builder:"
"sha256-c6bb70a7a340ed1047e7cb934aa55b086ee68a5eb9ba6b2ad2e6825c7184a3e8"
),
"reference": (
"gitea.example.com/jens/itworx-mcp-hub/contextforge-os-builder@"
"sha256:e23a733abd28376eb3328676a3ab1e6d153122228110de0c881bb5f3c38a4483"
),
"parentReference": (
"registry.access.redhat.com/ubi10@"
"sha256:1e32d829a4de713a835d702d3bc05f0c448a08590796281b7dec181912e9aeb8"
),
"imageId": "sha256:c6bb70a7a340ed1047e7cb934aa55b086ee68a5eb9ba6b2ad2e6825c7184a3e8",
"rpmInventorySha256": "6a8c0d4f66fc5a38008541ad15614711e7f536cd18c70c02d2eb0691552b88b0",
"platform": "linux/amd64",
"childManifestDigest": (
"sha256:e23a733abd28376eb3328676a3ab1e6d153122228110de0c881bb5f3c38a4483"
),
}
assert bases["UBI_MINIMAL"] == {
"arg": "UBI_MINIMAL",
"sourceTag": (
"gitea.example.com/jens/itworx-mcp-hub/contextforge-os-runtime:"
"sha256-fd94e2643dfc0401790d0528d3740bb2f0c04709e743f6c774a4e8a38606e40b"
),
"reference": (
"gitea.example.com/jens/itworx-mcp-hub/contextforge-os-runtime@"
"sha256:9b23d8152f253b10e47ce077bb9c5f8c3c370f3e0d5533f8a4a0e986ff176236"
),
"parentReference": (
"registry.access.redhat.com/ubi10/ubi-minimal@"
"sha256:afbfb5c18c628796fed3ad3122dcf096e0b2dec9dad3fbabe8620de06bc6f078"
),
"imageId": "sha256:fd94e2643dfc0401790d0528d3740bb2f0c04709e743f6c774a4e8a38606e40b",
"rpmInventorySha256": "a74d60ecb43d1aa561874305d1a9c62ac35c99a14c1dc275ba1656f14df7d034",
"platform": "linux/amd64",
"childManifestDigest": (
"sha256:9b23d8152f253b10e47ce077bb9c5f8c3c370f3e0d5533f8a4a0e986ff176236"
),
}
assert bases["NODEJS_IMAGE"]["reference"] == (
"registry.access.redhat.com/ubi10/nodejs-24@"
"sha256:0f110e68682f4a49188ba4db786eb4f207b119420913fc76bb5ba9512ffbef06"
)
assert "imageId" not in bases["NODEJS_IMAGE"]
def test_frozen_base_reference_drift_fails_before_candidate_build(
monkeypatch: pytest.MonkeyPatch,
) -> None:
original = recipe.BASE_IMAGES[0]
changed = dict(original)
changed["reference"] = changed["reference"].replace("e23a733", "f23a733", 1)
monkeypatch.setattr(recipe, "BASE_IMAGES", (changed, *recipe.BASE_IMAGES[1:]))
with pytest.raises(recipe.CandidateRecipeError, match="reviewed contract"):
recipe._read_lock_manifest()
def test_frozen_base_evidence_matches_candidate_pins_and_repository_inputs() -> None:
evidence_path = ROOT / "evidence" / "WP-400" / "CF_FROZEN_BASES.json"
evidence = json.loads(evidence_path.read_text(encoding="utf-8"))
manifest = json.loads((LOCK_DIR / "locks.json").read_text(encoding="utf-8"))
bases = {item["arg"]: item for item in manifest["baseImages"]}
assert evidence["schema"] == "itworx.contextforge-frozen-os-bases-evidence/v1"
assert evidence["status"] == "passed"
assert evidence["finalContextForgeCandidateBuilt"] is False
assert evidence["sourceInputs"]["upstreamCommit"] == manifest["upstreamCommit"]
assert evidence["sourceInputs"]["ContainerfileSha256"] == manifest["upstreamFiles"][
"Containerfile"
]
assert evidence["sourceInputs"]["pyprojectTomlSha256"] == manifest["upstreamFiles"][
"pyproject.toml"
]
assert evidence["sourceInputs"]["uvLockSha256"] == manifest["upstreamFiles"]["uv.lock"]
assert set(evidence["hubInputsSha256"]) == {
"scripts/contextforge_candidate_recipe.py",
"scripts/build_contextforge_compat_image.sh",
"infrastructure/images/contextforge/candidate/locks.json",
"infrastructure/images/contextforge/candidate/production-requirements.lock",
"infrastructure/images/contextforge/candidate/build-tools.lock",
"infrastructure/images/contextforge/os-bases/Dockerfile.builder",
"infrastructure/images/contextforge/os-bases/Dockerfile.runtime",
"infrastructure/compose/docker-compose.autodeploy.yml",
}
assert evidence["hubInputsSha256"] == {
name: _hash((ROOT / name).read_bytes()) for name in evidence["hubInputsSha256"]
}
for role, arg in (("builder", "UBI_BASE"), ("runtime", "UBI_MINIMAL")):
published = evidence["publishedBases"][role]
locked = bases[arg]
assert published["reference"] == locked["reference"]
assert published["imageId"] == locked["imageId"]
assert published["rpmInventorySha256"] == locked["rpmInventorySha256"]
assert published["platform"] == locked["platform"] == "linux/amd64"
assert published["publication"]["pulledByDigest"] is True
assert published["publication"]["manifestConfigImageIdMatches"] is True
assert published["publication"]["rpmInventoryMatchesAfterPull"] is True
assert published["rpmInventory"]["exactMatch"] is True
assert published["scan"]["secretFindings"] == 0
assert published["scan"]["vulnerabilityFindingRecords"] == 0
def test_candidate_manifest_rejects_changed_lock_bytes(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
lock_dir = tmp_path / "locks"
lock_hashes = _copy_candidate_locks(lock_dir)
manifest = recipe._make_manifest(
source_hashes=recipe.SOURCE_HASHES,
production_hash=lock_hashes["production-requirements.lock"],
build_tools_hash=lock_hashes["build-tools.lock"],
)
(lock_dir / "locks.json").write_bytes(recipe._canonical_json(manifest))
(lock_dir / "production-requirements.lock").write_bytes(b"changed")
monkeypatch.setattr(recipe, "LOCK_DIR", lock_dir)
monkeypatch.setattr(recipe, "LOCK_MANIFEST", lock_dir / "locks.json")
with pytest.raises(recipe.CandidateRecipeError, match="lock hash mismatch"):
recipe._read_lock_manifest()
@@ -1,9 +1,15 @@
# Shell fixture lines preserve exact mocked build arguments and OCI values.
# ruff: noqa: E501
from __future__ import annotations
import hashlib
import json
import os
import re
import shutil
import subprocess
import tomllib
from pathlib import Path
import pytest
@@ -12,6 +18,9 @@ ROOT = Path(__file__).resolve().parents[1]
MANIFEST = ROOT / "infrastructure" / "images" / "contextforge" / "compat-image.env"
CONTRACT = ROOT / "infrastructure" / "images" / "contextforge" / "runtime-contract.json"
BUILDER = ROOT / "scripts" / "build_contextforge_compat_image.sh"
SECURITY_REQUIREMENTS = (
ROOT / "infrastructure" / "images" / "contextforge" / "security-requirements.txt"
)
EXPECTED = {
"CONTEXTFORGE_UPSTREAM_COMMIT": "1e58a0434a78bbdbe1e975abeb0bed1043ff14c1",
@@ -73,18 +82,18 @@ def test_contextforge_compat_builder_guards_source_and_runtime() -> None:
assert 'CONTRACT="$ROOT/infrastructure/images/contextforge/runtime-contract.json"' in script
assert 'ENTRYPOINT="$ROOT/infrastructure/images/contextforge/entrypoint.sh"' in script
assert 'RUNTIME_VERIFIER="$ROOT/scripts/contextforge_runtime_contract.py"' in script
assert 'https://github.com/IBM/mcp-context-forge.git' in script
assert "https://github.com/IBM/mcp-context-forge.git" in script
assert 'git -C "$SRC" fetch --depth 1 origin "$CONTEXTFORGE_UPSTREAM_COMMIT"' in script
assert 'git -C "$SRC" checkout --detach FETCH_HEAD' in script
assert 'git -C "$SRC" rev-parse HEAD' in script
assert 'REVISION_PREFIX="${CONTEXTFORGE_ALEMBIC_HEAD}_"' in script
assert 'MCP_REQUIREMENT="mcp==${CONTEXTFORGE_MCP_SDK}"' in script
assert "from mcp import McpError" in script
assert 'alembic -c mcpgateway/alembic.ini heads' in script
assert 'CONTEXTFORGE_ALEMBIC_HEAD' in script
assert 'contextforge-runtime-contract.json' in script
assert 'contextforge-entrypoint.sh' in script
assert 'contextforge-runtime-contract.py' in script
assert "alembic -c mcpgateway/alembic.ini heads" in script
assert "CONTEXTFORGE_ALEMBIC_HEAD" in script
assert "contextforge-runtime-contract.json" in script
assert "contextforge-entrypoint.sh" in script
assert "contextforge-runtime-contract.py" in script
for label in (
"io.itworx.contextforge.contract-sha256",
"io.itworx.contextforge.entrypoint-sha256",
@@ -92,12 +101,68 @@ def test_contextforge_compat_builder_guards_source_and_runtime() -> None:
"io.itworx.contextforge.source-commit",
"io.itworx.contextforge.alembic-head",
"io.itworx.contextforge.mcp-sdk",
"io.itworx.contextforge.security-requirements-sha256",
):
assert label in script
assert 'docker image inspect -f' in script
assert "docker image inspect -f" in script
assert 'docker tag "$STAGED_IMAGE" "$CONTEXTFORGE_LOCAL_IMAGE"' in script
def test_contextforge_security_wheels_match_the_reviewed_hub_lock() -> None:
lock = tomllib.loads((ROOT / "uv.lock").read_text(encoding="utf-8"))
packages = {package["name"]: package for package in lock["package"]}
requirements = SECURITY_REQUIREMENTS.read_text(encoding="utf-8").splitlines()
assert len(requirements) == 2
names = set()
for requirement in requirements:
match = re.fullmatch(
r"([A-Za-z0-9]+)==([0-9]+\.[0-9]+\.[0-9]+) --hash=sha256:([0-9a-f]{64})", requirement
)
assert match is not None, (
"Security inputs must pin a wheel version and SHA-256 without extra flags."
)
name, version, digest = match.groups()
normalized = name.lower()
assert normalized not in names
names.add(normalized)
package = packages[normalized]
assert version == package["version"]
assert f"sha256:{digest}" in {wheel["hash"] for wheel in package["wheels"]}
assert names == {"pyjwt", "urllib3"}
def test_missing_security_inputs_stop_builder_before_any_external_command(tmp_path: Path) -> None:
if os.name == "nt":
pytest.skip("The Linux builder executes in the required Linux validation job")
scripts = tmp_path / "scripts"
scripts.mkdir()
builder = scripts / BUILDER.name
builder.write_text(BUILDER.read_text(encoding="utf-8"), encoding="utf-8")
inputs = tmp_path / "infrastructure" / "images" / "contextforge"
inputs.mkdir(parents=True)
for name in ("compat-image.env", "runtime-contract.json", "entrypoint.sh"):
(inputs / name).write_text("fixture", encoding="utf-8")
(scripts / "contextforge_runtime_contract.py").write_text("fixture", encoding="utf-8")
bin_directory = tmp_path / "bin"
bin_directory.mkdir()
marker = tmp_path / "external-command-ran"
for name in ("git", "docker"):
executable = bin_directory / name
executable.write_text(f"#!/bin/sh\ntouch '{marker}'\nexit 99\n", encoding="utf-8")
executable.chmod(0o755)
env = {**os.environ, "PATH": f"{bin_directory}:{os.environ['PATH']}"}
completed = subprocess.run( # noqa: S603
[shutil.which("bash") or "/bin/bash", str(builder)],
env=env,
capture_output=True,
text=True,
check=False,
)
assert completed.returncode == 66
assert "security-requirements.txt" in completed.stderr
assert not marker.exists()
def test_contextforge_compat_builder_has_valid_shell_syntax() -> None:
if os.name == "nt":
pytest.skip("WSL bash cannot read a Windows path for syntax validation")
@@ -110,3 +175,392 @@ def test_contextforge_compat_builder_has_valid_shell_syntax() -> None:
check=False,
)
assert completed.returncode == 0, completed.stderr
def _candidate_builder_fixture(tmp_path: Path) -> tuple[Path, dict[str, str], Path, Path]:
root = tmp_path / "hub"
for relative in (
"scripts/build_contextforge_compat_image.sh",
"scripts/contextforge_candidate_recipe.py",
"scripts/contextforge_runtime_contract.py",
"infrastructure/images/contextforge/compat-image.env",
"infrastructure/images/contextforge/runtime-contract.json",
"infrastructure/images/contextforge/entrypoint.sh",
"infrastructure/images/contextforge/security-requirements.txt",
):
target = root / relative
target.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(ROOT / relative, target)
bin_dir = tmp_path / "bin"
bin_dir.mkdir()
log = tmp_path / "external-calls.log"
layer_capture = tmp_path / "candidate-layer.Containerfile"
git = bin_dir / "git"
git.write_text(
"#!/bin/sh\n"
'echo "git $*" >> "$CALL_LOG"\n'
'if [ "$1" = "-C" ]; then\n'
' src="$2"; action="$3"\n'
' if [ "$src" = "$SOURCE_ROOT" ]; then\n'
' case "$action:$4:$5" in\n'
' rev-parse:HEAD:) printf "%s\\n" "$GIT_HEAD" ;;\n'
' rev-parse:HEAD*:) printf "%s\\n" "$GIT_TREE" ;;\n'
' show:-s:--format=%ct) printf "%s\\n" "$GIT_EPOCH" ;;\n'
' show:-s:--format=%cI) printf "%s\\n" "$GIT_COMMIT_DATE" ;;\n'
' status:*:*) printf "%s" "${GIT_DIRTY:-}" ;;\n'
" esac\n"
" exit 0\n"
" fi\n"
' case "$action" in\n'
' fetch|checkout) mkdir -p "$src/mcpgateway/alembic/versions"; '
' printf "revision = \\"12d4a0c7789c\\"\\n" > '
'"$src/mcpgateway/alembic/versions/12d4a0c7789c_fixture.py"; '
' printf "FROM python:3.12\\n" > "$src/Containerfile" ;;\n'
' rev-parse) printf "1e58a0434a78bbdbe1e975abeb0bed1043ff14c1\\n" ;;\n'
" esac\n"
"fi\n"
"exit 0\n",
encoding="utf-8",
)
git.chmod(0o755)
real_python = shutil.which("python3")
assert real_python is not None
python3 = bin_dir / "python3"
python3.write_text(
"#!/bin/sh\n"
'case "$1" in\n'
" */contextforge_candidate_recipe.py)\n"
' case "$2" in\n'
' prepare) printf "candidate recipe\\n" > "$4/Containerfile.itworx-candidate" ;;\n'
" build-args)\n"
' printf "%s\\n" \\\n'
' "UBI_BASE=gitea.example.com/jens/itworx-mcp-hub/contextforge-os-builder@sha256:e23a733abd28376eb3328676a3ab1e6d153122228110de0c881bb5f3c38a4483" \\\n'
' "NODEJS_IMAGE=registry.access.redhat.com/ubi10/nodejs-24@sha256:0f110e68682f4a49188ba4db786eb4f207b119420913fc76bb5ba9512ffbef06" \\\n'
' "UBI_MINIMAL=gitea.example.com/jens/itworx-mcp-hub/contextforge-os-runtime@sha256:9b23d8152f253b10e47ce077bb9c5f8c3c370f3e0d5533f8a4a0e986ff176236" \\\n'
' "WHEELS_REF=gitea.example.com/jens/itworx-mcp-hub/contextforge-os-runtime@sha256:9b23d8152f253b10e47ce077bb9c5f8c3c370f3e0d5533f8a4a0e986ff176236" \\\n'
' "PYTHON_VERSION=3.12" "ENABLE_RUST=false" "ENABLE_RUST_MCP_RMCP=false" "ENABLE_PROFILING=false" "ENABLE_FIPS=false" ;;\n'
" esac\n"
" exit 0 ;;\n"
"esac\n"
f'exec "{real_python}" "$@"\n',
encoding="utf-8",
)
python3.chmod(0o755)
docker = bin_dir / "docker"
docker.write_text(
"#!/bin/sh\n"
'echo "docker $*" >> "$CALL_LOG"\n'
'if [ "$1" = "image" ] && [ "$2" = "inspect" ]; then\n'
' if [ "$3" != "-f" ]; then\n'
' [ "${COLLISION_TAG:-}" = "$3" ] && exit 0\n'
' printf "Error response from daemon: No such image: %s\\n" "$3" >&2\n'
" exit 1\n"
" fi\n"
' case "$4" in\n'
' *Config.User*) printf "10001:10001\\n" ;;\n'
' *contract-sha256*) printf "%s\\n" "$CONTRACT_SHA" ;;\n'
' *entrypoint-sha256*) printf "%s\\n" "$ENTRYPOINT_SHA" ;;\n'
' *verifier-sha256*) printf "%s\\n" "$VERIFIER_SHA" ;;\n'
' *source-commit*) printf "1e58a0434a78bbdbe1e975abeb0bed1043ff14c1\\n" ;;\n'
' *alembic-head*) printf "12d4a0c7789c\\n" ;;\n'
' *mcp-sdk*) printf "1.30.0\\n" ;;\n'
' *security-requirements-sha256*) printf "%s\\n" "$SECURITY_SHA" ;;\n'
' *org.opencontainers.image.source-tree*) printf "%s\\n" "$APPOPS_SOURCE_TREE" ;;\n'
' *org.opencontainers.image.revision*) printf "%s\\n" "$APPOPS_SOURCE_REVISION" ;;\n'
' *org.opencontainers.image.version*) printf "%s\\n" "$APPOPS_BUILD_ID" ;;\n'
' *org.opencontainers.image.source-date-epoch*) printf "%s\\n" "$SOURCE_DATE_EPOCH" ;;\n'
' *org.opencontainers.image.created*) printf "%s\\n" "$APPOPS_BUILD_DATE" ;;\n'
' *org.opencontainers.image.source*) printf "%s\\n" "$OCI_SOURCE" ;;\n'
" esac\n"
" exit 0\n"
"fi\n"
'if [ "$1" = "build" ]; then\n'
' while [ "$#" -gt 0 ]; do\n'
' if [ "$1" = "-f" ]; then layer="$2"; shift 2; else shift; fi\n'
" done\n"
' case "$layer" in *Containerfile.compat) cp "$layer" "$LAYER_CAPTURE" ;; esac\n'
" exit 0\n"
"fi\n"
'if [ "$1" = "run" ]; then\n'
' case "$*" in\n'
' *"alembic -c mcpgateway/alembic.ini heads"*) printf "12d4a0c7789c (head)\\n" ;;\n'
' *"contextforge-runtime-contract.json"*) printf "%s\\n" "$CONTRACT_SHA" ;;\n'
' *"contextforge-entrypoint.sh"*) printf "%s\\n" "$ENTRYPOINT_SHA" ;;\n'
' *"contextforge-runtime-contract.py"*) printf "%s\\n" "$VERIFIER_SHA" ;;\n'
' *"contextforge-security-requirements.txt"*) printf "%s\\n" "$SECURITY_SHA" ;;\n'
" esac\n"
" exit 0\n"
"fi\n"
"exit 0\n",
encoding="utf-8",
)
docker.chmod(0o755)
contract_sha = hashlib.sha256(
(root / "infrastructure/images/contextforge/runtime-contract.json").read_bytes()
).hexdigest()
entrypoint_sha = hashlib.sha256(
(root / "infrastructure/images/contextforge/entrypoint.sh").read_bytes()
).hexdigest()
verifier_sha = hashlib.sha256(
(root / "scripts/contextforge_runtime_contract.py").read_bytes()
).hexdigest()
security_sha = hashlib.sha256(
(root / "infrastructure/images/contextforge/security-requirements.txt").read_bytes()
).hexdigest()
environment = {
**os.environ,
"PATH": f"{bin_dir}:{os.environ['PATH']}",
"CALL_LOG": str(log),
"LAYER_CAPTURE": str(layer_capture),
"SOURCE_ROOT": str(root),
"CONTRACT_SHA": contract_sha,
"ENTRYPOINT_SHA": entrypoint_sha,
"VERIFIER_SHA": verifier_sha,
"SECURITY_SHA": security_sha,
"OCI_SOURCE": "https://gitea.example.com/jens/itworx-mcp-hub",
"GIT_HEAD": "a" * 40,
"GIT_TREE": "b" * 40,
"GIT_EPOCH": "1790964000",
"GIT_COMMIT_DATE": "2026-09-30T00:00:00+00:00",
"APPOPS_SOURCE_REPOSITORY": "jens/itworx_mcp_hub",
"APPOPS_SOURCE_REVISION": "a" * 40,
"APPOPS_SOURCE_TREE": "b" * 40,
"APPOPS_BUILD_ID": "a" * 12,
"APPOPS_BUILD_DATE": "2026-10-02T18:00:00.123Z",
"SOURCE_DATE_EPOCH": "1790964000",
"GITEA_REPOSITORY": "jens/itworx_mcp_hub",
"GITEA_COMMIT_SHA": "a" * 40,
}
return root / "scripts/build_contextforge_compat_image.sh", environment, log, layer_capture
def test_candidate_mode_requires_frozen_metadata_before_git_or_docker(tmp_path: Path) -> None:
if os.name == "nt":
pytest.skip("The Linux builder executes in the required Linux validation job")
builder, env, log, _layer = _candidate_builder_fixture(tmp_path)
env.pop("APPOPS_SOURCE_TREE")
completed = subprocess.run( # noqa: S603
[shutil.which("bash") or "/bin/bash", str(builder), "--release-candidate"],
env=env,
capture_output=True,
text=True,
check=False,
)
assert completed.returncode != 0
assert "APPOPS_SOURCE_TREE" in completed.stderr
assert not log.exists() or log.read_text(encoding="utf-8") == ""
def test_candidate_mode_rejects_unreviewed_build_variants_before_git_or_docker(
tmp_path: Path,
) -> None:
if os.name == "nt":
pytest.skip("The Linux builder executes in the required Linux validation job")
builder, env, log, _layer = _candidate_builder_fixture(tmp_path)
completed = subprocess.run( # noqa: S603
[
shutil.which("bash") or "/bin/bash",
str(builder),
"--release-candidate",
"--enable-fips",
],
env=env,
capture_output=True,
text=True,
check=False,
)
assert completed.returncode == 64
assert "supported mode" in completed.stderr
assert not log.exists() or log.read_text(encoding="utf-8") == ""
def test_candidate_mode_rejects_invalid_calendar_date_before_git_or_docker(
tmp_path: Path,
) -> None:
if os.name == "nt":
pytest.skip("The Linux builder executes in the required Linux validation job")
builder, env, log, _layer = _candidate_builder_fixture(tmp_path)
env["APPOPS_BUILD_DATE"] = "2026-02-30T18:00:00.123Z"
completed = subprocess.run( # noqa: S603
[shutil.which("bash") or "/bin/bash", str(builder), "--release-candidate"],
env=env,
capture_output=True,
text=True,
check=False,
)
assert completed.returncode != 0
assert "valid UTC calendar timestamp" in completed.stderr
assert not log.exists() or log.read_text(encoding="utf-8") == ""
@pytest.mark.parametrize("collision", ["final", "upstream", "staged"])
def test_candidate_mode_rejects_existing_revision_tags_after_source_validation_before_build(
tmp_path: Path, collision: str
) -> None:
if os.name == "nt":
pytest.skip("The Linux builder executes in the required Linux validation job")
builder, env, log, _layer = _candidate_builder_fixture(tmp_path)
revision = env["APPOPS_SOURCE_REVISION"]
suffix = {"final": "", "upstream": "-upstream", "staged": "-staged"}[collision]
env["COLLISION_TAG"] = f"itworx-mcp-hub/contextforge-schema:{revision}{suffix}"
completed = subprocess.run( # noqa: S603
[shutil.which("bash") or "/bin/bash", str(builder), "--release-candidate"],
env=env,
capture_output=True,
text=True,
check=False,
)
assert completed.returncode != 0
assert "already exists" in completed.stderr
calls = log.read_text(encoding="utf-8").splitlines()
assert any("docker image inspect" in call for call in calls)
assert any(call.startswith("git ") for call in calls)
assert not any("docker build" in call or "docker tag" in call for call in calls)
def test_candidate_mode_uses_only_revision_scoped_tags_and_frozen_oci_metadata(
tmp_path: Path,
) -> None:
if os.name == "nt":
pytest.skip("The Linux builder executes in the required Linux validation job")
builder, env, log, layer_capture = _candidate_builder_fixture(tmp_path)
static = EXPECTED["CONTEXTFORGE_LOCAL_IMAGE"]
revision = env["APPOPS_SOURCE_REVISION"]
completed = subprocess.run( # noqa: S603
[shutil.which("bash") or "/bin/bash", str(builder), "--release-candidate"],
env=env,
capture_output=True,
text=True,
check=False,
)
assert completed.returncode == 0, completed.stderr
calls = log.read_text(encoding="utf-8").splitlines()
tags = [call for call in calls if call.startswith("docker tag ")]
assert tags == [
f"docker tag itworx-mcp-hub/contextforge-schema:{revision}-staged "
f"itworx-mcp-hub/contextforge-schema:{revision}"
]
assert any(
f"-t itworx-mcp-hub/contextforge-schema:{revision}-upstream " in call for call in calls
)
assert any(
f"-t itworx-mcp-hub/contextforge-schema:{revision}-staged " in call for call in calls
)
candidate_build = next(
call
for call in calls
if "docker build" in call and "Containerfile.itworx-candidate" in call
)
assert "--platform linux/amd64" in candidate_build
assert (
"UBI_BASE=gitea.example.com/jens/itworx-mcp-hub/contextforge-os-builder@"
"sha256:e23a733abd28376eb3328676a3ab1e6d153122228110de0c881bb5f3c38a4483"
in candidate_build
)
assert (
"NODEJS_IMAGE=registry.access.redhat.com/ubi10/nodejs-24@sha256:0f110e686"
in candidate_build
)
assert (
"UBI_MINIMAL=gitea.example.com/jens/itworx-mcp-hub/contextforge-os-runtime@"
"sha256:9b23d8152f253b10e47ce077bb9c5f8c3c370f3e0d5533f8a4a0e986ff176236"
in candidate_build
)
assert (
"WHEELS_REF=gitea.example.com/jens/itworx-mcp-hub/contextforge-os-runtime@"
"sha256:9b23d8152f253b10e47ce077bb9c5f8c3c370f3e0d5533f8a4a0e986ff176236"
in candidate_build
)
assert "ENABLE_RUST=false" in candidate_build
assert "ENABLE_RUST_MCP_RMCP=false" in candidate_build
assert "ENABLE_PROFILING=false" in candidate_build
assert "ENABLE_FIPS=false" in candidate_build
assert not any(static in call for call in calls)
assert not any(call.startswith("docker rmi ") for call in calls)
assert "NOT APPROVED OR DEPLOYED" in completed.stdout
layer = layer_capture.read_text(encoding="utf-8")
assert "-m pip" not in layer
assert "import importlib.util" in layer
assert "find_spec" in layer
assert (
'org.opencontainers.image.source="https://gitea.example.com/jens/itworx-mcp-hub"' in layer
)
assert f'org.opencontainers.image.revision="{revision}"' in layer
assert f'org.opencontainers.image.source-tree="{env["APPOPS_SOURCE_TREE"]}"' in layer
assert f'org.opencontainers.image.version="{env["APPOPS_BUILD_ID"]}"' in layer
assert f'org.opencontainers.image.created="{env["APPOPS_BUILD_DATE"]}"' in layer
assert f'org.opencontainers.image.source-date-epoch="{env["SOURCE_DATE_EPOCH"]}"' in layer
@pytest.mark.parametrize(
"dirty", [" M scripts/contextforge_runtime_contract.py\n", "?? unexpected.py\n"]
)
def test_candidate_mode_rejects_a_dirty_source_checkout_before_fetch_or_build(
tmp_path: Path,
dirty: str,
) -> None:
if os.name == "nt":
pytest.skip("The Linux builder executes in the required Linux validation job")
builder, env, log, _layer = _candidate_builder_fixture(tmp_path)
env["GIT_DIRTY"] = dirty
completed = subprocess.run( # noqa: S603
[shutil.which("bash") or "/bin/bash", str(builder), "--release-candidate"],
env=env,
capture_output=True,
text=True,
check=False,
)
assert completed.returncode != 0
assert "source checkout has changes" in completed.stderr
calls = log.read_text(encoding="utf-8").splitlines()
assert not any("git init" in call or "git fetch" in call for call in calls)
assert not any(call.startswith("docker ") for call in calls)
assert not any("docker build" in call or "docker tag" in call for call in calls)
def test_candidate_mode_rejects_source_tree_mismatch_before_fetch_or_build(
tmp_path: Path,
) -> None:
if os.name == "nt":
pytest.skip("The Linux builder executes in the required Linux validation job")
builder, env, log, _layer = _candidate_builder_fixture(tmp_path)
env["APPOPS_SOURCE_TREE"] = "c" * 40
completed = subprocess.run( # noqa: S603
[shutil.which("bash") or "/bin/bash", str(builder), "--release-candidate"],
env=env,
capture_output=True,
text=True,
check=False,
)
assert completed.returncode != 0
assert "source tree differs" in completed.stderr
calls = log.read_text(encoding="utf-8").splitlines()
assert any("rev-parse" in call for call in calls)
assert not any("git init" in call or "git fetch" in call for call in calls)
assert not any(call.startswith("docker ") for call in calls)
assert not any("docker build" in call or "docker tag" in call for call in calls)
def test_candidate_mode_rejects_revision_mismatch_with_checked_out_head(
tmp_path: Path,
) -> None:
if os.name == "nt":
pytest.skip("The Linux builder executes in the required Linux validation job")
builder, env, log, _layer = _candidate_builder_fixture(tmp_path)
env["APPOPS_SOURCE_REVISION"] = "c" * 40
env["GITEA_COMMIT_SHA"] = "c" * 40
env["APPOPS_BUILD_ID"] = "c" * 12
completed = subprocess.run( # noqa: S603
[shutil.which("bash") or "/bin/bash", str(builder), "--release-candidate"],
env=env,
capture_output=True,
text=True,
check=False,
)
assert completed.returncode != 0
assert "checked-out Hub revision differs" in completed.stderr
calls = log.read_text(encoding="utf-8").splitlines()
assert any("rev-parse" in call for call in calls)
assert not any("git init" in call or "git fetch" in call for call in calls)
assert not any(call.startswith("docker ") for call in calls)
assert not any("docker build" in call or "docker tag" in call for call in calls)
@@ -3,6 +3,8 @@ from __future__ import annotations
import hashlib
from pathlib import Path
import yaml
from scripts.promotion_preflight import (
CONTEXTFORGE_PRODUCTION_IMAGE,
IMAGE_ENVIRONMENT,
@@ -14,15 +16,23 @@ ENV_EXAMPLE = ROOT / "infrastructure" / "compose" / ".env.example"
INPUT_MAP = ROOT / "infrastructure" / "compose" / "production-input-map.json"
PROD_COMPOSE = ROOT / "infrastructure" / "compose" / "docker-compose.prod.yml"
CONTRACT = ROOT / "infrastructure" / "images" / "contextforge" / "runtime-contract.json"
AUTODEPLOY = ROOT / "infrastructure" / "compose" / "docker-compose.autodeploy.yml"
def test_governed_contextforge_candidate_uses_the_exact_release_revision() -> None:
document = yaml.safe_load(AUTODEPLOY.read_text(encoding="utf-8"))
service = document["services"]["contextforge"]
assert service["image"] == (
"itworx-mcp-hub/contextforge-schema:${GITEA_COMMIT_SHA:?GITEA_COMMIT_SHA is required}"
)
assert service["pull_policy"] == "never"
assert not service.get("build")
def test_contextforge_uses_the_verified_local_compatibility_image() -> None:
assert "contextforge" not in IMAGE_ENVIRONMENT
assert "CONTEXTFORGE_IMAGE" not in REQUIRED_ENV
assert (
CONTEXTFORGE_PRODUCTION_IMAGE
== "itworx-mcp-hub/contextforge-schema:12d4a0c7789c"
)
assert CONTEXTFORGE_PRODUCTION_IMAGE == "itworx-mcp-hub/contextforge-schema:12d4a0c7789c"
env_example = ENV_EXAMPLE.read_text(encoding="utf-8")
assert "CONTEXTFORGE_IMAGE=" not in env_example
@@ -42,8 +52,5 @@ def test_contextforge_contract_digest_is_repository_owned_and_exact() -> None:
expected = hashlib.sha256(CONTRACT.read_bytes()).hexdigest()
production = PROD_COMPOSE.read_text(encoding="utf-8")
assert (
f'ITWORX_CONTEXTFORGE_EXPECTED_CONTRACT_SHA256: "{expected}"'
in production
)
assert f'ITWORX_CONTEXTFORGE_EXPECTED_CONTRACT_SHA256: "{expected}"' in production
assert "${CONTEXTFORGE_CONTRACT_SHA256" not in production
+4 -1
View File
@@ -255,7 +255,10 @@ class IngestionCatalogComposeTests(unittest.TestCase):
**os.environ,
"SECRETS_DIR": str(ROOT / "tests/fixtures"),
"CONNECTOR_INGESTION_IMAGE": digest,
"GITEA_COMMIT_SHA": "test-sha",
"GITEA_COMMIT_SHA": "a" * 40,
"APPOPS_SOURCE_TREE": "b" * 40,
"APPOPS_BUILD_ID": "a" * 12,
"SOURCE_DATE_EPOCH": "1790888863",
},
capture_output=True,
text=True,
+358 -2
View File
@@ -3,10 +3,12 @@
from __future__ import annotations
import json
import sys
from datetime import date, timedelta
from pathlib import Path
from scripts.check_cve_exceptions import REQUIRED_FIELDS, check
from scripts.draft_cve_exceptions import main as draft_exceptions_main
ROOT = Path(__file__).resolve().parents[1]
TODAY = date(2026, 8, 15)
@@ -45,6 +47,13 @@ def _exception(**overrides) -> dict:
return base
def _image_entry(image_id: str, tag: str | None = None) -> dict[str, str]:
entry = {"imageId": image_id}
if tag is not None:
entry["tag"] = tag
return entry
def test_real_wp220_registry_has_every_required_field() -> None:
"""The actual drafted registry this packet ships must be schema-complete."""
doc = json.loads(
@@ -122,7 +131,7 @@ def test_changed_digest_fails() -> None:
exceptions = {
"exceptions": [_exception(affectedImageDigests={"control-api": "sha256:" + "a" * 64})]
}
current_digests = {"control-api": "sha256:" + "b" * 64}
current_digests = {"control-api": _image_entry("sha256:" + "b" * 64)}
errors = check(scan, exceptions, current_digests, TODAY)
assert any("DIGEST CHANGED" in e for e in errors)
@@ -132,11 +141,258 @@ def test_matching_digest_passes() -> None:
exceptions = {
"exceptions": [_exception(affectedImageDigests={"control-api": "sha256:" + "a" * 64})]
}
current_digests = {"control-api": "sha256:" + "a" * 64}
current_digests = {"control-api": _image_entry("sha256:" + "a" * 64)}
errors = check(scan, exceptions, current_digests, TODAY)
assert errors == []
def test_missing_current_service_for_affected_image_fails() -> None:
scan = _scan(
{
"package": "pkg",
"cves": ["CVE-2026-1"],
"severity": "HIGH",
"affectedImages": ["local/control-api:dev", "local/worker:dev"],
}
)
exceptions = {
"exceptions": [
_exception(
affectedImageDigests={
"control-api": "sha256:" + "a" * 64,
"worker": "sha256:" + "b" * 64,
}
)
]
}
current = {"control-api": _image_entry("sha256:" + "a" * 64, "local/control-api:dev")}
errors = check(scan, exceptions, current, TODAY)
assert any(
"AFFECTED IMAGE UNBOUND" in error and "local/worker:dev" in error for error in errors
)
def test_missing_exception_digest_binding_fails_closed() -> None:
scan = _scan(
{
"package": "pkg",
"cves": ["CVE-2026-1"],
"severity": "HIGH",
"affectedImages": ["local/control-api:dev"],
}
)
exceptions = {
"exceptions": [
_exception(
affectedImageDigests={
"unrelated": "sha256:" + "c" * 64,
}
)
]
}
current = {"control-api": _image_entry("sha256:" + "a" * 64, "local/control-api:dev")}
errors = check(scan, exceptions, current, TODAY)
assert any("IMAGE BINDING MISSING" in error and "control-api" in error for error in errors)
def test_empty_exception_digest_binding_fails_closed() -> None:
scan = _scan({"package": "pkg", "cves": ["CVE-2026-1"], "severity": "HIGH"})
exceptions = {"exceptions": [_exception(affectedImageDigests={"control-api": ""})]}
current = {"control-api": _image_entry("sha256:" + "a" * 64)}
errors = check(scan, exceptions, current, TODAY)
assert any("IMAGE BINDING MISSING" in error and "control-api" in error for error in errors)
def test_malformed_recorded_digest_fails_closed() -> None:
scan = _scan({"package": "pkg", "cves": ["CVE-2026-1"], "severity": "HIGH"})
exceptions = {"exceptions": [_exception(affectedImageDigests={"control-api": "sha256:abc"})]}
current = {"control-api": _image_entry("sha256:" + "a" * 64)}
errors = check(scan, exceptions, current, TODAY)
assert any("IMAGE BINDING INVALID" in error and "control-api" in error for error in errors)
def test_missing_or_malformed_current_image_id_fails_even_with_digest() -> None:
scan = _scan({"package": "pkg", "cves": ["CVE-2026-1"], "severity": "HIGH"})
exceptions = {"exceptions": [_exception()]}
current = {"control-api": {"digest": "sha256:" + "a" * 64}}
errors = check(scan, exceptions, current, TODAY)
assert any("CURRENT IMAGE ID INVALID" in error and "control-api" in error for error in errors)
def test_malformed_current_image_id_fails_even_with_digest() -> None:
scan = _scan({"package": "pkg", "cves": ["CVE-2026-1"], "severity": "HIGH"})
exceptions = {"exceptions": [_exception()]}
current = {
"control-api": {
"imageId": "sha256:not-a-full-image-id",
"digest": "sha256:" + "a" * 64,
}
}
errors = check(scan, exceptions, current, TODAY)
assert any("CURRENT IMAGE ID INVALID" in error for error in errors)
def test_empty_current_image_inventory_fails_when_supplied() -> None:
scan = _scan({"package": "pkg", "cves": ["CVE-2026-1"], "severity": "HIGH"})
errors = check(scan, {"exceptions": [_exception()]}, {}, TODAY)
assert any("IMAGE INVENTORY INVALID" in error for error in errors)
def test_scan_installed_version_must_match_reviewed_version() -> None:
scan = _scan(
{
"package": "pkg",
"cves": ["CVE-2026-1"],
"severity": "HIGH",
"installedVersion": "2.0",
}
)
errors = check(scan, {"exceptions": [_exception(installedVersion="1.0")]}, None, TODAY)
assert any("VERSION MISMATCH" in error and "2.0" in error for error in errors)
def test_conflicting_duplicate_exceptions_fail_instead_of_overwriting() -> None:
scan = _scan({"package": "pkg", "cves": ["CVE-2026-1"], "severity": "HIGH"})
approved = _exception()
conflicting = _exception(
approvalStatus="pending", riskOwner="", approver="", compensatingControls=""
)
errors = check(scan, {"exceptions": [approved, conflicting]}, None, TODAY)
assert any("CONFLICTING DUPLICATE" in error for error in errors)
assert any("UNAPPROVED" in error for error in errors)
def test_scoped_approval_binds_only_affected_services() -> None:
scan = _scan(
{
"package": "pkg",
"cves": ["CVE-2026-1"],
"severity": "HIGH",
"installedVersion": "1.0",
"affectedImages": ["local/worker:dev"],
}
)
exceptions = {"exceptions": [_exception(affectedImageDigests={"worker": "sha256:" + "b" * 64})]}
current = {
"control-api": _image_entry("sha256:" + "c" * 64, "local/control-api:dev"),
"worker": _image_entry("sha256:" + "b" * 64, "local/worker:dev"),
}
errors = check(scan, exceptions, current, TODAY)
assert errors == []
def test_legacy_scan_without_affected_images_uses_full_inventory() -> None:
scan = _scan({"package": "pkg", "cves": ["CVE-2026-1"], "severity": "HIGH"})
exceptions = {
"exceptions": [_exception(affectedImageDigests={"control-api": "sha256:" + "a" * 64})]
}
current = {
"control-api": _image_entry("sha256:" + "a" * 64),
"worker": _image_entry("sha256:" + "b" * 64),
}
errors = check(scan, exceptions, current, TODAY)
assert any("IMAGE BINDING MISSING" in error and "worker" in error for error in errors)
def test_legacy_scan_rejects_inventory_missing_a_reviewed_service() -> None:
scan = _scan({"package": "pkg", "cves": ["CVE-2026-1"], "severity": "HIGH"})
exceptions = {
"exceptions": [
_exception(
affectedImageDigests={
"control-api": "sha256:" + "a" * 64,
"worker": "sha256:" + "b" * 64,
}
)
]
}
current = {"control-api": _image_entry("sha256:" + "a" * 64)}
errors = check(scan, exceptions, current, TODAY)
assert any("IMAGE INVENTORY SCOPE CHANGED" in error for error in errors)
def test_draft_is_pending_and_scopes_digests_to_affected_images(
tmp_path: Path, monkeypatch
) -> None:
scan_path = tmp_path / "scan.json"
image_path = tmp_path / "images.json"
output_path = tmp_path / "draft.json"
scan_path.write_text(
json.dumps(
{
**_scan(
{
"package": "pkg",
"cves": ["CVE-2026-1"],
"severity": "HIGH",
"installedVersion": "1.0",
"affectedImages": ["local/worker:dev"],
}
),
"scannedAt": "2026-08-15T00:00:00Z",
}
),
encoding="utf-8",
)
image_path.write_text(
json.dumps(
{
"images": {
"control-api": _image_entry("sha256:" + "a" * 64, "local/control-api:dev"),
"worker": _image_entry("sha256:" + "b" * 64, "local/worker:dev"),
}
}
),
encoding="utf-8",
)
monkeypatch.setattr(
sys,
"argv",
[
"draft_cve_exceptions.py",
"--scan-summary",
str(scan_path),
"--image-digests",
str(image_path),
"--evidence-reference",
"evidence/WP-200/test.md",
"--output",
str(output_path),
],
)
assert draft_exceptions_main() == 0
drafted = json.loads(output_path.read_text(encoding="utf-8"))["exceptions"]
assert len(drafted) == 1
assert drafted[0]["approvalStatus"] == "pending"
assert drafted[0]["affectedImageDigests"] == {"worker": "sha256:" + "b" * 64}
def test_malformed_exception_missing_required_field_fails() -> None:
scan = _scan({"package": "pkg", "cves": ["CVE-2026-1"], "severity": "HIGH"})
broken = _exception()
@@ -158,3 +414,103 @@ def test_multiple_cves_in_one_package_row_each_need_their_own_exception() -> Non
errors = check(scan, exceptions, None, TODAY)
assert not any("CVE-2026-1" in e for e in errors)
assert any("CVE-2026-2" in e and "UNAPPROVED" in e for e in errors)
def test_distinct_installed_versions_are_reviewed_separately_for_scoped_images() -> None:
scan = _scan(
{
"package": "pkg",
"cves": ["CVE-2026-1"],
"severity": "HIGH",
"installedVersion": "1.0",
"affectedImages": ["local/web:dev"],
},
{
"package": "pkg",
"cves": ["CVE-2026-1"],
"severity": "HIGH",
"installedVersion": "2.0",
"affectedImages": ["local/postgres:dev"],
},
)
exceptions = {
"exceptions": [
_exception(affectedImageDigests={"web": "sha256:" + "a" * 64}),
_exception(
id="pkg-CVE-2026-1-v2",
installedVersion="2.0",
affectedImageDigests={"postgres": "sha256:" + "b" * 64},
),
]
}
images = {
"web": _image_entry("sha256:" + "a" * 64, "local/web:dev"),
"postgres": _image_entry("sha256:" + "b" * 64, "local/postgres:dev"),
}
assert check(scan, exceptions, images, TODAY) == []
exceptions["exceptions"].pop()
assert any("VERSION MISMATCH" in error for error in check(scan, exceptions, images, TODAY))
def test_versionless_legacy_scan_rejects_ambiguous_version_reviews() -> None:
scan = _scan({"package": "pkg", "cves": ["CVE-2026-1"], "severity": "HIGH"})
exceptions = {"exceptions": [_exception(), _exception(id="v2", installedVersion="2.0")]}
assert any("AMBIGUOUS VERSION" in error for error in check(scan, exceptions, None, TODAY))
def test_draft_distinct_versions_keeps_unique_pending_image_bound_reviews(
tmp_path: Path, monkeypatch
) -> None:
scan = _scan(
*[
{
"package": "pkg",
"cves": ["CVE-2026-1"],
"severity": "HIGH",
"installedVersion": version,
"affectedImages": [f"local/{service}:dev"],
}
for version, service in [("1.0", "web"), ("2.0", "postgres")]
]
)
scans, images, output = (
tmp_path / "scan.json",
tmp_path / "images.json",
tmp_path / "draft.json",
)
scans.write_text(json.dumps(scan), encoding="utf-8")
images.write_text(
json.dumps(
{
"images": {
"web": _image_entry("sha256:" + "a" * 64, "local/web:dev"),
"postgres": _image_entry("sha256:" + "b" * 64, "local/postgres:dev"),
}
}
),
encoding="utf-8",
)
monkeypatch.setattr(
sys,
"argv",
[
"draft",
"--scan-summary",
str(scans),
"--image-digests",
str(images),
"--output",
str(output),
"--evidence-reference",
"fixture",
],
)
assert draft_exceptions_main() == 0
drafted = json.loads(output.read_text(encoding="utf-8"))["exceptions"]
assert len(drafted) == 2 and len({entry["id"] for entry in drafted}) == 2
assert all(
entry["approvalStatus"] == "pending" and not entry["riskOwner"] and not entry["approver"]
for entry in drafted
)
assert drafted[0]["affectedImageDigests"] == {"web": "sha256:" + "a" * 64}
assert drafted[1]["affectedImageDigests"] == {"postgres": "sha256:" + "b" * 64}