Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .github/workflows/sbom-diff-and-risk-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,14 @@ on:
- ".github/workflows/sbom-diff-and-risk-ci.yml"
- "tools/sbom-diff-and-risk/**"

env:
SBOM_DIFF_RISK_DIST_ARTIFACT_NAME: sbom-diff-and-risk-dist

jobs:
test:
runs-on: ubuntu-latest
permissions:
contents: read
defaults:
run:
working-directory: tools/sbom-diff-and-risk
Expand Down Expand Up @@ -49,3 +54,48 @@ jobs:
test -f "$tmpdir/report.md"
diff -u examples/sample-report.json "$tmpdir/report.json"
diff -u examples/sample-report.md "$tmpdir/report.md"

build-and-attest:
# Keep provenance publication on trusted non-PR runs so consumers verify
# workflow-produced wheel and sdist artifacts from this repository workflow.
if: github.event_name != 'pull_request'
needs: test
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
attestations: write
defaults:
run:
working-directory: tools/sbom-diff-and-risk
steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Upgrade pip
run: python -m pip install --upgrade pip

- name: Install build tooling
run: python -m pip install build

- name: Build distributable artifacts
run: python -m build

- name: Upload wheel and source distribution artifact
uses: actions/upload-artifact@v4
with:
name: ${{ env.SBOM_DIFF_RISK_DIST_ARTIFACT_NAME }}
path: |
tools/sbom-diff-and-risk/dist/*.whl
tools/sbom-diff-and-risk/dist/*.tar.gz
if-no-files-found: error

- name: Generate artifact attestation for built distributions
uses: actions/attest@v4
with:
subject-path: ${{ github.workspace }}/tools/sbom-diff-and-risk/dist/*
11 changes: 11 additions & 0 deletions tools/sbom-diff-and-risk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,17 @@ sbom-diff-risk compare \

For GitHub code scanning integration guidance and a minimal upload workflow, see [docs/github-code-scanning.md](D:/OneDrive/Code/scientific-computing-toolkit/tools/sbom-diff-and-risk/docs/github-code-scanning.md).

## Self-provenance

This repository also records provenance for `sbom-diff-and-risk` itself by generating GitHub artifact attestations for the wheel and source distribution produced by the `sbom-diff-and-risk-ci` workflow.

- the attested files are the wheel and source distribution built by `python -m build` from `tools/sbom-diff-and-risk`
- the build files are uploaded together as the `sbom-diff-and-risk-dist` workflow artifact
- only trusted non-PR runs publish the attestation
- consumers can verify provenance with GitHub's attestation tooling after downloading one of those artifacts
- this complements the tool's analysis of third-party supply-chain inputs, but it does not replace that analysis

See [docs/self-provenance.md](D:/OneDrive/Code/scientific-computing-toolkit/tools/sbom-diff-and-risk/docs/self-provenance.md) for the exact attested filenames, where the evidence appears in GitHub, and a run-by-run verification flow for consumers.
## Parser Boundaries

Deterministic local mode intentionally supports a conservative subset of packaging syntax. The detailed matrix lives in [docs/parser-boundaries.md](D:/OneDrive/Code/scientific-computing-toolkit/tools/sbom-diff-and-risk/docs/parser-boundaries.md).
Expand Down
100 changes: 100 additions & 0 deletions tools/sbom-diff-and-risk/docs/self-provenance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Self-provenance and artifact attestations

`sbom-diff-and-risk` analyzes third-party dependency changes, but consumers should also be able to verify where the tool itself came from. This repository generates GitHub artifact attestations for the packaged build outputs produced by the `sbom-diff-and-risk-ci` workflow.

## What is attested in this repository

The attested subjects are the exact Python distributables built from `tools/sbom-diff-and-risk` via `python -m build`:

- the wheel: `dist/sbom_diff_and_risk-<version>-py3-none-any.whl`
- the source distribution: `dist/sbom_diff_and_risk-<version>.tar.gz`

Those two files are uploaded together as the workflow artifact named `sbom-diff-and-risk-dist`. The attestation applies to the built files themselves, not just to the artifact bundle name shown in the Actions UI.

Current attestations cover workflow-built wheel and sdist artifacts, not GitHub Release assets or PyPI-published distributions.

## Workflow and permissions

The attestation is generated in `.github/workflows/sbom-diff-and-risk-ci.yml` by the `build-and-attest` job in the `sbom-diff-and-risk-ci` workflow.

That job runs only for trusted non-PR events in this repository:

- `push`
- `workflow_dispatch`

Pull request runs still execute the `test` job, but they do not publish artifact attestations.

The `build-and-attest` job uses the minimum explicit permissions required for GitHub-hosted build provenance:

- `contents: read` for repository checkout
- `id-token: write` for GitHub's signing identity
- `attestations: write` to publish the attestation

## Where provenance evidence appears in GitHub

After a successful non-PR run of `sbom-diff-and-risk-ci`, consumers can find the evidence in two useful places:

1. On the workflow run page:
- the uploaded artifact appears as `sbom-diff-and-risk-dist`
- this is the run consumers should use to confirm the workflow name, job name, and downloaded artifact bundle before verification
2. In the repository-wide attestations view:
- open **Actions**
- in the left sidebar, under **Management**, open **Attestations**
- search for `sbom_diff_and_risk-` or filter by recent creation date

On the **Attestations** page, the relevant subjects are the wheel and sdist filenames, not the workflow artifact bundle name. On the workflow run page, the main visible bundle name is still `sbom-diff-and-risk-dist`.

## Manual verification for one workflow run

Use this path after a merge to the default branch or an intentional `workflow_dispatch` run.

1. Open the repository's **Actions** tab.
2. Open a successful `sbom-diff-and-risk-ci` run triggered by `push` or `workflow_dispatch`.
3. Confirm that the `build-and-attest` job ran successfully.
4. Download the `sbom-diff-and-risk-dist` artifact from that run.
5. Confirm the downloaded archive contains exactly the expected build outputs for that version:
- `sbom_diff_and_risk-<version>-py3-none-any.whl`
- `sbom_diff_and_risk-<version>.tar.gz`
6. Verify one of the files with the GitHub CLI:

```bash
gh attestation verify path/to/sbom_diff_and_risk-<version>-py3-none-any.whl \
--repo OWNER/scientific-computing-toolkit \
--signer-workflow OWNER/scientific-computing-toolkit/.github/workflows/sbom-diff-and-risk-ci.yml
```

You can verify the source distribution the same way:

```bash
gh attestation verify path/to/sbom_diff_and_risk-<version>.tar.gz \
--repo OWNER/scientific-computing-toolkit \
--signer-workflow OWNER/scientific-computing-toolkit/.github/workflows/sbom-diff-and-risk-ci.yml
```

If you want more inspection detail during review, ask the CLI for structured output:

```bash
gh attestation verify path/to/sbom_diff_and_risk-<version>-py3-none-any.whl \
--repo OWNER/scientific-computing-toolkit \
--signer-workflow OWNER/scientific-computing-toolkit/.github/workflows/sbom-diff-and-risk-ci.yml \
--format json
```

A successful verification confirms that:

- the downloaded file matches an attested subject
- the attestation was linked to `OWNER/scientific-computing-toolkit`
- the attestation was signed by `.github/workflows/sbom-diff-and-risk-ci.yml`

## Release-consumer note

If these same wheel or source distribution bytes are later attached to a GitHub release, consumers should verify the downloaded release asset file itself with the same `gh attestation verify` flow. In the current setup, the provenance source of truth is still the workflow-produced build artifact and its attestation, not a separate release-attestation workflow.

## How this complements the tool's own analysis

Self-provenance and dependency analysis solve different problems:

- artifact attestations help consumers verify where `sbom-diff-and-risk` itself was built
- `sbom-diff-and-risk` helps users review and gate third-party dependency changes in their own projects

These attestations strengthen trust in the tool's own distributable artifacts, but they do not replace the tool's analysis of external SBOM inputs, policy decisions, or trust-signal reporting for third-party packages.
Loading
Loading