Skip to content

Commit ad103cf

Browse files
authored
feat: prepare Macaron GitHub Action to publish on GitHub Marketplace (#1259)
Prepare Macaron for publishing on GitHub Action Marketplace, and add the documentation. Signed-off-by: Demolus13 <[email protected]>
1 parent d6627df commit ad103cf

File tree

9 files changed

+255
-39
lines changed

9 files changed

+255
-39
lines changed

.github/workflows/test_macaron_action.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ jobs:
184184
package_url: pkg:maven/io.github.behnazh-w.demo/[email protected]?type=jar
185185
repo_path: https://github.com/behnazh-w/example-maven-app
186186
output_dir: macaron_output/detect_malicious_java_dep
187-
sbom_path: ./resources/detect_malicious_java_dep/example-sbom.json
187+
sbom_path: ./tests/tutorial_resources/detect_malicious_java_dep/example-sbom.json
188188
deps_depth: '1'
189189

190190
- name: Run Macaron (verify policy - detect-malicious-upload)

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,27 @@
44

55
![Macaron](./docs/source/assets/macaron.svg)
66

7-
[Full Documentation](https://oracle.github.io/macaron/index.html) | [Tutorials](https://oracle.github.io/macaron/pages/tutorials/index.html) | [Videos](https://www.youtube.com/watch?v=ebo0kGKP6bw) | [Papers](#publications) | [Presentations](#presentations)
7+
[Full Documentation](https://oracle.github.io/macaron/index.html) | [Tutorials](https://oracle.github.io/macaron/pages/tutorials/index.html) | [Videos](https://www.youtube.com/watch?v=ebo0kGKP6bw) | [Papers](#publications) | [Presentations](#presentations) | [Macaron GitHub Action](https://oracle.github.io/macaron/pages/macaron_action.html)
88

99

1010
**Macaron** is a software supply chain security analysis tool from Oracle Labs focused on verifying the **build integrity** of artifacts and their dependencies. It helps developers, security teams, and researchers ensure that packages are built as expected and have not been tampered with.
1111

12+
Use Macaron as a GitHub Action
13+
14+
To use the Macaron GitHub Action, add the following step to your workflow (adjust the version as needed). In this example, we use an example policy. For detailed instructions and a comprehensive list of available options, please refer to the [Macaron GitHub Action documentation](https://oracle.github.io/macaron/pages/macaron_action.html).
15+
16+
```yaml
17+
- uses: oracle/[email protected]
18+
with:
19+
repo_path: 'https://github.com/example/project'
20+
policy_file: check-github-actions
21+
policy_purl: 'pkg:github.com/example/project'
22+
output_dir: 'macaron-output'
23+
upload_attestation: true
24+
```
25+
26+
For detailed instructions and a comprehensive list of available options, please refer to the [Macaron GitHub Action documentation](https://oracle.github.io/macaron/pages/macaron_action.html).
27+
1228
## Key Capabilities
1329
1430
Macaron supports:

action.yaml

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -58,28 +58,13 @@ outputs:
5858
runs:
5959
using: composite
6060
steps:
61-
- name: Setup Python
62-
uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
63-
with:
64-
python-version: 3.11.14
65-
66-
- name: Setup Go
67-
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
68-
with:
69-
go-version: '1.23'
70-
cache: false
71-
72-
- name: Setup JDK
73-
uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4.4.0
74-
with:
75-
java-version: '17'
76-
distribution: oracle
77-
7861
- name: Setup Macaron
79-
# Create or reuse a Python virtualenv with the macaron CLI and export the `MACARON` binary path via `$GITHUB_ENV` so later steps can use it.
62+
# Create or reuse run_macaron.sh script
8063
run: |
8164
bash "$GITHUB_ACTION_PATH/scripts/actions/setup_macaron.sh"
8265
shell: bash
66+
env:
67+
ACTION_REF: ${{ github.action_ref }}
8368

8469
- name: Run Macaron Analysis
8570
id: run-macaron-analysis

docs/source/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ intermediate representations as abstractions. Using such abstractions, Macaron i
121121
pages/installation
122122
pages/using
123123
pages/cli_usage/index
124+
pages/macaron_action
124125
pages/tutorials/index
125126
pages/output_files
126127
pages/checks/slsa_builds
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
Macaron GitHub Action
2+
=====================
3+
4+
Overview
5+
--------
6+
7+
This document describes the composite GitHub Action defined in ``action.yaml`` at the repository root. The action uses the Macaron CLI to run supply-chain security analysis and policy verification from a GitHub Actions workflow.
8+
9+
Quick usage
10+
-----------
11+
12+
When using this action you can reference the action in your workflow. Example:
13+
14+
.. code-block:: yaml
15+
16+
jobs:
17+
analyze:
18+
runs-on: ubuntu-latest
19+
steps:
20+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
21+
- name: Run Macaron Security Analysis
22+
uses: oracle/[email protected]
23+
with:
24+
repo_path: 'https://github.com/example/project'
25+
policy_file: check-github-actions
26+
policy_purl: 'pkg:github.com/example/project'
27+
output_dir: 'macaron-output'
28+
upload_attestation: true
29+
30+
Example: policy verification only
31+
----------------------------------
32+
33+
To run only the policy verification step (when you already have an output
34+
database), call the action with ``policy_file`` and set ``output_dir`` to the
35+
directory containing ``macaron.db``:
36+
37+
.. code-block:: yaml
38+
39+
- name: Verify policy
40+
uses: oracle/[email protected]
41+
with:
42+
policy_file: policy.dl
43+
output_dir: macaron-output
44+
upload_attestation: true
45+
46+
Inputs
47+
------
48+
The action exposes a number of inputs which map directly to Macaron CLI
49+
options. Key inputs are listed below (see ``action.yaml`` for the full list):
50+
51+
.. list-table::
52+
:header-rows: 1
53+
:widths: 20 60 20
54+
55+
* - Input
56+
- Description
57+
- Default
58+
* - ``repo_path``
59+
- The path or URL of the repository to analyze.
60+
-
61+
* - ``package_url``
62+
- A PURL identifying a package to analyze instead of a repository.
63+
-
64+
* - ``sbom_path``
65+
- Path to an SBOM file to analyze.
66+
-
67+
* - ``python_venv``
68+
- Path to an existing Python virtualenv (used when analyzing Python
69+
packages).
70+
-
71+
* - ``defaults_path``
72+
- Path to a Macaron defaults configuration file.
73+
-
74+
* - ``policy_file``
75+
- Path to a Datalog policy file for policy verification.
76+
-
77+
* - ``policy_purl``
78+
- PURL for a pre-defined policy to use with verification.
79+
-
80+
* - ``branch`` / ``digest``
81+
- Checkout options when analyzing a repository (branch name or commit
82+
digest).
83+
-
84+
* - ``provenance_expectation``
85+
- The path to provenance expectation file or directory.
86+
-
87+
* - ``provenance_file``
88+
- The path to the provenance file in in-toto format.
89+
-
90+
* - ``deps_depth``
91+
- Dependency resolution depth (how many levels of transitive dependencies
92+
to resolve).
93+
- ``0``
94+
* - ``show_prelude``
95+
- Shows the Datalog prelude for the database.
96+
-
97+
* - ``github_token``
98+
- Token used by Macaron to access GitHub (for cloning, API access,
99+
etc.).
100+
- ``${{ github.token }}``
101+
* - ``output_dir``
102+
- Directory where Macaron writes results (database, reports, artifacts).
103+
- ``output``
104+
* - ``upload_attestation``
105+
- When ``true``, the action will attempt to upload a generated
106+
verification attestation (VSA) after policy verification.
107+
- ``false``
108+
* - ``subject_path``
109+
- Path to the artifact serving as the subject of the attestation.
110+
- ``${{ github.workspace }}``
111+
112+
Outputs
113+
-------
114+
115+
The composite action exposes the following outputs (set by the
116+
``run_macaron_policy_verification.sh`` script when applicable):
117+
118+
.. list-table::
119+
:header-rows: 1
120+
:widths: 20 70
121+
122+
* - Output
123+
- Description
124+
* - ``policy_report``
125+
- Path to the generated policy report JSON file produced by
126+
``macaron verify-policy``. This file contains the policy evaluation
127+
results.
128+
* - ``vsa_report``
129+
- Path to the generated VSA (Verification Summary Attestation) in
130+
`in-toto <https://in-toto.io/>`_ JSONL format. If no VSA was produced
131+
during verification, the action emits the string ``"VSA Not Generated."``
132+
instead of a path.
133+
134+
Default Policies
135+
----------------
136+
137+
Macaron provides policy templates to run pre-defined policies:
138+
139+
.. list-table::
140+
:header-rows: 1
141+
:widths: 20 60 20
142+
143+
* - Policy name
144+
- Description
145+
- Template
146+
* - ``check-github-actions``
147+
- Detects whether a component was built using GitHub Actions that
148+
are known to be vulnerable or otherwise unsafe. The policy
149+
evaluates a check named `mcn_githubactions_vulnerabilities_1` and
150+
reports a passed/failed result for the component when applied.
151+
- `check-github-actions template <https://github.com/oracle/macaron/blob/main/src/macaron/resources/policies/datalog/check-github-actions.dl.template>`_
152+
* - ``malware-detection``
153+
- Checks a component for indicators of malicious or suspicious content.
154+
The policy evaluates a check named mcn_detect_malicious_metadata_1
155+
and reports a passed/failed result for the component when applied.
156+
- `malware-detection template <https://github.com/oracle/macaron/blob/main/src/macaron/resources/policies/datalog/malware-detection.dl.template>`_
157+
* - ``malware-detection-dependencies``
158+
- Checks the component and its transitive dependencies for indicators
159+
of malicious or suspicious content. The policy ensures the component
160+
and each dependency pass the `mcn_detect_malicious_metadata_1` check.
161+
- `malware-detection-dependencies template <https://github.com/oracle/macaron/blob/main/src/macaron/resources/policies/datalog/malware-detection-dependencies.dl.template>`_
162+
163+
How the action works
164+
--------------------
165+
166+
1. ``Setup Macaron``: downloads ``run_macaron.sh`` script to install and run macaron in the action.
167+
168+
2. ``Run Macaron Analysis``: calls ``scripts/actions/run_macaron_analysis.sh``
169+
which assembles the ``macaron analyze`` command from the inputs and runs
170+
it. Results are written into ``output_dir``.
171+
172+
3. ``Run Macaron Policy Verification``: if a policy file or PURL is supplied,
173+
the corresponding script runs ``macaron verify-policy`` against the
174+
analysis database and writes ``policy_report`` and ``vsa_report`` to
175+
``$GITHUB_OUTPUT`` when produced.

scripts/actions/run_macaron_analysis.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ else
1919
fi
2020

2121
OUTPUT_DIR=${OUTPUT_DIR:-output}
22-
CMD="$CMD --output-dir ${OUTPUT_DIR} -lr . analyze"
22+
CMD="$CMD --output ${OUTPUT_DIR} -lr . analyze"
2323

2424
if [ -n "${REPO_PATH:-}" ]; then
2525
CMD="$CMD -rp ${REPO_PATH}"

scripts/actions/run_macaron_policy_verification.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ if [ -n "$DEFAULTS_PATH" ]; then
2525
else
2626
CMD="$MACARON"
2727
fi
28-
CMD="$CMD --output-dir ${OUTPUT_DIR} verify-policy --database ${OUTPUT_DIR}/macaron.db"
28+
CMD="$CMD --output ${OUTPUT_DIR} verify-policy --database ${OUTPUT_DIR}/macaron.db"
2929

3030
if [ -n "$FILE" ] && [ -f "$FILE" ]; then
3131
CMD="$CMD --file $FILE"

scripts/actions/setup_macaron.sh

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,65 @@
44
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/.
55
set -euo pipefail
66

7-
# Setup Macaron virtualenv and make available via GitHub Actions environment files.
8-
# This script writes `MACARON=<path>` to `$GITHUB_ENV` so later steps can invoke the macaron CLI, and appends the venv `bin` directory to `$GITHUB_PATH`.
9-
107
MACARON_DIR="${RUNNER_TEMP:-/tmp}/macaron"
11-
VENV_MACARON="$MACARON_DIR/.venv/bin/macaron"
12-
138
mkdir -p "$MACARON_DIR"
149

15-
if [ -x "$VENV_MACARON" ]; then
16-
echo "Using macaron from existing venv: $VENV_MACARON"
17-
echo "MACARON=$VENV_MACARON" >> "$GITHUB_ENV"
18-
echo "$MACARON_DIR/.venv/bin" >> "$GITHUB_PATH"
19-
exit 0
10+
ACTION_DIR="${RUNNER_TEMP:-/tmp}/macaron-action"
11+
rm -rf "$ACTION_DIR"
12+
mkdir -p "$ACTION_DIR"
13+
14+
git clone --filter=blob:none --no-checkout https://github.com/oracle/macaron.git "$ACTION_DIR"
15+
16+
TARGET_REF="${ACTION_REF:-main}"
17+
MACARON_IMAGE_TAG=""
18+
cd "$ACTION_DIR"
19+
if [[ "$TARGET_REF" =~ ^[0-9a-f]{40}$ ]]; then
20+
# Check for tags pointing directly at the SHA.
21+
tags=$(git tag --points-at "$TARGET_REF")
22+
if [[ -n "$tags" ]]; then
23+
# Get the first tag (main or first one listed)
24+
MACARON_IMAGE_TAG="$(echo "$tags" | head -n1)"
25+
echo "SHA $TARGET_REF maps to exact tag: $MACARON_IMAGE_TAG"
26+
else
27+
# Search all tags that contain the commit (could be ancestor).
28+
history_tags=$(git tag --contains "$TARGET_REF")
29+
if [[ -n "$history_tags" ]]; then
30+
MACARON_IMAGE_TAG="$(echo "$history_tags" | head -n1)"
31+
echo "SHA $TARGET_REF is contained in tag: $MACARON_IMAGE_TAG"
32+
else
33+
echo "No tag found for SHA $TARGET_REF. Defaulting to 'latest'."
34+
MACARON_IMAGE_TAG="latest"
35+
fi
36+
fi
37+
elif [[ "$TARGET_REF" =~ ^v[0-9] ]]; then
38+
MACARON_IMAGE_TAG="$TARGET_REF"
39+
echo "Ref is a direct tag: $MACARON_IMAGE_TAG"
40+
else
41+
echo "Using 'latest' image."
42+
MACARON_IMAGE_TAG="latest"
2043
fi
2144

2245
cd "$MACARON_DIR"
23-
git clone https://github.com/oracle/macaron.git .
24-
make venv
25-
export PATH="$MACARON_DIR/.venv/bin:$PATH"
26-
make setup
27-
echo "MACARON=$VENV_MACARON" >> "$GITHUB_ENV"
28-
echo "$MACARON_DIR/.venv/bin" >> "$GITHUB_PATH"
46+
47+
# Download image using macaron_image_tag else latest release
48+
if [ "${MACARON_IMAGE_TAG}" != "latest" ]; then
49+
echo "MACARON_IMAGE_TAG detected: ${MACARON_IMAGE_TAG}"
50+
URL="https://raw.githubusercontent.com/oracle/macaron/refs/tags/${MACARON_IMAGE_TAG}/scripts/release_scripts/run_macaron.sh"
51+
SCRIPT_NAME="run_macaron_${MACARON_IMAGE_TAG}.sh"
52+
else
53+
echo "Using default latest release."
54+
URL="https://raw.githubusercontent.com/oracle/macaron/release/scripts/release_scripts/run_macaron.sh"
55+
SCRIPT_NAME="run_macaron.sh"
56+
fi
57+
58+
# Get the run_macaron.sh script
59+
if [ ! -f "$SCRIPT_NAME" ]; then
60+
echo "Downloading $SCRIPT_NAME from: $URL"
61+
curl -fSL -o "$SCRIPT_NAME" "$URL"
62+
else
63+
echo "$SCRIPT_NAME already exists, skipping download."
64+
fi
65+
66+
chmod +x "$SCRIPT_NAME"
67+
echo "MACARON=$MACARON_DIR/$SCRIPT_NAME" >> "$GITHUB_ENV"
68+
echo "MACARON_IMAGE_TAG=${MACARON_IMAGE_TAG}" >> "$GITHUB_ENV"

src/macaron/resources/policies/datalog/malware-detection.dl.template

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
Policy("check-component", component_id, "Check component artifacts.") :-
44
check_passed(component_id, "mcn_detect_malicious_metadata_1").
55

6-
76
apply_policy_to("check-component", component_id) :-
87
is_component(component_id, purl),
98
match("<PACKAGE_PURL>", purl).

0 commit comments

Comments
 (0)