Skip to content

Commit 2ab8ee2

Browse files
committed
chore: refactor level 3 provenance check
Signed-off-by: Ben Selwyn-Smith <[email protected]>
1 parent 65f9325 commit 2ab8ee2

26 files changed

+648
-716
lines changed

docs/source/pages/developers_guide/apidoc/macaron.repo_finder.rst

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,6 @@ macaron.repo\_finder.commit\_finder module
1717
:undoc-members:
1818
:show-inheritance:
1919

20-
macaron.repo\_finder.provenance\_extractor module
21-
-------------------------------------------------
22-
23-
.. automodule:: macaron.repo_finder.provenance_extractor
24-
:members:
25-
:undoc-members:
26-
:show-inheritance:
27-
28-
macaron.repo\_finder.provenance\_finder module
29-
----------------------------------------------
30-
31-
.. automodule:: macaron.repo_finder.provenance_finder
32-
:members:
33-
:undoc-members:
34-
:show-inheritance:
35-
3620
macaron.repo\_finder.repo\_finder module
3721
----------------------------------------
3822

docs/source/pages/developers_guide/apidoc/macaron.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Subpackages
2020
macaron.output_reporter
2121
macaron.parsers
2222
macaron.policy_engine
23+
macaron.provenance
2324
macaron.repo_finder
2425
macaron.repo_verifier
2526
macaron.slsa_analyzer

src/macaron/database/db_custom_types.py

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2023 - 2024, Oracle and/or its affiliates. All rights reserved.
1+
# Copyright (c) 2023 - 2025, Oracle and/or its affiliates. All rights reserved.
22
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/.
33

44
"""This module implements SQLAlchemy type for converting date format to RFC3339 string representation."""
@@ -8,6 +8,8 @@
88

99
from sqlalchemy import JSON, String, TypeDecorator
1010

11+
from macaron.slsa_analyzer.provenance.intoto import InTotoPayload, validate_intoto_payload
12+
1113

1214
class RFC3339DateTime(TypeDecorator): # pylint: disable=W0223
1315
"""
@@ -36,7 +38,7 @@ def process_bind_param(self, value: None | Any, dialect: Any) -> None | str:
3638
if the provided ``datetime`` is a naive ``datetime`` object then UTC is added.
3739
3840
value: None | datetime.datetime
39-
The value being stored
41+
The value being stored.
4042
"""
4143
if value is None:
4244
return None
@@ -52,7 +54,7 @@ def process_result_value(self, value: None | str, dialect: Any) -> None | dateti
5254
If the deserialized ``datetime`` has a timezone then return it, otherwise add UTC as its timezone.
5355
5456
value: None | str
55-
The value being loaded
57+
The value being loaded.
5658
"""
5759
if value is None:
5860
return None
@@ -76,7 +78,7 @@ def process_bind_param(self, value: None | dict, dialect: Any) -> None | dict:
7678
"""Process when storing a dict object to the SQLite db.
7779
7880
value: None | dict
79-
The value being stored
81+
The value being stored.
8082
"""
8183
if not isinstance(value, dict):
8284
raise TypeError("DBJsonDict type expects a dict.")
@@ -87,8 +89,47 @@ def process_result_value(self, value: None | dict, dialect: Any) -> None | dict:
8789
"""Process when loading a dict object from the SQLite db.
8890
8991
value: None | dict
90-
The value being loaded
92+
The value being loaded.
9193
"""
9294
if not isinstance(value, dict):
9395
raise TypeError("DBJsonDict type expects a dict.")
9496
return value
97+
98+
99+
class ProvenancePayload(TypeDecorator): # pylint: disable=W0223
100+
"""SQLAlchemy column type to serialize InTotoProvenance."""
101+
102+
# It is stored in the database as a json value.
103+
impl = JSON
104+
105+
# To prevent Sphinx from rendering the docstrings for `cache_ok`, make this docstring private.
106+
#: :meta private:
107+
cache_ok = True
108+
109+
def process_bind_param(self, value: None | InTotoPayload, dialect: Any) -> None | Any:
110+
"""Process when storing a dict object to the SQLite db.
111+
112+
value: None | InTotoPayload
113+
The value being stored.
114+
"""
115+
if value is None:
116+
return None
117+
118+
if not isinstance(value, InTotoPayload):
119+
raise TypeError("ProvenancePayload type expects an InTotoPayload.")
120+
121+
return value.statement.get("payload")
122+
123+
def process_result_value(self, value: None | dict, dialect: Any) -> None | InTotoPayload:
124+
"""Process when loading a dict object from the SQLite db.
125+
126+
value: None | dict
127+
The value being loaded.
128+
"""
129+
if value is None:
130+
return None
131+
132+
if not isinstance(value, dict):
133+
raise TypeError("ProvenancePayload type expects a dict.")
134+
135+
return validate_intoto_payload(value)

src/macaron/database/table_definitions.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2023 - 2024, Oracle and/or its affiliates. All rights reserved.
1+
# Copyright (c) 2023 - 2025, Oracle and/or its affiliates. All rights reserved.
22
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/.
33

44
"""
@@ -34,7 +34,7 @@
3434

