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
8 changes: 8 additions & 0 deletions qualification/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,14 @@ The `sdk-php-cooperative-server` entry in `composer-container-trust.json`
applies only to its registered Compose request and reviewed Server recipes.
It supplies no trust for other build or runtime paths.

Its additional Server 3.8.0 recipe comes from published source
`28f084513235f6647e740c4b3d9e3aace7a323b7`. It binds the fixed APT parent
Dockerfile, lockfile, copied/executed `docker/apt/require-fixed-apt.sh` and
`docker/apt/parent.v1.json` proof alongside the existing preparation inputs.
The older recipe remains available. Source matching alone does not qualify
the caller: its clean predecessor, live in-container verifier and actual
registered Compose request remain required.

The container control runs the actual digest-pinned Composer image against a
local synthetic TLS registry. The ambient store accepts its synthetic blocked
root. The verified clean store refuses before an HTTP request. Wrong bundle
Expand Down
16 changes: 16 additions & 0 deletions qualification/composer-container-trust.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,22 @@
},
"composer_image": "composer:2.10.3@sha256:da624c2c705d54e2f5a9bb77a5dc6c7d091711433ebefd7035672e84c2010fee",
"composer_stage": "composer"
},
{
"files": {
"Dockerfile": "d70f15b575b98f0cfd6c5b6abc95a9d53b9560b03aeed9c1996fec46d4d9d41a",
".dockerignore": "9ae64622b015a660f64c594f6948540e224255ffe64ab1a766ee0633f1d5f5c4",
"Dockerfile.dockerignore": "e7bf60d34720f0639193f44ce715d74165bba3355c0dacb5445fe5e82c64ba33",
"composer.json": "e22b3c192ac024781142c44a6cc2c81deb6abdd364cf84cba5f15381be98c4f5",
"composer.lock": "c622d912e8367c8a1bc5a532adf302c1c28d4b2479bbdac043eb2b2ffbf78bfc",
"scripts/ci/WorkflowPackageAuthority.php": "24960bb0afe9078ee0522c81f6be45aa85122e76655fe0a1dfabd5f4ee4de9a3",
"scripts/ci/resolve-workflow-package-authority.php": "53ae520195192c20efe6531c3c2a50aef599ff0dcf99ebaf0933cbb6b5a04f86",
"scripts/ci/prepare-release-workflow-composer-metadata.php": "a96f9a3d0472646de3476fc1a07ba4754b5832f8cf8739223b16ca8d57a122fd",
"docker/apt/require-fixed-apt.sh": "082e4bcf3aebaf8da74658c2f15c4b6df259e0cb8f2b09e4e16a737e223a94a3",
"docker/apt/parent.v1.json": "09078d7166cd57d8781ef344f5f7b2f69712ace54aa867d320d99954f039cd60"
},
"composer_image": "composer:2.10.3@sha256:da624c2c705d54e2f5a9bb77a5dc6c7d091711433ebefd7035672e84c2010fee",
"composer_stage": "composer"
}
]
}
Expand Down
31 changes: 31 additions & 0 deletions tests/test_composer_container_trust.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,37 @@ def test_unrelated_product_source_can_advance_without_changing_the_recipe(self):
self.commit = self.git("rev-parse", "HEAD")
self.assertEqual(self.commit, self.check()[1]["source_commit"])

def test_a_successor_recipe_binds_its_added_executed_helper(self):
helper = self.source / "docker/apt/require-fixed-apt.sh"
helper.parent.mkdir(parents=True)
helper.write_text("#!/bin/sh\nexit 0\n")
self.dockerfile += "COPY docker/apt/require-fixed-apt.sh /fixed-apt.sh\nRUN sh /fixed-apt.sh\n"
(self.source / "Dockerfile").write_text(self.dockerfile)
self.git("add", ".")
self.git("commit", "--quiet", "-m", "successor with fixed APT prerequisite")
self.commit = self.git("rev-parse", "HEAD")
with self.assertRaisesRegex(ContainerTrustRefused, "no uniquely approved"):
self.check()

successor = deepcopy(self.catalog["requests"]["fixture"]["approved_recipes"][0])
successor["files"]["Dockerfile"] = sha256(self.dockerfile.encode())
successor["files"]["docker/apt/require-fixed-apt.sh"] = sha256(helper.read_bytes())
self.catalog["requests"]["fixture"]["approved_recipes"].append(successor)
self.assertEqual(self.commit, self.check()[1]["source_commit"])

helper.write_text("#!/bin/sh\nexit 1\n")
self.git("add", ".")
self.git("commit", "--quiet", "-m", "changed helper without recipe review")
self.commit = self.git("rev-parse", "HEAD")
with self.assertRaisesRegex(ContainerTrustRefused, "reviewed recipe files"):
self.check()

self.git("rm", "docker/apt/require-fixed-apt.sh")
self.git("commit", "--quiet", "-m", "missing helper")
self.commit = self.git("rev-parse", "HEAD")
with self.assertRaisesRegex(ContainerTrustRefused, "required recipe file is missing"):
self.check()

def test_a_new_dockerfile_specific_context_policy_requires_recipe_review(self):
(self.source / "Dockerfile.dockerignore").write_text("# Changes the actual Docker context\n")
self.git("add", "Dockerfile.dockerignore")
Expand Down
Loading