diff --git a/src/macaron/repo_finder/provenance_extractor.py b/src/macaron/repo_finder/provenance_extractor.py index c327154ab..2d32bead0 100644 --- a/src/macaron/repo_finder/provenance_extractor.py +++ b/src/macaron/repo_finder/provenance_extractor.py @@ -132,36 +132,44 @@ def _extract_from_slsa_v1(payload: InTotoV1Payload) -> tuple[str | None, str | N return None, None # Extract the repository URL. - repo = None - if build_type == "https://slsa-framework.github.io/gcb-buildtypes/triggered-build/v1": - repo = json_extract(build_def, ["externalParameters", "sourceToBuild", "repository"], str) - if not repo: - repo = json_extract(build_def, ["externalParameters", "configSource", "repository"], str) - if build_type == "https://slsa-framework.github.io/github-actions-buildtypes/workflow/v1": - repo = json_extract(build_def, ["externalParameters", "workflow", "repository"], str) + match build_type: + case "https://slsa-framework.github.io/gcb-buildtypes/triggered-build/v1": + repo = json_extract(build_def, ["externalParameters", "sourceToBuild", "repository"], str) + if not repo: + repo = json_extract(build_def, ["externalParameters", "configSource", "repository"], str) + case "https://slsa-framework.github.io/github-actions-buildtypes/workflow/v1": + repo = json_extract(build_def, ["externalParameters", "workflow", "repository"], str) + case "https://github.com/oracle/macaron/tree/main/src/macaron/resources/provenance-buildtypes/oci/v1": + repo = json_extract(build_def, ["externalParameters", "source"], str) + case _: + logger.debug("Unsupported build type for SLSA v1: %s", build_type) + return None, None if not repo: - logger.debug("Repo required to extract commit from SLSA v1.") + logger.debug("Repo URL not found in SLSA v1 payload.") return None, None # Extract the commit hash. commit = None - deps = json_extract(build_def, ["resolvedDependencies"], list) - if not deps: - return repo, None - for dep in deps: - if not isinstance(dep, dict): - continue - uri = json_extract(dep, ["uri"], str) - if not uri: - continue - url = _clean_spdx(uri) - if url != repo: - continue - digest_set = json_extract(dep, ["digest"], dict) - if not digest_set: - continue - commit = _extract_commit_from_digest_set(digest_set, SLSA_V1_DIGEST_SET_GIT_ALGORITHMS) + if build_type == "https://github.com/oracle/macaron/tree/main/src/macaron/resources/provenance-buildtypes/oci/v1": + commit = json_extract(build_def, ["internalParameters", "buildEnvVar", "BLD_COMMIT_HASH"], str) + else: + deps = json_extract(build_def, ["resolvedDependencies"], list) + if not deps: + return repo, None + for dep in deps: + if not isinstance(dep, dict): + continue + uri = json_extract(dep, ["uri"], str) + if not uri: + continue + url = _clean_spdx(uri) + if url != repo: + continue + digest_set = json_extract(dep, ["digest"], dict) + if not digest_set: + continue + commit = _extract_commit_from_digest_set(digest_set, SLSA_V1_DIGEST_SET_GIT_ALGORITHMS) return repo, commit or None diff --git a/tests/repo_finder/test_provenance_extractor.py b/tests/repo_finder/test_provenance_extractor.py index 704aaaa8f..0fc2460ef 100644 --- a/tests/repo_finder/test_provenance_extractor.py +++ b/tests/repo_finder/test_provenance_extractor.py @@ -113,6 +113,40 @@ def slsa_v1_github_provenance_() -> dict[str, JsonType]: ) +@pytest.fixture(name="slsa_v1_oci_provenance") +def slsa_v1_oci_provenance_() -> dict[str, JsonType]: + """Return a valid SLSA v1 provenance using the OCI build type.""" + payload = _load_and_validate_json( + """ + { + "_type": "https://in-toto.io/Statement/v1", + "predicateType": "https://slsa.dev/provenance/v1", + "subject": [], + "predicate": { + "buildDefinition": { + "buildType": "", + "externalParameters": { + "source": "https://github.com/oracle/macaron" + }, + "internalParameters": { + "buildEnvVar": { + "BLD_COMMIT_HASH": "51aa22a42ec1bffa71518041a6a6d42d40bf50f0" + } + } + } + } + } + """ + ) + # The build type is modified here to avoid issues with excessive line length. + _json_modify( + payload, + ["predicate", "buildDefinition", "buildType"], + "https://github.com/oracle/macaron/tree/main/src/macaron/resources/provenance-buildtypes/oci/v1", + ) + return payload + + @pytest.fixture(name="slsa_v02_provenance") def slsa_v02_provenance_() -> dict[str, JsonType]: """Return a valid SLSA v02 provenance.""" @@ -322,6 +356,28 @@ def test_slsa_v1_github_is_invalid( _test_extract_repo_and_commit_from_provenance(slsa_v1_github_provenance) +def test_slsa_v1_oci_is_valid( + slsa_v1_oci_provenance: dict[str, JsonType], target_repository: str, target_commit: str +) -> None: + """Test SLSA v1 oci provenance.""" + _test_extract_repo_and_commit_from_provenance(slsa_v1_oci_provenance, target_repository, target_commit) + + +@pytest.mark.parametrize( + ("keys", "new_value"), + [ + (["predicate", "buildDefinition", "externalParameters", "source"], ""), + (["predicate", "buildDefinition", "externalParameters", "source"], None), + ], +) +def test_slsa_v1_oci_is_invalid( + slsa_v1_oci_provenance: dict[str, JsonType], keys: list[str], new_value: JsonType +) -> None: + """Test invalidly modified SLSA v1 oci provenance.""" + _json_modify(slsa_v1_oci_provenance, keys, new_value) + _test_extract_repo_and_commit_from_provenance(slsa_v1_oci_provenance) + + def test_slsa_v02_is_valid( slsa_v02_provenance: dict[str, JsonType], target_repository: str, target_commit: str ) -> None: