Skip to content

Commit 95453c8

Browse files
authored
feat: add a script to check VSA (#858)
This PR adds the check_vsa.sh script, which takes an artifact, VSA, and the package URL as the artifact identifier and reports whether the verification result has been successful. This PR also adds a tutorial for the VSAs published for the Graal Development Kit (GDK) artifacts. The integration test checks [email protected] with a manually generated VSA as well as [email protected] whose VSA is published on Oracle Maven. Signed-off-by: behnazh-w <[email protected]>
1 parent c9752b3 commit 95453c8

File tree

13 files changed

+485
-16
lines changed

13 files changed

+485
-16
lines changed

docs/source/index.rst

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -50,43 +50,43 @@ the requirements that are currently supported by Macaron.
5050
:widths: 20 40 40
5151
:header-rows: 1
5252

53-
* - SLSA level
53+
* - Check ID
5454
- SLSA requirement
5555
- Concrete check
56-
* - 1
56+
* - ``mcn_build_script_1``
5757
- **Scripted build** - All build steps were fully defined in a “build script”.
5858
- Identify and validate build script(s).
59-
* - 1
59+
* - ``mcn_provenance_available_1``
6060
- **Provenance available** - Provenances are available.
6161
- Check for existence of provenances, which can be :term:`SLSA` or :term:`Witness` provenances. If there is no provenance, the repo can still be compliant to level 1 given the build script is available.
62-
* - 1
62+
* - ``mcn_provenance_witness_level_one_1``
6363
- **Witness provenance** - One or more :term:`Witness` provenances are discovered.
6464
- Check for existence of :term:`Witness` provenances, and whether artifact digests match those in the provenances.
65-
* - 2
65+
* - ``mcn_build_service_1``
6666
- **Build service** - All build steps are run using some build service (e.g. GitHub Actions)
6767
- Identify and validate the CI service(s) used for the build process.
68-
* - 2+
68+
* - ``mcn_provenance_verified_1``
6969
- **Provenance verified** - Provenance is available and verified.
7070
- See :doc:`SLSA Build Levels </pages/checks/slsa_builds>`
71-
* - 3
71+
* - ``mcn_trusted_builder_level_three_1``
7272
- **Trusted builders** - Guarantees the identification of the top-level build configuration used to initiate the build. The build is verified to be hermetic, isolated, parameterless, and executed in an ephemeral environment.
7373
- Identify and validate that the builder used in the CI pipeline is a trusted one.
74-
* - 3
74+
* - ``mcn_build_as_code_1``
7575
- **Build as code** - If a trusted builder is not present, this requirement determines that the build definition and configuration executed by the build service is verifiably derived from text file definitions stored in a version control system.
7676
- Identify and validate the CI service(s) used to build and deploy/publish an artifact.
77-
* - 3
77+
* - ``mcn_infer_artifact_pipeline_1``
7878
- **Infer artifact publish pipeline** - When a provenance is not available, checks whether a CI workflow run has automatically published the artifact.
7979
- Identify a workflow run that has triggered the deploy step determined by the ``Build as code`` check.
80-
* - 3
80+
* - ``mcn_provenance_level_three_1``
8181
- **Provenance Level three** - Check whether the target has SLSA provenance level 3.
8282
- Use the `slsa-verifier <https://github.com/slsa-framework/slsa-verifier>`_ to attest to the subjects in the SLSA provenance that accompanies an artifact.
83-
* - 3
83+
* - ``mcn_provenance_expectation_1``
8484
- **Provenance expectation** - Check if the provenance meets an expectation.
85-
- The user can provide an expectation for the provenance as a CUE policy, which will be compared against the SLSA provenance.
86-
* - 3
85+
- The user can provide an expectation for the provenance as a CUE expectation file, which will be compared against the provenance.
86+
* - ``mcn_provenance_derived_repo_1``
8787
- **Provenance derived repo** - Check if the analysis target's repository matches the repository in the provenance.
8888
- If there is no provenance, this check will fail.
89-
* - 3
89+
* - ``mcn_provenance_derived_commit_1``
9090
- **Provenance derived commit** - Check if the analysis target's commit matches the commit in the provenance.
9191
- If there is no commit, this check will fail.
9292

@@ -98,9 +98,9 @@ Macaron checks that report integrity issues but do not map to SLSA requirements
9898
:widths: 20 40
9999
:header-rows: 1
100100

101-
* - Check name
101+
* - Check ID
102102
- Description
103-
* - Detect malicious metadata
103+
* - ``mcn_detect_malicious_metadata_1``
104104
- This check analyzes the metadata of a package and reports malicious behavior. This check currently supports PyPI packages.
105105

106106
----------------------

docs/source/pages/tutorials/generate_verification_summary_attestation.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
.. Copyright (c) 2024 - 2024, 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
4+
.. _gen-vsa_tutorial:
5+
46
=========================================
57
Generate Verification Summary Attestation
68
=========================================

docs/source/pages/tutorials/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ For the full list of supported technologies, such as CI services, registries, an
2222
npm_provenance
2323
detect_malicious_java_dep
2424
generate_verification_summary_attestation
25+
use_verification_summary_attestation
2526
exclude_include_checks
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
.. Copyright (c) 2024 - 2024, 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+
============================================
5+
How to use Verification Summary Attestations
6+
============================================
7+
8+
This tutorial explains how to use the `Verification Summary Attestations (VSA) <https://slsa.dev/spec/v1.0/verification_summary>`_ generated by Macaron, using the VSAs for the `Graal Development Kit (GDK) <https://graal.cloud/gdk/>`_ artifacts as an example.
9+
10+
For more information about VSAs, please refer to the :ref:`Verification Summary Attestation page<vsa>`. To use Macaron to generate VSAs see this :ref:`tutorial <gen-vsa_tutorial>`.
11+
12+
.. contents:: :local:
13+
14+
--------
15+
Use case
16+
--------
17+
18+
Imagine you are a consumer of GDK artifacts and want to verify whether they are produced by a secure, :term:`SLSA`-compliant build service and sourced from a trusted source code repository. You need to confirm whether a provenance record for this artifact is published and has been verified. The GDK team must keep the details of their build pipeline confidential while still communicating that verification has occurred.
19+
20+
A VSA allows you to assess the security properties of an artifact without needing direct access to the provenance details. This process involves delegating the policy decision to Macaron. Macaron receives the provenance of the build as input, analyzes various aspects of the build, and verifies the gathered data against a Datalog policy. It then generates a VSA that is published alongside the artifacts, attesting to the artifacts produced by the build.
21+
22+
-------
23+
Example
24+
-------
25+
26+
GDK is an Oracle build of the open source Micronaut® framework. GDK provides a curated set of Micronaut framework modules which are built from source and published on the `Oracle Maven repository <https://maven.oracle.com/public>`_. If a GDK artifact is verified by Macaron, you should be able to to find a corresponding VSA on Oracle Maven repository. Let's consider, the ``io.micronaut/[email protected]`` JAR artifact which is published at `<https://maven.oracle.com/public/io/micronaut/micronaut-core/4.6.5-oracle-00001/micronaut-core-4.6.5-oracle-00001.jar>`_. In order to verify the artifact with Macaron, you can follow the following steps:
27+
28+
''''''''''''''''
29+
Download the VSA
30+
''''''''''''''''
31+
32+
Check wether a VSA is published for the artifact and download it for further examination.
33+
34+
.. code-block:: shell
35+
36+
curl -O https://maven.oracle.com/public/io/micronaut/micronaut-core/4.6.5-oracle-00001/vsa.intoto.jsonl
37+
38+
''''''''''''''''''''''''''''''''''''
39+
Manual inspection of the VSA content
40+
''''''''''''''''''''''''''''''''''''
41+
42+
.. code-block:: shell
43+
44+
cat vsa.intoto.jsonl | jq -r '.payload' | base64 -d | jq
45+
46+
The output of the this command should look like below:
47+
48+
.. toggle::
49+
50+
.. code-block:: json
51+
52+
{
53+
"_type": "https://in-toto.io/Statement/v1",
54+
"subject": [
55+
{
56+
"uri": "pkg:maven/io.micronaut/[email protected]?type=jar",
57+
"digest": {
58+
"sha256": "685644ae52ed580030550c7e4f441f39df2741c45095f1cf93583bddc413e6f8"
59+
}
60+
},
61+
{
62+
"uri": "pkg:maven/io.micronaut/[email protected]?type=pom",
63+
"digest": {
64+
"sha256": "64ba60107cdf5a93bec28b73f33585b93635f1fe6ae0707e6c8b42ed2d7d5198"
65+
}
66+
},
67+
{
68+
"uri": "pkg:maven/io.micronaut/[email protected]?type=java-source",
69+
"digest": {
70+
"sha256": "bcfcdb0213868100ca421f341411a5d5bc98ecb5cf44186804d27a4a34906818"
71+
}
72+
},
73+
{
74+
"uri": "pkg:maven/io.micronaut/[email protected]?type=javadoc",
75+
"digest": {
76+
"sha256": "33f720a21faad105f2566944a2e49b198eb310a1f9cfaa7742fdae8f46677e46"
77+
}
78+
}
79+
],
80+
"predicateType": "https://slsa.dev/verification_summary/v1",
81+
"predicate": {
82+
"verifier": {
83+
"id": "https://github.com/oracle/macaron",
84+
"version": {
85+
"macaron": "0.10.0"
86+
}
87+
},
88+
"timeVerified": "2024-09-10T06:35:56.559568+00:00",
89+
"resourceUri": "pkg:maven/io.micronaut/[email protected]",
90+
"policy": {
91+
"content": "#include \"prelude.dl\"\n\nPolicy(\"gdk_provenance_policy\", component_id, \"Policy for GDK builds\") :-\n check_passed(component_id, \"mcn_provenance_expectation_1\").\n\napply_policy_to(\"gdk_provenance_policy\", component_id) :-\n is_component(component_id, purl),\n match(\"^pkg:maven/io.micronaut/micronaut-core@.*$\", purl)."
92+
},
93+
"verificationResult": "PASSED",
94+
"verifiedLevels": []
95+
}
96+
}
97+
98+
99+
The VSA adheres to the `schema <https://slsa.dev/spec/v1.0/verification_summary>`_ provided by SLSA. However, rather than specifying a URI for the policy, it includes the policy directly within the VSA under the ``predicate.policy.content`` field. The VSA also includes the list of subjects and their corresponding checksums that have been verified, the version of Macaron used, the timestamp of the verification, and the result of the verification.
100+
101+
Here is a pretty-printed version of the policy as it appears in the VSA, along with its description.
102+
103+
.. toggle::
104+
105+
.. code-block:: prolog
106+
107+
#include "prelude.dl"
108+
109+
Policy("gdk_provenance_policy", component_id, "Policy for GDK builds") :-
110+
check_passed(component_id, "mcn_provenance_expectation_1")
111+
112+
apply_policy_to("gdk_provenance_policy", component_id) :-
113+
is_component(component_id, purl),
114+
match("^pkg:maven/io.micronaut/micronaut-core@.*$", purl).
115+
116+
This policy makes sure the :ref:`mcn_provenance_expectation_1 <checks>` check, which verifies the content of the provenance file matches a :ref:`CUE expectation <pages/using:Verifying provenance expectations in CUE language>`.
117+
118+
* Policy prelude (``#include "prelude.dl"``): Copies all the pre-written rules and the generated fact import statements into the policy program. All user-written policy files must begin with ``#include "prelude.dl"``.
119+
120+
* Policy Validation (``Policy``): This rule ensures that the component satisfies the ``mcn_provenance_expectation_1`` check.
121+
122+
* Applying the Policy (``apply_policy_to``): To apply the ``gcn_provenance_policy``, Macaron first determines if the ``component_id`` is a valid component and if its ``PURL`` conforms to the pattern defined in the ``match`` predicate. If both conditions are met, the policy is applied.
123+
124+
* The template Datalog policy file can be downloaded from `here <https://github.com/oracle/macaron/tree/main/src/macaron/resources/policies/gdk/policy.dl.template>`_
125+
126+
Below you can find the template CUE file that has been used by the :ref:`mcn_provenance_expectation_1 <checks>` check at verification time to verify the provenance. It contains place holders for expected values that are populated by the GDK maintainers.
127+
128+
.. code-block:: javascript
129+
130+
{
131+
target: "<EXPECTATION_PURL>",
132+
predicate: {
133+
attestations: [
134+
{
135+
attestation: {
136+
jobimage: "<IMAGE-NAME>",
137+
projecturl: "https://<REPO_URL>",
138+
},
139+
},
140+
]
141+
}
142+
}
143+
144+
145+
* ``target: "<EXPECTATION_PURL>"``: This specifies the software component that is verified. ``<EXPECTATION_PURL>`` is a placeholder for the actual PURL (Package URL) of the target component, e.g., ``pkg:maven/io.micronaut/micronaut-core``.
146+
147+
* ``jobimage: "<IMAGE-NAME>"``: This condition checks that the ``jobimage`` attribute matches a specific pattern. ``<IMAGE-NAME>`` is a placeholder for the actual image name used at build time, e.g., ``container-registry.oracle.com/os/oraclelinux:9-slim``.
148+
149+
* ``projecturl: "https://<REPO_URL>"``: This checks that the ``projecturl`` attribute exactly matches the expected Repository URL. ``<REPO_URL>`` is a placeholder for the actual repository URL, e.g., ``internal.repo.com/micronaut-projects/micronaut-core``.
150+
151+
* The template CUE expectation can be downloaded from `this location <https://github.com/oracle/macaron/tree/main/src/macaron/resources/policies/gdk/expectation.cue.template>`_.
152+
153+
154+
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
155+
Automatically check the artifact checksum and verification result
156+
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
157+
158+
To verify that the artifact checksum matches the subject listed in the VSA and that the verification process has passed, follow these steps:
159+
160+
+++++++++++++
161+
Prerequisites
162+
+++++++++++++
163+
164+
Before running the script, ensure that the following tools are installed and available on your system’s PATH:
165+
166+
* ``bash``: This script has been tested with ``bash 5.1.16(1)-release``.
167+
* ``curl``
168+
* ``jq``
169+
* ``shasum``
170+
* ``awk``
171+
172+
++++++++++++++++++++++++++++++++
173+
Download the check_vsa.sh script
174+
++++++++++++++++++++++++++++++++
175+
176+
.. code-block:: shell
177+
178+
curl -O https://raw.githubusercontent.com/oracle/macaron/main/scripts/release_scripts/check_vsa.sh
179+
180+
++++++++++++++++++++++++++
181+
Make the script executable
182+
++++++++++++++++++++++++++
183+
184+
.. code-block:: shell
185+
186+
chmod +x check_vsa.sh
187+
188+
+++++++++++++++++++++++++++++++++++++++++++++
189+
Run the script with the appropriate arguments
190+
+++++++++++++++++++++++++++++++++++++++++++++
191+
192+
Following our example, let’s verify that the VSA has passed for the artifact available at `<https://maven.oracle.com/public/io/micronaut/micronaut-core/4.6.5-oracle-00001/micronaut-core-4.6.5-oracle-00001.jar>`_. You can either download the JAR from the repository or, if you have built the GDK project, obtain the artifact from your local Maven repository at ``~/.m2/repository/io/micronaut/micronaut-core/4.6.5-oracle-00001/micronaut-core-4.6.5-oracle-00001.jar``. Then, run the following command:
193+
194+
.. code-block:: shell
195+
196+
./check_vsa.sh --artifact-path micronaut-core-4.6.5-oracle-00001.jar --vsa-path vsa.intoto.jsonl --purl "pkg:maven/io.micronaut/[email protected]?type=jar"
197+
198+
The artifact and VSA paths should be valid paths on your filesystem. Ensure you replace ``micronaut-core-4.6.5-oracle-00001.jar``, ``vsa.intoto.jsonl``, and ``pkg:maven/io.micronaut/[email protected]?type=jar`` with your actual file paths and package URL.
199+
200+
+++++++++++++++++
201+
Verify the output
202+
+++++++++++++++++
203+
204+
If the verification is successful, the script will print:
205+
206+
.. code-block:: shell
207+
208+
PASSED
209+
210+
If there is an issue, the script will return an error code ``1`` and print an appropriate error message.

0 commit comments

Comments
 (0)