Skip to content

Commit 896d791

Browse files
authored
Add SBOM, license report and OpenSSF Scorecard. (#556)
* Update GitHub Actions to latest versions. * Add SBOM and license report generation to release workflow. * Add OpenSSF Scorecard workflow. * Add "Security" section to `README` and improve `SECURITY.md`. * Use `python -m pip` instead of `pip` in workflows.
2 parents 86500ce + 62f8ef5 commit 896d791

File tree

8 files changed

+120
-17
lines changed

8 files changed

+120
-17
lines changed

.github/workflows/create-release.yml

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,54 @@ on:
88
jobs:
99
build:
1010
runs-on: ubuntu-latest
11-
# environment: release
11+
# environment: release # uncomment to require manual approval before publishing to PyPI (recommended for extra protection)
1212
permissions:
13-
id-token: write
13+
contents: write # needed to upload SBOM files as release assets via `gh release upload`
14+
id-token: write # needed for PyPI Trusted Publishing (OIDC) via pypa/gh-action-pypi-publish
1415

1516
steps:
1617
- name: Checkout
1718
uses: actions/checkout@v6
1819

20+
- name: Set up Python
21+
uses: actions/setup-python@v6
22+
with:
23+
python-version: '3.x'
24+
cache: 'pip'
25+
26+
- name: Upgrade pip
27+
run: python -m pip install --upgrade pip
28+
29+
- name: Install requirements
30+
run: |
31+
python -m pip install -r requirements.txt -r requirements-release.txt
32+
python -m pip install ".[all]"
33+
34+
- name: Build package
35+
run: python -m build
36+
37+
- name: Generate SBOM
38+
run: |
39+
cyclonedx-py environment \
40+
--pyproject pyproject.toml \
41+
--mc-type library \
42+
--of JSON \
43+
-o sbom.cyclonedx.json
44+
cyclonedx-py environment \
45+
--pyproject pyproject.toml \
46+
--mc-type library \
47+
--of XML \
48+
-o sbom.cyclonedx.xml
49+
50+
- name: Generate license report
51+
run: |
52+
pip-licenses \
53+
--ignore-packages build cyclonedx-bom cyclonedx-py pip-licenses \
54+
--with-authors --with-urls --format=csv --output-file=licenses.csv
55+
pip-licenses \
56+
--ignore-packages build cyclonedx-bom cyclonedx-py pip-licenses \
57+
--with-authors --with-urls --format=markdown --output-file=licenses.md
58+
1959
- name: Extract release notes
2060
id: extract-release-notes
2161
uses: ffurrer2/extract-release-notes@v3
@@ -26,17 +66,16 @@ jobs:
2666
body: ${{ steps.extract-release-notes.outputs.release_notes }}
2767
token: ${{ secrets.WORKFLOWS_CREATE_RELEASE_TOKEN }}
2868

29-
- name: Set up Python
30-
uses: actions/setup-python@v6
31-
with:
32-
python-version: '3.x'
33-
cache: 'pip'
34-
35-
- name: Build Package
69+
- name: Upload release assets
3670
run: |
37-
python -m pip install --upgrade pip
38-
python -m pip install build
39-
python -m build
71+
gh release upload ${{ github.ref_name }} \
72+
sbom.cyclonedx.json \
73+
sbom.cyclonedx.xml \
74+
licenses.csv \
75+
licenses.md \
76+
--clobber
77+
env:
78+
GH_TOKEN: ${{ secrets.WORKFLOWS_CREATE_RELEASE_TOKEN }}
4079

4180
- name: Publish on PyPI
4281
uses: pypa/gh-action-pypi-publish@release/v1

.github/workflows/pre-commit-autoupdate.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
- uses: actions/setup-python@v6
2020
with:
2121
python-version: '3.x'
22-
- uses: browniebroke/pre-commit-autoupdate-action@main
22+
- uses: browniebroke/pre-commit-autoupdate-action@v1
2323
- uses: peter-evans/create-pull-request@v8
2424
with:
2525
token: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/scorecard.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: OpenSSF Scorecard
2+
3+
on:
4+
push:
5+
branches: [main]
6+
schedule:
7+
- cron: '0 8 * * 6' # every Saturday at 08:00 UTC
8+
workflow_dispatch:
9+
10+
permissions: read-all
11+
12+
jobs:
13+
scorecard:
14+
runs-on: ubuntu-latest
15+
permissions:
16+
security-events: write # needed to upload SARIF results to GitHub Security tab
17+
id-token: write # needed for Scorecard's OIDC token
18+
contents: read
19+
20+
steps:
21+
- name: Checkout
22+
uses: actions/checkout@v6
23+
with:
24+
persist-credentials: false
25+
26+
- name: Run Scorecard
27+
uses: ossf/scorecard-action@v2
28+
with:
29+
results_file: scorecard-results.sarif
30+
results_format: sarif
31+
publish_results: true
32+
33+
- name: Upload results to GitHub Security tab
34+
uses: github/codeql-action/upload-sarif@v3
35+
with:
36+
sarif_file: scorecard-results.sarif
37+
category: scorecard

.github/workflows/test-package.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ jobs:
4949
coverage xml -o ./coverage.xml
5050
5151
- name: Upload coverage to Codecov
52-
uses: codecov/codecov-action@v5
52+
uses: codecov/codecov-action@v6
5353
with:
5454
token: ${{ secrets.CODECOV_TOKEN }}
5555
fail_ci_if_error: false

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,8 @@ dmypy.json
125125
# custom
126126
TODO.txt
127127
test-coverage.sh
128+
129+
# generated at release time, not committed
130+
sbom.cyclonedx.*
131+
licenses.csv
132+
licenses.md

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
[![](https://img.shields.io/scrutinizer/quality/g/fabiocaccamo/python-benedict?logo=scrutinizer)](https://scrutinizer-ci.com/g/fabiocaccamo/python-benedict/?branch=main)
1212
[![](https://img.shields.io/badge/code%20style-black-000000.svg?logo=python&logoColor=black)](https://github.com/psf/black)
1313
[![](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
14+
[![](https://img.shields.io/badge/security-policy-blue?logo=github)](https://github.com/fabiocaccamo/python-benedict/blob/main/SECURITY.md)
15+
[![](https://img.shields.io/badge/SBOM-CycloneDX-blue?logo=dependabot)](https://github.com/fabiocaccamo/python-benedict/releases/latest)
16+
[![](https://api.securityscorecards.dev/projects/github.com/fabiocaccamo/python-benedict/badge)](https://scorecard.dev/viewer/?uri=github.com/fabiocaccamo/python-benedict)
1417

1518
# python-benedict
1619
python-benedict is a dict subclass with **keylist/keypath/keyattr** support, **I/O** shortcuts (`base64`, `cli`, `csv`, `html`, `ini`, `json`, `pickle`, `plist`, `query-string`, `toml`, `xls`, `xml`, `yaml`) and many **utilities**... for humans, obviously.
@@ -44,6 +47,7 @@ python-benedict is a dict subclass with **keylist/keypath/keyattr** support, **I
4447
- [I/O methods](#io-methods)
4548
- [Parse methods](#parse-methods)
4649
- [Testing](#testing)
50+
- [Security](#security)
4751
- [License](#license)
4852

4953
## Installation
@@ -1030,6 +1034,13 @@ tox
10301034
python -m unittest
10311035
```
10321036

1037+
## Security
1038+
1039+
- **SBOM** — a Software Bill of Materials in [CycloneDX](https://cyclonedx.org/) format (JSON and XML) is generated and published as a release asset on every release. You can download it from the [Releases](https://github.com/fabiocaccamo/python-benedict/releases/latest) page.
1040+
- **Trusted Publishing** — packages are published to PyPI via [OIDC Trusted Publishing](https://docs.pypi.org/trusted-publishers/), without long-lived secrets.
1041+
- **OpenSSF Scorecard** — the repository is evaluated weekly against the [OpenSSF Scorecard](https://scorecard.dev/viewer/?uri=github.com/fabiocaccamo/python-benedict) checks; results are visible in the GitHub Security tab.
1042+
- **Reporting** — to report a vulnerability, please follow the [Security Policy](SECURITY.md).
1043+
10331044
## License
10341045
Released under [MIT License](LICENSE.txt).
10351046

SECURITY.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,21 @@
22

33
## Supported Versions
44

5-
Keep this library updated to the latest version.
5+
Only the latest stable release receives security fixes.
66

77
| Version | Supported |
88
| ------- | ------------------ |
99
| latest | :white_check_mark: |
10-
| oldest | :x: |
10+
| older | :x: |
1111

1212
## Reporting a Vulnerability
1313

14-
Open an issue.
14+
**Please do not open a public GitHub issue for security vulnerabilities.**
15+
16+
Use GitHub's private [Report a vulnerability](https://github.com/fabiocaccamo/python-benedict/security/advisories/new) feature. You will receive a response within 7 days, and a fix will be released as soon as possible depending on severity.
17+
18+
## Supply Chain Security
19+
20+
- **SBOM** — a Software Bill of Materials in [CycloneDX](https://cyclonedx.org/) format (JSON and XML) is attached to every [release](https://github.com/fabiocaccamo/python-benedict/releases/latest) as `sbom.cyclonedx.json` / `sbom.cyclonedx.xml`.
21+
- **License report** — a full dependency license inventory (`licenses.csv` / `licenses.md`) is also attached to every release.
22+
- **Trusted Publishing** — packages are published to PyPI via [OIDC Trusted Publishing](https://docs.pypi.org/trusted-publishers/), without storing long-lived API tokens.

requirements-release.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
build == 1.4.*
2+
cyclonedx-bom == 7.3.*
3+
pip-licenses == 5.5.*

0 commit comments

Comments
 (0)