From 1bd7e7a41f971b5eac99a57ff3e67eacb3c45537 Mon Sep 17 00:00:00 2001 From: libops-agent <115990865+libops-agent@users.noreply.github.com> Date: Sun, 30 Aug 2026 19:04:34 +0000 Subject: [PATCH] [patch] Separate managed and resolved builder identity --- .../validate.mjs | 7 ++- .github/compatibility/README.md | 4 +- .../platform-release.owners.json | 2 + .../platform-release.schema.json | 8 ++- ci/github/test_managed_refs.py | 58 +++++++++++++++++++ .../testdata/platform-release.valid.json | 37 ++++++------ 6 files changed, 91 insertions(+), 25 deletions(-) diff --git a/.github/actions/validate-platform-compatibility/validate.mjs b/.github/actions/validate-platform-compatibility/validate.mjs index e3ee55c..2affb3e 100644 --- a/.github/actions/validate-platform-compatibility/validate.mjs +++ b/.github/actions/validate-platform-compatibility/validate.mjs @@ -57,7 +57,7 @@ const packageName = /^[a-z0-9][a-z0-9-]*$/; const digest = /^sha256:[0-9a-f]{64}$/; const image = /^[A-Za-z0-9][A-Za-z0-9._/-]*:[A-Za-z0-9][A-Za-z0-9._-]*@sha256:[0-9a-f]{64}$/; const runURL = /^https:\/\/github\.com\/[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+\/actions\/runs\/[0-9]+$/; -const certificateIdentity = /^https:\/\/github\.com\/[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+\/\.github\/workflows\/build-push\.ya?ml@[0-9a-f]{40}$/; +const certificateIdentity = /^https:\/\/github\.com\/libops\/\.github\/\.github\/workflows\/build-push\.yaml@refs\/(heads|tags)\/[A-Za-z0-9._/-]+$/; const callerWorkflowRef = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+\/\.github\/workflows\/[A-Za-z0-9_.-]+\.ya?ml@\S+$/; const families = new Set(["archivesspace", "drupal", "islandora", "ojs", "omeka-classic", "omeka-s", "wordpress"]); @@ -205,8 +205,9 @@ function validateImage(item, path) { if (!image.test(item.reference)) die(`${path}.reference must contain an exact tag and sha256 digest`); source(item.source, `${path}.source`); const attestationsPath = `${path}.attestations`; - exactKeys(item.attestations, attestationsPath, ["certificateIdentity", "callerWorkflowRef", "sbom", "provenance"]); - if (!certificateIdentity.test(item.attestations.certificateIdentity)) die(`${attestationsPath}.certificateIdentity must bind the exact shared publisher commit`); + exactKeys(item.attestations, attestationsPath, ["certificateIdentity", "builderCommit", "callerWorkflowRef", "sbom", "provenance"]); + if (!certificateIdentity.test(item.attestations.certificateIdentity)) die(`${attestationsPath}.certificateIdentity must bind a managed shared-publisher ref`); + if (!sha.test(item.attestations.builderCommit)) die(`${attestationsPath}.builderCommit must bind the exact resolved shared-publisher commit`); if (!callerWorkflowRef.test(item.attestations.callerWorkflowRef)) die(`${attestationsPath}.callerWorkflowRef must identify the caller workflow and ref`); exactKeys(item.attestations.sbom, `${attestationsPath}.sbom`, ["predicateType", "platforms", "verificationRun"]); if (item.attestations.sbom.predicateType !== "https://spdx.dev/Document") die(`${attestationsPath}.sbom.predicateType is invalid`); diff --git a/.github/compatibility/README.md b/.github/compatibility/README.md index 9826d8e..08b5e98 100644 --- a/.github/compatibility/README.md +++ b/.github/compatibility/README.md @@ -6,8 +6,8 @@ contract. The manifest is the exact, reviewable set that was tested together: - the Terraform source commit; - all 17 required API, controller, runner, Vault, edge, PPB, Task Agent, and - sandbox images, each with source, digest, publisher identity, SBOM, - provenance, and contract-test evidence; + sandbox images, each with source, digest, managed publisher identity, exact + runtime-resolved builder commit, SBOM, provenance, and contract-test evidence; - the canonical skills source commit and embedded-manifest digest; - hosted onboarding, GitHub-install, Slack-install, Vault-recovery, edge-routing, Task Agent, MariaDB-recovery, and rollback runs; diff --git a/.github/compatibility/platform-release.owners.json b/.github/compatibility/platform-release.owners.json index ff2c261..7cc4d34 100644 --- a/.github/compatibility/platform-release.owners.json +++ b/.github/compatibility/platform-release.owners.json @@ -13,6 +13,7 @@ {"path": "/platformImages/*/image/source/repository", "owner": "platform-component-owner"}, {"path": "/platformImages/*/image/source/commit", "owner": "platform-component-owner"}, {"path": "/platformImages/*/image/attestations/certificateIdentity", "owner": "libops-devsecops"}, + {"path": "/platformImages/*/image/attestations/builderCommit", "owner": "libops-devsecops"}, {"path": "/platformImages/*/image/attestations/callerWorkflowRef", "owner": "libops-devsecops"}, {"path": "/platformImages/*/image/attestations/sbom/predicateType", "owner": "libops-devsecops"}, {"path": "/platformImages/*/image/attestations/sbom/platforms/*", "owner": "libops-devsecops"}, @@ -55,6 +56,7 @@ {"path": "/applications/*/images/*/source/repository", "owner": "application-family-owner"}, {"path": "/applications/*/images/*/source/commit", "owner": "application-family-owner"}, {"path": "/applications/*/images/*/attestations/certificateIdentity", "owner": "libops-devsecops"}, + {"path": "/applications/*/images/*/attestations/builderCommit", "owner": "libops-devsecops"}, {"path": "/applications/*/images/*/attestations/callerWorkflowRef", "owner": "libops-devsecops"}, {"path": "/applications/*/images/*/attestations/sbom/predicateType", "owner": "libops-devsecops"}, {"path": "/applications/*/images/*/attestations/sbom/platforms/*", "owner": "libops-devsecops"}, diff --git a/.github/compatibility/platform-release.schema.json b/.github/compatibility/platform-release.schema.json index 5941006..5f3b8e2 100644 --- a/.github/compatibility/platform-release.schema.json +++ b/.github/compatibility/platform-release.schema.json @@ -172,11 +172,15 @@ "attestations": { "type": "object", "additionalProperties": false, - "required": ["certificateIdentity", "callerWorkflowRef", "sbom", "provenance"], + "required": ["certificateIdentity", "builderCommit", "callerWorkflowRef", "sbom", "provenance"], "properties": { "certificateIdentity": { "type": "string", - "pattern": "^https://github\\.com/[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+/\\.github/workflows/build-push\\.ya?ml@[0-9a-f]{40}$" + "pattern": "^https://github\\.com/libops/\\.github/\\.github/workflows/build-push\\.yaml@refs/(heads|tags)/[A-Za-z0-9._/-]+$" + }, + "builderCommit": { + "type": "string", + "pattern": "^[0-9a-f]{40}$" }, "callerWorkflowRef": { "type": "string", diff --git a/ci/github/test_managed_refs.py b/ci/github/test_managed_refs.py index c9ad09b..ec2ec12 100644 --- a/ci/github/test_managed_refs.py +++ b/ci/github/test_managed_refs.py @@ -1,4 +1,7 @@ +import json import re +import subprocess +import tempfile import unittest from pathlib import Path @@ -29,6 +32,61 @@ def test_libops_actions_and_workflows_follow_managed_channels(self) -> None: "record the resolved commit as generated evidence instead", ) + def test_release_manifest_separates_managed_identity_from_exact_builder(self) -> None: + fixture = REPOSITORY_ROOT / "ci/github/testdata/platform-release.valid.json" + manifest = json.loads(fixture.read_text()) + attestations = manifest["platformImages"][0]["image"]["attestations"] + self.assertEqual( + attestations["certificateIdentity"], + ( + "https://github.com/libops/.github/.github/workflows/" + "build-push.yaml@refs/heads/main" + ), + ) + self.assertRegex(attestations["builderCommit"], r"^[0-9a-f]{40}$") + self.assert_validator_accepts(manifest) + + attestations["builderCommit"] = "refs/heads/main" + result = self.run_validator(manifest) + self.assertNotEqual(result.returncode, 0) + self.assertIn("builderCommit must bind the exact resolved", result.stderr) + + def test_release_manifest_rejects_sha_pinned_managed_certificate_identity(self) -> None: + fixture = REPOSITORY_ROOT / "ci/github/testdata/platform-release.valid.json" + manifest = json.loads(fixture.read_text()) + manifest["platformImages"][0]["image"]["attestations"]["certificateIdentity"] = ( + "https://github.com/libops/.github/.github/workflows/build-push.yaml@" + "1" * 40 + ) + result = self.run_validator(manifest) + self.assertNotEqual(result.returncode, 0) + self.assertIn("must bind a managed shared-publisher ref", result.stderr) + + def assert_validator_accepts(self, manifest: dict[str, object]) -> None: + result = self.run_validator(manifest) + self.assertEqual(result.returncode, 0, result.stderr) + + def run_validator(self, manifest: dict[str, object]) -> subprocess.CompletedProcess[str]: + with tempfile.NamedTemporaryFile(mode="w", suffix=".json") as candidate: + json.dump(manifest, candidate) + candidate.flush() + return subprocess.run( + [ + "node", + str( + REPOSITORY_ROOT + / ".github/actions/validate-platform-compatibility/validate.mjs" + ), + "--schema", + str(REPOSITORY_ROOT / ".github/compatibility/platform-release.schema.json"), + "--owners", + str(REPOSITORY_ROOT / ".github/compatibility/platform-release.owners.json"), + candidate.name, + ], + check=False, + capture_output=True, + text=True, + ) + if __name__ == "__main__": unittest.main() diff --git a/ci/github/testdata/platform-release.valid.json b/ci/github/testdata/platform-release.valid.json index 208b399..a138c67 100644 --- a/ci/github/testdata/platform-release.valid.json +++ b/ci/github/testdata/platform-release.valid.json @@ -6,23 +6,23 @@ "commit": "2222222222222222222222222222222222222222" }, "platformImages": [ - {"component":"api","image":{"service":"api","reference":"ghcr.io/libops/api:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/api","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@3333333333333333333333333333333333333333","callerWorkflowRef":"libops/api/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/api/actions/runs/200"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/api/actions/runs/300"}}},"contractTestRun":"https://github.com/libops/api/actions/runs/400"}, - {"component":"api-init","image":{"service":"api-init","reference":"ghcr.io/libops/api-init:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/api","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@3333333333333333333333333333333333333333","callerWorkflowRef":"libops/api/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/api/actions/runs/201"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/api/actions/runs/301"}}},"contractTestRun":"https://github.com/libops/api/actions/runs/401"}, - {"component":"api-vault-agent","image":{"service":"api-vault-agent","reference":"ghcr.io/libops/api-vault-agent:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/api","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@3333333333333333333333333333333333333333","callerWorkflowRef":"libops/api/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/api/actions/runs/202"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/api/actions/runs/302"}}},"contractTestRun":"https://github.com/libops/api/actions/runs/402"}, - {"component":"cli-sandbox","image":{"service":"cli-sandbox","reference":"ghcr.io/libops/cli-sandbox:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/cli-sandbox","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@3333333333333333333333333333333333333333","callerWorkflowRef":"libops/cli-sandbox/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/cli-sandbox/actions/runs/203"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/cli-sandbox/actions/runs/303"}}},"contractTestRun":"https://github.com/libops/cli-sandbox/actions/runs/403"}, - {"component":"control-plane","image":{"service":"control-plane","reference":"ghcr.io/libops/control-plane:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/api","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@3333333333333333333333333333333333333333","callerWorkflowRef":"libops/api/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/api/actions/runs/204"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/api/actions/runs/304"}}},"contractTestRun":"https://github.com/libops/api/actions/runs/404"}, - {"component":"controller-ingress","image":{"service":"controller-ingress","reference":"ghcr.io/libops/controller-ingress:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/api","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@3333333333333333333333333333333333333333","callerWorkflowRef":"libops/api/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/api/actions/runs/205"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/api/actions/runs/305"}}},"contractTestRun":"https://github.com/libops/api/actions/runs/405"}, - {"component":"edge-controller","image":{"service":"edge-controller","reference":"ghcr.io/libops/edge-controller:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/api","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@3333333333333333333333333333333333333333","callerWorkflowRef":"libops/api/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/api/actions/runs/206"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/api/actions/runs/306"}}},"contractTestRun":"https://github.com/libops/api/actions/runs/406"}, - {"component":"edge-provider-mutator","image":{"service":"edge-provider-mutator","reference":"ghcr.io/libops/edge-provider-mutator:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/api","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@3333333333333333333333333333333333333333","callerWorkflowRef":"libops/api/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/api/actions/runs/207"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/api/actions/runs/307"}}},"contractTestRun":"https://github.com/libops/api/actions/runs/407"}, - {"component":"gcp-vm-ip-controller","image":{"service":"gcp-vm-ip-controller","reference":"ghcr.io/libops/gcp-vm-ip-controller:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/api","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@3333333333333333333333333333333333333333","callerWorkflowRef":"libops/api/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/api/actions/runs/208"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/api/actions/runs/308"}}},"contractTestRun":"https://github.com/libops/api/actions/runs/408"}, - {"component":"ppb","image":{"service":"ppb","reference":"ghcr.io/libops/ppb:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/ppb","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@3333333333333333333333333333333333333333","callerWorkflowRef":"libops/ppb/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/ppb/actions/runs/209"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/ppb/actions/runs/309"}}},"contractTestRun":"https://github.com/libops/ppb/actions/runs/409"}, - {"component":"site-controller","image":{"service":"site-controller","reference":"ghcr.io/libops/site-controller:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/api","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@3333333333333333333333333333333333333333","callerWorkflowRef":"libops/api/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/api/actions/runs/210"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/api/actions/runs/310"}}},"contractTestRun":"https://github.com/libops/api/actions/runs/410"}, - {"component":"site-router","image":{"service":"site-router","reference":"ghcr.io/libops/site-router:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/api","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@3333333333333333333333333333333333333333","callerWorkflowRef":"libops/api/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/api/actions/runs/211"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/api/actions/runs/311"}}},"contractTestRun":"https://github.com/libops/api/actions/runs/411"}, - {"component":"task-agent-model-gateway","image":{"service":"task-agent-ollama-glm-5-2-cloud","reference":"ghcr.io/libops/task-agent-ollama-glm-5-2-cloud:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/api","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@3333333333333333333333333333333333333333","callerWorkflowRef":"libops/api/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/api/actions/runs/212"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/api/actions/runs/312"}}},"contractTestRun":"https://github.com/libops/api/actions/runs/412"}, - {"component":"terraform-runner","image":{"service":"terraform-runner","reference":"ghcr.io/libops/terraform-runner:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/api","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@3333333333333333333333333333333333333333","callerWorkflowRef":"libops/api/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/api/actions/runs/213"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/api/actions/runs/313"}}},"contractTestRun":"https://github.com/libops/api/actions/runs/413"}, - {"component":"vault-init","image":{"service":"vault-init","reference":"ghcr.io/libops/vault-init:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/vault-init","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@3333333333333333333333333333333333333333","callerWorkflowRef":"libops/vault-init/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/vault-init/actions/runs/214"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/vault-init/actions/runs/314"}}},"contractTestRun":"https://github.com/libops/vault-init/actions/runs/414"}, - {"component":"vault-proxy","image":{"service":"vault-proxy","reference":"ghcr.io/libops/vault-proxy:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/vault-proxy","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@3333333333333333333333333333333333333333","callerWorkflowRef":"libops/vault-proxy/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/vault-proxy/actions/runs/215"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/vault-proxy/actions/runs/315"}}},"contractTestRun":"https://github.com/libops/vault-proxy/actions/runs/415"}, - {"component":"vault-server","image":{"service":"vault-server","reference":"ghcr.io/libops/vault-server:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/terraform-vault-cloudrun","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@3333333333333333333333333333333333333333","callerWorkflowRef":"libops/terraform-vault-cloudrun/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/terraform-vault-cloudrun/actions/runs/216"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/terraform-vault-cloudrun/actions/runs/316"}}},"contractTestRun":"https://github.com/libops/terraform-vault-cloudrun/actions/runs/416"} + {"component":"api","image":{"service":"api","reference":"ghcr.io/libops/api:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/api","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@refs/heads/main","builderCommit":"3333333333333333333333333333333333333333","callerWorkflowRef":"libops/api/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/api/actions/runs/200"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/api/actions/runs/300"}}},"contractTestRun":"https://github.com/libops/api/actions/runs/400"}, + {"component":"api-init","image":{"service":"api-init","reference":"ghcr.io/libops/api-init:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/api","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@refs/heads/main","builderCommit":"3333333333333333333333333333333333333333","callerWorkflowRef":"libops/api/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/api/actions/runs/201"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/api/actions/runs/301"}}},"contractTestRun":"https://github.com/libops/api/actions/runs/401"}, + {"component":"api-vault-agent","image":{"service":"api-vault-agent","reference":"ghcr.io/libops/api-vault-agent:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/api","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@refs/heads/main","builderCommit":"3333333333333333333333333333333333333333","callerWorkflowRef":"libops/api/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/api/actions/runs/202"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/api/actions/runs/302"}}},"contractTestRun":"https://github.com/libops/api/actions/runs/402"}, + {"component":"cli-sandbox","image":{"service":"cli-sandbox","reference":"ghcr.io/libops/cli-sandbox:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/cli-sandbox","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@refs/heads/main","builderCommit":"3333333333333333333333333333333333333333","callerWorkflowRef":"libops/cli-sandbox/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/cli-sandbox/actions/runs/203"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/cli-sandbox/actions/runs/303"}}},"contractTestRun":"https://github.com/libops/cli-sandbox/actions/runs/403"}, + {"component":"control-plane","image":{"service":"control-plane","reference":"ghcr.io/libops/control-plane:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/api","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@refs/heads/main","builderCommit":"3333333333333333333333333333333333333333","callerWorkflowRef":"libops/api/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/api/actions/runs/204"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/api/actions/runs/304"}}},"contractTestRun":"https://github.com/libops/api/actions/runs/404"}, + {"component":"controller-ingress","image":{"service":"controller-ingress","reference":"ghcr.io/libops/controller-ingress:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/api","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@refs/heads/main","builderCommit":"3333333333333333333333333333333333333333","callerWorkflowRef":"libops/api/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/api/actions/runs/205"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/api/actions/runs/305"}}},"contractTestRun":"https://github.com/libops/api/actions/runs/405"}, + {"component":"edge-controller","image":{"service":"edge-controller","reference":"ghcr.io/libops/edge-controller:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/api","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@refs/heads/main","builderCommit":"3333333333333333333333333333333333333333","callerWorkflowRef":"libops/api/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/api/actions/runs/206"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/api/actions/runs/306"}}},"contractTestRun":"https://github.com/libops/api/actions/runs/406"}, + {"component":"edge-provider-mutator","image":{"service":"edge-provider-mutator","reference":"ghcr.io/libops/edge-provider-mutator:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/api","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@refs/heads/main","builderCommit":"3333333333333333333333333333333333333333","callerWorkflowRef":"libops/api/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/api/actions/runs/207"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/api/actions/runs/307"}}},"contractTestRun":"https://github.com/libops/api/actions/runs/407"}, + {"component":"gcp-vm-ip-controller","image":{"service":"gcp-vm-ip-controller","reference":"ghcr.io/libops/gcp-vm-ip-controller:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/api","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@refs/heads/main","builderCommit":"3333333333333333333333333333333333333333","callerWorkflowRef":"libops/api/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/api/actions/runs/208"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/api/actions/runs/308"}}},"contractTestRun":"https://github.com/libops/api/actions/runs/408"}, + {"component":"ppb","image":{"service":"ppb","reference":"ghcr.io/libops/ppb:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/ppb","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@refs/heads/main","builderCommit":"3333333333333333333333333333333333333333","callerWorkflowRef":"libops/ppb/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/ppb/actions/runs/209"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/ppb/actions/runs/309"}}},"contractTestRun":"https://github.com/libops/ppb/actions/runs/409"}, + {"component":"site-controller","image":{"service":"site-controller","reference":"ghcr.io/libops/site-controller:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/api","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@refs/heads/main","builderCommit":"3333333333333333333333333333333333333333","callerWorkflowRef":"libops/api/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/api/actions/runs/210"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/api/actions/runs/310"}}},"contractTestRun":"https://github.com/libops/api/actions/runs/410"}, + {"component":"site-router","image":{"service":"site-router","reference":"ghcr.io/libops/site-router:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/api","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@refs/heads/main","builderCommit":"3333333333333333333333333333333333333333","callerWorkflowRef":"libops/api/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/api/actions/runs/211"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/api/actions/runs/311"}}},"contractTestRun":"https://github.com/libops/api/actions/runs/411"}, + {"component":"task-agent-model-gateway","image":{"service":"task-agent-ollama-glm-5-2-cloud","reference":"ghcr.io/libops/task-agent-ollama-glm-5-2-cloud:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/api","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@refs/heads/main","builderCommit":"3333333333333333333333333333333333333333","callerWorkflowRef":"libops/api/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/api/actions/runs/212"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/api/actions/runs/312"}}},"contractTestRun":"https://github.com/libops/api/actions/runs/412"}, + {"component":"terraform-runner","image":{"service":"terraform-runner","reference":"ghcr.io/libops/terraform-runner:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/api","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@refs/heads/main","builderCommit":"3333333333333333333333333333333333333333","callerWorkflowRef":"libops/api/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/api/actions/runs/213"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/api/actions/runs/313"}}},"contractTestRun":"https://github.com/libops/api/actions/runs/413"}, + {"component":"vault-init","image":{"service":"vault-init","reference":"ghcr.io/libops/vault-init:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/vault-init","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@refs/heads/main","builderCommit":"3333333333333333333333333333333333333333","callerWorkflowRef":"libops/vault-init/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/vault-init/actions/runs/214"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/vault-init/actions/runs/314"}}},"contractTestRun":"https://github.com/libops/vault-init/actions/runs/414"}, + {"component":"vault-proxy","image":{"service":"vault-proxy","reference":"ghcr.io/libops/vault-proxy:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/vault-proxy","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@refs/heads/main","builderCommit":"3333333333333333333333333333333333333333","callerWorkflowRef":"libops/vault-proxy/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/vault-proxy/actions/runs/215"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/vault-proxy/actions/runs/315"}}},"contractTestRun":"https://github.com/libops/vault-proxy/actions/runs/415"}, + {"component":"vault-server","image":{"service":"vault-server","reference":"ghcr.io/libops/vault-server:2026.8@sha256:4444444444444444444444444444444444444444444444444444444444444444","source":{"repository":"https://github.com/libops/terraform-vault-cloudrun","commit":"2222222222222222222222222222222222222222"},"attestations":{"certificateIdentity":"https://github.com/libops/.github/.github/workflows/build-push.yaml@refs/heads/main","builderCommit":"3333333333333333333333333333333333333333","callerWorkflowRef":"libops/terraform-vault-cloudrun/.github/workflows/build.yml@refs/heads/main","sbom":{"predicateType":"https://spdx.dev/Document","platforms":["linux/amd64","linux/arm64"],"verificationRun":"https://github.com/libops/terraform-vault-cloudrun/actions/runs/216"},"provenance":{"predicateType":"https://slsa.dev/provenance/v1","verificationRun":"https://github.com/libops/terraform-vault-cloudrun/actions/runs/316"}}},"contractTestRun":"https://github.com/libops/terraform-vault-cloudrun/actions/runs/416"} ], "skillsBundle": { "source": { @@ -81,7 +81,8 @@ "commit": "2222222222222222222222222222222222222222" }, "attestations": { - "certificateIdentity": "https://github.com/libops/.github/.github/workflows/build-push.yaml@3333333333333333333333333333333333333333", + "certificateIdentity": "https://github.com/libops/.github/.github/workflows/build-push.yaml@refs/heads/main", + "builderCommit": "3333333333333333333333333333333333333333", "callerWorkflowRef": "libops/archivesspace/.github/workflows/build.yml@refs/heads/main", "sbom": { "predicateType": "https://spdx.dev/Document",