Skip to content

Commit

Permalink
feat: use repository url provided as input for finding a commit (#622)
Browse files Browse the repository at this point in the history
This PR allows a user to provide to the command line: a repository URL with no digest alongside a PURL with a version.

Signed-off-by: Ben Selwyn-Smith <[email protected]>
  • Loading branch information
benmss authored Feb 9, 2024
1 parent 1feed17 commit 380c7d5
Show file tree
Hide file tree
Showing 4 changed files with 288 additions and 12 deletions.
12 changes: 9 additions & 3 deletions docs/source/pages/using.rst
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,19 @@ Run the analysis using the PURL string as follows:
./run_macaron.sh analyze -purl <purl_string>
You can also provide the PURL string together with the repository path. In this case, the PURL string will be used as the unique identifier for the analysis target:
You can also provide the PURL string together with the repository path. In this case, the PURL string will be used as the unique identifier for the analysis target. If providing a PURL with a version, providing the repository path as well is sufficient for analysis to take place. If providing a PURL without a version, the branch and digest must also be provided alongside the repository path. Examples of both use cases follow.

Analyzing a PURL (with an included version) and a repository path:

.. code-block:: shell
./run_macaron.sh analyze -purl <purl_string> -rp <repo_path> -b <branch> -d <digest>
./run_macaron.sh analyze -purl <purl_string_with_version> -rp <repo_path>
Analyzing a PURL (without an included version) and a repository path (with a digest and branch):

.. note:: When providing the PURL and the repository path, both the branch name and commit digest must be provided as well.
.. code-block:: shell
./run_macaron.sh analyze -purl <purl_string> -rp <repo_path> -b <branch> -d <digest>
''''''''''''''''''''''''''''''''''''''
Providing an artifact as a PURL string
Expand Down
9 changes: 9 additions & 0 deletions scripts/dev_scripts/integration_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,15 @@ $RUN_MACARON analyze -purl pkg:maven/com.google.guava/[email protected]?type=jar

check_or_update_expected_output $COMPARE_JSON_OUT $JSON_RESULT $JSON_EXPECTED || log_fail

echo -e "\n----------------------------------------------------------------------------------"
echo "org.tinymediamanager/tinyMediaManager: Analyzing the purl with a version, and a provided repo with no commit."
echo -e "----------------------------------------------------------------------------------\n"
JSON_EXPECTED=$WORKSPACE/tests/e2e/expected_results/purl/org_tinymediamanager/tinyMediaManager.json
JSON_RESULT=$WORKSPACE/output/reports/maven/org_tinymediamanager/tinyMediaManager/tinyMediaManager.json
$RUN_MACARON analyze -purl pkg:maven/org.tinymediamanager/[email protected] -rp https://gitlab.com/tinyMediaManager/tinyMediaManager --skip-deps || log_fail

check_or_update_expected_output $COMPARE_JSON_OUT $JSON_RESULT $JSON_EXPECTED || log_fail


# Running Macaron using local paths.
echo -e "\n=================================================================================="
Expand Down
26 changes: 17 additions & 9 deletions src/macaron/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from importlib import metadata as importlib_metadata

from jinja2 import Environment, FileSystemLoader, select_autoescape
from packageurl import PackageURL

import macaron
from macaron.config.defaults import create_defaults, load_defaults
Expand Down Expand Up @@ -92,15 +93,22 @@ def analyze_slsa_levels_single(analyzer_single_args: argparse.Namespace) -> None
branch = analyzer_single_args.branch
digest = analyzer_single_args.digest

if repo_path and purl and not digest:
# To provide the purl together with the repository path, the user must specify the branch and commit
# digest.
logger.error(
"Please provide the commit digest for the repo at %s that matches to the PURL string %s.",
repo_path,
purl,
)
sys.exit(os.EX_USAGE)
if repo_path and purl:
# To provide the purl together with the repository path, the user must specify the commit digest unless the
# purl has a version.
try:
purl_object = PackageURL.from_string(purl)
except ValueError as error:
logger.debug("Could not parse PURL: %s", error)
sys.exit(os.EX_USAGE)
if not (purl_object.version or digest):
logger.error(
"Please provide the commit digest for the repo at %s that matches to the PURL string %s. Or "
"include the version in the PURL",
repo_path,
purl,
)
sys.exit(os.EX_USAGE)

# We need to use empty strings when the input values are of None type. This is because this dictionary will be
# passed into the Configuration instance, where the existing values in Configuration.options are replaced by
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
{
"metadata": {
"timestamps": "2024-02-02 15:39:30",
"has_passing_check": true
},
"target": {
"info": {
"full_name": "pkg:maven/org.tinymediamanager/[email protected]",
"local_cloned_path": "git_repos/gitlab_com/tinyMediaManager/tinyMediaManager",
"remote_path": "https://gitlab.com/tinyMediaManager/tinyMediaManager",
"branch": null,
"commit_hash": "968745f6b9d592af053f0ef5610357435a0e3b5a",
"commit_date": "2023-08-19T11:27:15+00:00"
},
"provenances": {
"is_inferred": true,
"content": {
"gitlab_ci": [
{
"_type": "https://in-toto.io/Statement/v0.1",
"subject": [],
"predicateType": "https://slsa.dev/provenance/v0.2",
"predicate": {
"builder": {
"id": "<URI>"
},
"buildType": "<URI>",
"invocation": {
"configSource": {
"uri": "<URI>",
"digest": {
"sha1": "<STING>"
},
"entryPoint": "<STRING>"
},
"parameters": {},
"environment": {}
},
"buildConfig": {
"jobID": "<STRING>",
"stepID": "<STRING>"
},
"metadata": {
"buildInvocationId": "<STRING>",
"buildStartedOn": "<TIMESTAMP>",
"buildFinishedOn": "<TIMESTAMP>",
"completeness": {
"parameters": "false",
"environment": "false",
"materials": "false"
},
"reproducible": "false"
},
"materials": [
{
"uri": "<URI>",
"digest": {}
}
]
}
}
],
"Maven Central Registry": []
}
},
"checks": {
"summary": {
"DISABLED": 0,
"FAILED": 8,
"PASSED": 2,
"SKIPPED": 0,
"UNKNOWN": 0
},
"results": [
{
"check_id": "mcn_build_script_1",
"check_description": "Check if the target repo has a valid build script.",
"slsa_requirements": [
"Scripted Build - SLSA Level 1"
],
"justification": [
"The target repository uses build tool maven.",
"The target repository uses build tool docker."
],
"result_type": "PASSED"
},
{
"check_id": "mcn_version_control_system_1",
"check_description": "Check whether the target repo uses a version control system.",
"slsa_requirements": [
"Version controlled - SLSA Level 2"
],
"justification": [
{
"This is a Git repository": "https://gitlab.com/tinyMediaManager/tinyMediaManager"
}
],
"result_type": "PASSED"
},
{
"check_id": "mcn_build_as_code_1",
"check_description": "The build definition and configuration executed by the build service is verifiably derived from text file definitions stored in a version control system.",
"slsa_requirements": [
"Build as code - SLSA Level 3"
],
"justification": [
"The target repository does not use maven to deploy.",
"The target repository does not use docker to deploy."
],
"result_type": "FAILED"
},
{
"check_id": "mcn_build_service_1",
"check_description": "Check if the target repo has a valid build service.",
"slsa_requirements": [
"Build service - SLSA Level 2"
],
"justification": [
"The target repository does not have a build service for maven.",
"The target repository does not have a build service for docker.",
"The target repository does not have a build service for at least one build tool."
],
"result_type": "FAILED"
},
{
"check_id": "mcn_infer_artifact_pipeline_1",
"check_description": "Detects potential pipelines from which an artifact is published.",
"slsa_requirements": [
"Build as code - SLSA Level 3"
],
"justification": [
"Check mcn_infer_artifact_pipeline_1 is set to FAILED because mcn_build_as_code_1 FAILED."
],
"result_type": "FAILED"
},
{
"check_id": "mcn_provenance_available_1",
"check_description": "Check whether the target has intoto provenance.",
"slsa_requirements": [
"Provenance - Available - SLSA Level 1",
"Provenance content - Identifies build instructions - SLSA Level 1",
"Provenance content - Identifies artifacts - SLSA Level 1",
"Provenance content - Identifies builder - SLSA Level 1"
],
"justification": [
"Could not find any SLSA or Witness provenances."
],
"result_type": "FAILED"
},
{
"check_id": "mcn_provenance_expectation_1",
"check_description": "Check whether the SLSA provenance for the produced artifact conforms to the expected value.",
"slsa_requirements": [
"Provenance conforms with expectations - SLSA Level 3"
],
"justification": [
"Check mcn_provenance_expectation_1 is set to FAILED because mcn_provenance_available_1 FAILED."
],
"result_type": "FAILED"
},
{
"check_id": "mcn_provenance_level_three_1",
"check_description": "Check whether the target has SLSA provenance level 3.",
"slsa_requirements": [
"Provenance - Non falsifiable - SLSA Level 3",
"Provenance content - Includes all build parameters - SLSA Level 3",
"Provenance content - Identifies entry point - SLSA Level 3",
"Provenance content - Identifies source code - SLSA Level 2"
],
"justification": [
"Check mcn_provenance_level_three_1 is set to FAILED because mcn_provenance_available_1 FAILED."
],
"result_type": "FAILED"
},
{
"check_id": "mcn_provenance_witness_level_one_1",
"check_description": "Check whether the target has a level-1 witness provenance.",
"slsa_requirements": [
"Provenance - Available - SLSA Level 1",
"Provenance content - Identifies build instructions - SLSA Level 1",
"Provenance content - Identifies artifacts - SLSA Level 1",
"Provenance content - Identifies builder - SLSA Level 1"
],
"justification": [
"Check mcn_provenance_witness_level_one_1 is set to FAILED because mcn_provenance_available_1 FAILED."
],
"result_type": "FAILED"
},
{
"check_id": "mcn_trusted_builder_level_three_1",
"check_description": "Check whether the target uses a trusted SLSA level 3 builder.",
"slsa_requirements": [
"Hermetic - SLSA Level 4",
"Isolated - SLSA Level 3",
"Parameterless - SLSA Level 4",
"Ephemeral environment - SLSA Level 3"
],
"justification": [
"Could not find a trusted level 3 builder as a GitHub Actions workflow."
],
"result_type": "FAILED"
}
]
}
},
"dependencies": {
"analyzed_deps": 0,
"unique_dep_repos": 0,
"checks_summary": [
{
"check_id": "mcn_build_as_code_1",
"num_deps_pass": 0
},
{
"check_id": "mcn_build_script_1",
"num_deps_pass": 0
},
{
"check_id": "mcn_build_service_1",
"num_deps_pass": 0
},
{
"check_id": "mcn_infer_artifact_pipeline_1",
"num_deps_pass": 0
},
{
"check_id": "mcn_provenance_available_1",
"num_deps_pass": 0
},
{
"check_id": "mcn_provenance_level_three_1",
"num_deps_pass": 0
},
{
"check_id": "mcn_provenance_expectation_1",
"num_deps_pass": 0
},
{
"check_id": "mcn_provenance_witness_level_one_1",
"num_deps_pass": 0
},
{
"check_id": "mcn_trusted_builder_level_three_1",
"num_deps_pass": 0
},
{
"check_id": "mcn_version_control_system_1",
"num_deps_pass": 0
}
],
"dep_status": []
}
}

0 comments on commit 380c7d5

Please sign in to comment.