3535
from macaron.artifact.maven import MavenSubjectPURLMatcher
3636
from macaron.database.database_manager import ORMBase
37-
from macaron.database.db_custom_types import RFC3339DateTime
37+
from macaron.database.db_custom_types import ProvenancePayload, RFC3339DateTime
3838
from macaron.errors import InvalidPURLError
3939
from macaron.slsa_analyzer.provenance.intoto import InTotoPayload, ProvenanceSubjectPURLMatcher
4040
from macaron.slsa_analyzer.slsa_req import ReqName
@@ -481,14 +481,26 @@ class Provenance(ORMBase):
481481
#: The SLSA version.
482482
version: Mapped[str] = mapped_column(String, nullable=False)
483483

484+
#: The SLSA level.
485+
slsa_level: Mapped[int] = mapped_column(Integer, default=0)
486+
484487
#: The release tag commit sha.
485488
release_commit_sha: Mapped[str] = mapped_column(String, nullable=True)
486489

487490
#: The release tag.
488491
release_tag: Mapped[str] = mapped_column(String, nullable=True)
489492

490-
#: The provenance payload content in JSON format.
491-
provenance_json: Mapped[str] = mapped_column(String, nullable=False)
493+
#: The repository URL from the provenance.
494+
repository_url: Mapped[str] = mapped_column(String, nullable=True)
495+
496+
#: The commit sha from the provenance.
497+
commit_sha: Mapped[str] = mapped_column(String, nullable=True)
498+
499+
#: The provenance payload.
500+
provenance_payload: Mapped[InTotoPayload] = mapped_column(ProvenancePayload, nullable=False)
501+
502+
#: The verified status of the provenance.
503+
verified: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
492504

493505
#: A one-to-many relationship with the release artifacts.
494506
artifact: Mapped[list["ReleaseArtifact"]] = relationship(back_populates="provenance")

src/macaron/provenance/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Copyright (c) 2024 - 2025, Oracle and/or its affiliates. All rights reserved.
2+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/.
3+
4+
"""This package contains the provenance tools for software components."""

src/macaron/repo_finder/provenance_extractor.py renamed to src/macaron/provenance/provenance_extractor.py

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2024 - 2024, Oracle and/or its affiliates. All rights reserved.
1+
# Copyright (c) 2024 - 2025, Oracle and/or its affiliates. All rights reserved.
22
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/.
33

44
"""This module contains methods for extracting repository and commit metadata from provenance files."""
@@ -7,16 +7,11 @@
77
from abc import ABC, abstractmethod
88

99
from packageurl import PackageURL
10-
from pydriller import Git
1110

1211
from macaron.errors import ProvenanceError
1312
from macaron.json_tools import JsonType, json_extract
1413
from macaron.repo_finder import to_domain_from_known_purl_types
15-
from macaron.repo_finder.commit_finder import (
16-
AbstractPurlType,
17-
determine_abstract_purl_type,
18-
extract_commit_from_version,
19-
)
14+
from macaron.repo_finder.commit_finder import AbstractPurlType, determine_abstract_purl_type
2015
from macaron.slsa_analyzer.provenance.intoto import InTotoPayload, InTotoV1Payload, InTotoV01Payload
2116
from macaron.slsa_analyzer.provenance.intoto.v01 import InTotoV01Statement
2217
from macaron.slsa_analyzer.provenance.intoto.v1 import InTotoV1Statement
@@ -278,27 +273,18 @@ def check_if_input_repo_provenance_conflict(
278273

279274

280275
def check_if_input_purl_provenance_conflict(
281-
git_obj: Git,
282276
repo_path_input: bool,
283-
digest_input: bool,
284277
provenance_repo_url: str | None,
285-
provenance_commit_digest: str | None,
286278
purl: PackageURL,
287279
) -> bool:
288280
"""Test if the input repository type PURL's repo and commit match the contents of the provenance.
289281
290282
Parameters
291283
----------
292-
git_obj: Git
293-
The Git object.
294284
repo_path_input: bool
295285
True if there is a repo as input.
296-
digest_input: str
297-
True if there is a commit as input.
298286
provenance_repo_url: str | None
299287
The repo url from provenance.
300-
provenance_commit_digest: str | None
301-
The commit digest from provenance.
302288
purl: PackageURL
303289
The input repository PURL.
304290
@@ -321,18 +307,6 @@ def check_if_input_purl_provenance_conflict(
321307
)
322308
return True
323309

324-
# Check the PURL commit against the provenance.
325-
if not digest_input and provenance_commit_digest and purl.version:
326-
purl_commit = extract_commit_from_version(git_obj, purl.version)
327-
if purl_commit and purl_commit != provenance_commit_digest:
328-
logger.debug(
329-
"The commit digest passed via purl input does not match what exists in the "
330-
"provenance. Purl Commit: %s, Provenance Commit: %s.",
331-
purl_commit,
332-
provenance_commit_digest,
333-
)
334-
return True
335-
336310
return False
337311

338312

0 commit comments

Comments
 (0)