Skip to content

Commit 81f9811

Browse files
committed
fix: add the missing provenance asset links to the reports
Signed-off-by: behnazh-w <[email protected]>
1 parent d995156 commit 81f9811

File tree

5 files changed

+36
-25
lines changed

5 files changed

+36
-25
lines changed

src/macaron/provenance/__init__.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,16 @@
22
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/.
33

44
"""This package contains the provenance tools for software components."""
5+
6+
from dataclasses import dataclass
7+
8+
from macaron.slsa_analyzer.provenance.intoto import InTotoPayload
9+
10+
11+
@dataclass(frozen=True)
12+
class ProvenanceAsset:
13+
"""This class exists to hold a provenance payload with the original asset's name and URL."""
14+
15+
payload: InTotoPayload
16+
name: str
17+
url: str

src/macaron/provenance/provenance_finder.py

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
import logging
77
import os
88
import tempfile
9-
from dataclasses import dataclass
109
from functools import partial
1110

1211
from packageurl import PackageURL
1312
from pydriller import Git
1413

1514
from macaron.artifact.local_artifact import get_local_artifact_hash
1615
from macaron.config.defaults import defaults
16+
from macaron.provenance import ProvenanceAsset
1717
from macaron.repo_finder.commit_finder import AbstractPurlType, determine_abstract_purl_type
1818
from macaron.repo_finder.repo_finder_deps_dev import DepsDevRepoFinder
1919
from macaron.repo_finder.repo_utils import get_repo_tags
@@ -30,7 +30,6 @@
3030
)
3131
from macaron.slsa_analyzer.package_registry.npm_registry import NPMAttestationAsset
3232
from macaron.slsa_analyzer.package_registry.pypi_registry import find_or_create_pypi_asset
33-
from macaron.slsa_analyzer.provenance.intoto import InTotoPayload
3433
from macaron.slsa_analyzer.provenance.intoto.errors import LoadIntotoAttestationError
3534
from macaron.slsa_analyzer.provenance.loader import load_provenance_payload
3635
from macaron.slsa_analyzer.provenance.slsa import SLSAProvenanceData
@@ -41,15 +40,6 @@
4140
logger: logging.Logger = logging.getLogger(__name__)
4241

4342

44-
@dataclass(frozen=True)
45-
class ProvenanceAsset:
46-
"""This class exists to hold a provenance payload with the original asset's name and URL."""
47-
48-
payload: InTotoPayload
49-
name: str
50-
url: str
51-
52-
5343
class ProvenanceFinder:
5444
"""This class is used to find and retrieve provenance files from supported registries."""
5545

src/macaron/slsa_analyzer/analyzer.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,9 +527,10 @@ def run_single(
527527
# Try to discover GitHub attestation for the target software component.
528528
artifact_hash = get_artifact_hash(parsed_purl, local_artifact_dirs, package_registries_info)
529529
if artifact_hash:
530-
provenance_payload = git_service.get_attestation_payload(
530+
provenance_asset = git_service.get_attestation(
531531
analyze_ctx.component.repository.full_name, artifact_hash
532532
)
533+
provenance_payload = provenance_asset.payload if provenance_asset else None
533534
if provenance_payload:
534535
try:
535536
provenance_repo_url, provenance_commit_digest = extract_repo_and_commit_from_provenance(

src/macaron/slsa_analyzer/git_service/api_client.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -648,8 +648,8 @@ def download_asset(self, url: str, download_path: str) -> bool:
648648

649649
return download_file_with_size_limit(url, headers, download_path, timeout, size_limit)
650650

651-
def get_attestation(self, full_name: str, artifact_hash: str) -> dict:
652-
"""Download and return the attestation associated with the passed artifact hash, if any.
651+
def get_attestation(self, full_name: str, artifact_hash: str) -> tuple[str | None, dict]:
652+
"""Download and return the attestation url and content associated with the passed artifact hash, if any.
653653
654654
Parameters
655655
----------
@@ -660,12 +660,14 @@ def get_attestation(self, full_name: str, artifact_hash: str) -> dict:
660660
661661
Returns
662662
-------
663-
dict
664-
The attestation data, or an empty dict if not found.
663+
tuple[str|None,dict]
664+
The attestation url and data, or None and an empty dict if not found.
665665
"""
666666
url = f"{GhAPIClient._REPO_END_POINT}/{full_name}/attestations/sha256:{artifact_hash}"
667667
response_data = send_get_http(url, self.headers)
668-
return response_data or {}
668+
if not response_data:
669+
return (None, {})
670+
return (url, response_data)
669671

670672

671673
def get_default_gh_client(access_token: str) -> GhAPIClient:

src/macaron/slsa_analyzer/git_service/github.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@
99
from macaron.config.global_config import global_config
1010
from macaron.errors import ConfigurationError, RepoCheckOutError
1111
from macaron.json_tools import json_extract
12+
from macaron.provenance import ProvenanceAsset
1213
from macaron.slsa_analyzer import git_url
1314
from macaron.slsa_analyzer.git_service.api_client import GhAPIClient, get_default_gh_client
1415
from macaron.slsa_analyzer.git_service.base_git_service import BaseGitService
15-
from macaron.slsa_analyzer.provenance.intoto import InTotoPayload, ValidateInTotoPayloadError, validate_intoto_payload
16+
from macaron.slsa_analyzer.provenance.intoto import ValidateInTotoPayloadError, validate_intoto_payload
1617
from macaron.slsa_analyzer.provenance.loader import decode_provenance
1718

1819
logger: logging.Logger = logging.getLogger(__name__)
@@ -96,7 +97,7 @@ def check_out_repo(self, git_obj: Git, branch: str, digest: str, offline_mode: b
9697

9798
return git_obj
9899

99-
def get_attestation_payload(self, repository_name: str, artifact_hash: str) -> InTotoPayload | None:
100+
def get_attestation(self, repository_name: str, artifact_hash: str) -> ProvenanceAsset | None:
100101
"""Get the GitHub attestation associated with the given PURL, or None if it cannot be found.
101102
102103
The schema of GitHub attestation can be found on the API page:
@@ -111,22 +112,26 @@ def get_attestation_payload(self, repository_name: str, artifact_hash: str) -> I
111112
112113
Returns
113114
-------
114-
InTotoPayload | None
115-
The attestation payload, if found.
115+
ProvenanceAsset | None
116+
The provenance asset, if found.
116117
"""
117-
git_attestation_dict = self.api_client.get_attestation(repository_name, artifact_hash)
118+
attestation_url, git_attestation_dict = self.api_client.get_attestation(repository_name, artifact_hash)
118119

119-
if not git_attestation_dict:
120+
if not attestation_url or not git_attestation_dict:
120121
return None
121122

122123
git_attestation_list = json_extract(git_attestation_dict, ["attestations"], list)
123124
if not git_attestation_list:
124125
return None
125126

126127
payload = decode_provenance(git_attestation_list[0])
127-
128+
validated_payload = None
128129
try:
129-
return validate_intoto_payload(payload)
130+
validated_payload = validate_intoto_payload(payload)
130131
except ValidateInTotoPayloadError as error:
131132
logger.debug("Invalid attestation payload: %s", error)
132133
return None
134+
if not validated_payload:
135+
return None
136+
137+
return ProvenanceAsset(validated_payload, artifact_hash, attestation_url)

0 commit comments

Comments
 (0)