Skip to content

feat(ci): apply security fixes to all github workflows - #56

Merged
LCrossman merged 2 commits into
LCrossman:mainfrom
ubiratansoares:u/zizmor-fixes
Oct 17, 2026
Merged

LCrossman merged 2 commits into
LCrossman:mainfrom
ubiratansoares:u/zizmor-fixes

Conversation

@ubiratansoares

@ubiratansoares ubiratansoares commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Hi @LCrossman! Ubi here, from RustConf 2026 Track3 / Day 2 and also from Rust infra team!

I saw your project today in one of my feeds and remembered you! After checking it out, I realized could land a small contribution :)

Here I updated all your Github Workflows fixing all security issues one can find using zizmor, a SAST tool I contribute with and also extensively adopted in the Rust Project itself.

Here is the summary of what it found (v1.31.1)

52 findings (8 unsafe fixes): 6 informational, 6 low, 11 medium, 29 high
Check here to see the full output ➜ microBioRust git:(main) zizmor --persona=pedantic --no-progress . INFO zizmor: 🌈 zizmor v1.31.1 WARN audit: zizmor: zizmor is running in offline mode by default; some audits and auto-fixes will not be available. see https://docs.zizmor.sh/usage/#operating-modes for details INFO audit: zizmor: 🌈 completed ./.github/workflows/R-CMD-check.yaml INFO audit: zizmor: 🌈 completed ./.github/workflows/microbiorust-py_benchmarks.yml INFO audit: zizmor: 🌈 completed ./.github/workflows/python-app.yml INFO audit: zizmor: 🌈 completed ./.github/workflows/release.yml INFO audit: zizmor: 🌈 completed ./.github/workflows/rust.yml warning[artipacked]: credential persistence through GitHub Actions artifacts --> ./.github/workflows/R-CMD-check.yaml:26:9 | 26 | - name: Checkout Repository | _________^ 27 | | uses: actions/checkout@v4 | |_________________________________^ does not set persist-credentials: false | = note: audit confidence → Low = note: this finding has an auto-fix

warning[excessive-permissions]: overly broad permissions
--> ./.github/workflows/R-CMD-check.yaml:1:1
|
1 | / on:
2 | | push:
3 | | branches: [main, master]
4 | | pull_request:
... |
67 | | env:
68 | | R_CHECK_CRAN_INCOMING: false
| |_________________________________________^ default permissions used due to no permissions: block
|
= note: audit confidence → Medium

warning[excessive-permissions]: overly broad permissions
--> ./.github/workflows/R-CMD-check.yaml:10:3
|
10 | / R-CMD-check:
11 | | runs-on: ${{ matrix.config.os }}
12 | | name: ${{ matrix.config.os }} (${{ matrix.config.r }})
... |
67 | | env:
68 | | R_CHECK_CRAN_INCOMING: false
| | ^
| | |
| |_________________________________________this job
| default permissions used due to no permissions: block
|
= note: audit confidence → Medium

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/R-CMD-check.yaml:27:15
|
27 | uses: actions/checkout@v4
| ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/R-CMD-check.yaml:30:15
|
30 | uses: dtolnay/rust-toolchain@stable
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/R-CMD-check.yaml:33:15
|
33 | uses: Swatinem/rust-cache@v2
| ^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/R-CMD-check.yaml:51:15
|
51 | uses: r-lib/actions/setup-r@v2
| ^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/R-CMD-check.yaml:57:15
|
57 | uses: r-lib/actions/setup-r-dependencies@v2
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/R-CMD-check.yaml:64:15
|
64 | uses: r-lib/actions/check-r-package@v2
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

help[concurrency-limits]: insufficient job-level concurrency limits
--> ./.github/workflows/R-CMD-check.yaml:1:1
|
1 | / on:
2 | | push:
3 | | branches: [main, master]
4 | | pull_request:
5 | | branches: [main, master]
| |____________________________^ workflow is missing concurrency setting
...
12 | name: ${{ matrix.config.os }} (${{ matrix.config.r }})
| ------------------------------------------------------ job affected by missing workflow concurrency
|
= note: audit confidence → High

info[superfluous-actions]: action functionality is already included by the runner
--> ./.github/workflows/R-CMD-check.yaml:30:15
|
29 | - name: Set up Rust
| ----------------- this step
30 | uses: dtolnay/rust-toolchain@stable
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use rustup and/or cargo in a script step
|
= note: audit confidence → Medium

warning[artipacked]: credential persistence through GitHub Actions artifacts
--> ./.github/workflows/microbiorust-py_benchmarks.yml:21:9
|
21 | - name: Checkout source
| ^
22 | | uses: actions/checkout@v4
23 | | with:
24 | | fetch-depth: 0
| |
_______________^ does not set persist-credentials: false
|
= note: audit confidence → Low
= note: this finding has an auto-fix

warning[artipacked]: credential persistence through GitHub Actions artifacts
--> ./.github/workflows/microbiorust-py_benchmarks.yml:39:9
|
39 | - name: Load previous results
| ^
40 | | continue-on-error: true
41 | | uses: actions/checkout@v4
42 | | with:
43 | | ref: gh-pages
44 | | path: old_pages
45 | | # set up ASV here so as to copy the history to it
| |
______________________________________________^ does not set persist-credentials: false
|
= note: audit confidence → Low
= note: this finding has an auto-fix

error[excessive-permissions]: overly broad permissions
--> ./.github/workflows/microbiorust-py_benchmarks.yml:9:3
|
9 | contents: write
| ^^^^^^^^^^^^^^^ contents: write is overly broad at the workflow level
|
= note: audit confidence → High

error[excessive-permissions]: overly broad permissions
--> ./.github/workflows/microbiorust-py_benchmarks.yml:10:3
|
10 | pages: write
| ^^^^^^^^^^^^ pages: write is overly broad at the workflow level
|
= note: audit confidence → High

error[excessive-permissions]: overly broad permissions
--> ./.github/workflows/microbiorust-py_benchmarks.yml:11:3
|
11 | id-token: write
| ^^^^^^^^^^^^^^^ id-token: write is overly broad at the workflow level
|
= note: audit confidence → High

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/microbiorust-py_benchmarks.yml:22:15
|
22 | uses: actions/checkout@v4
| ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/microbiorust-py_benchmarks.yml:27:15
|
27 | uses: actions/setup-python@v5
| ^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/microbiorust-py_benchmarks.yml:33:15
|
33 | uses: dtolnay/rust-toolchain@stable
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/microbiorust-py_benchmarks.yml:41:15
|
41 | uses: actions/checkout@v4
| ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/microbiorust-py_benchmarks.yml:94:15
|
94 | uses: peaceiris/actions-gh-pages@v3
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

help[undocumented-permissions]: permissions without explanatory comments
--> ./.github/workflows/microbiorust-py_benchmarks.yml:9:3
|
9 | contents: write
| ^^^^^^^^^^^^^^^ needs an explanatory comment
10 | pages: write
| ^^^^^^^^^^^^ needs an explanatory comment
11 | id-token: write
| ^^^^^^^^^^^^^^^ needs an explanatory comment
|
= note: audit confidence → High

info[anonymous-definition]: workflow or action definition without a name
--> ./.github/workflows/microbiorust-py_benchmarks.yml:14:3
|
14 | benchmark:
| ^^^^^^^^^ this job
|
= note: audit confidence → High
= tip: use 'name: ...' to give this job a name

help[concurrency-limits]: insufficient job-level concurrency limits
--> ./.github/workflows/microbiorust-py_benchmarks.yml:3:1
|
3 | / on:
4 | | push:
5 | | branches:
6 | | - main
| |____________^ workflow is missing concurrency setting
...
14 | benchmark:
| --------- job affected by missing workflow concurrency
|
= note: audit confidence → High

info[superfluous-actions]: action functionality is already included by the runner
--> ./.github/workflows/microbiorust-py_benchmarks.yml:33:15
|
32 | - name: Set up Rust
| ----------------- this step
33 | uses: dtolnay/rust-toolchain@stable
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use rustup and/or cargo in a script step
|
= note: audit confidence → Medium

warning[artipacked]: credential persistence through GitHub Actions artifacts
--> ./.github/workflows/python-app.yml:25:7
|
25 | - uses: actions/checkout@v4
| ^^^^^^^^^^^^^^^^^^^^^^^^^ does not set persist-credentials: false
|
= note: audit confidence → Low
= note: this finding has an auto-fix

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/python-app.yml:25:13
|
25 | - uses: actions/checkout@v4
| ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/python-app.yml:27:13
|
27 | uses: actions/setup-python@v5
| ^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/python-app.yml:34:13
|
34 | uses: dtolnay/rust-toolchain@stable
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

info[anonymous-definition]: workflow or action definition without a name
--> ./.github/workflows/python-app.yml:20:3
|
20 | build:
| ^^^^^ this job
|
= note: audit confidence → High
= tip: use 'name: ...' to give this job a name

help[concurrency-limits]: insufficient job-level concurrency limits
--> ./.github/workflows/python-app.yml:6:1
|
6 | / on:
7 | | push:
8 | | branches: [ "main" ]
9 | | paths:
... |
13 | | paths:
14 | | - 'microbiorust-py/**'
| |____________________________^ workflow is missing concurrency setting
...
20 | build:
| ----- job affected by missing workflow concurrency
|
= note: audit confidence → High

info[superfluous-actions]: action functionality is already included by the runner
--> ./.github/workflows/python-app.yml:34:13
|
33 | - name: Set up Rust
| ----------------- this step
34 | uses: dtolnay/rust-toolchain@stable
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use rustup and/or cargo in a script step
|
= note: audit confidence → Medium

warning[artipacked]: credential persistence through GitHub Actions artifacts
--> ./.github/workflows/release.yml:38:9
|
38 | - uses: actions/checkout@v4
| ^^^^^^^^^^^^^^^^^^^^^^^^^ does not set persist-credentials: false
|
= note: audit confidence → Low
= note: this finding has an auto-fix

warning[artipacked]: credential persistence through GitHub Actions artifacts
--> ./.github/workflows/release.yml:61:9
|
61 | - uses: actions/checkout@v4
| ^^^^^^^^^^^^^^^^^^^^^^^^^ does not set persist-credentials: false
|
= note: audit confidence → Low
= note: this finding has an auto-fix

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/release.yml:38:15
|
38 | - uses: actions/checkout@v4
| ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/release.yml:39:15
|
39 | - uses: actions/setup-python@v5
| ^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/release.yml:43:15
|
43 | uses: PyO3/maturin-action@v1
| ^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/release.yml:51:15
|
51 | uses: actions/upload-artifact@v4
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/release.yml:61:15
|
61 | - uses: actions/checkout@v4
| ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/release.yml:62:15
|
62 | - uses: actions/setup-python@v5
| ^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/release.yml:66:15
|
66 | uses: PyO3/maturin-action@v1
| ^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/release.yml:72:15
|
72 | uses: actions/upload-artifact@v4
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/release.yml:86:15
|
86 | - uses: actions/download-artifact@v4
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/release.yml:91:15
|
91 | uses: PyO3/maturin-action@v1
| ^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

error[cache-poisoning]: runtime artifacts potentially vulnerable to a cache poisoning attack
--> ./.github/workflows/release.yml:43:9
|
11 | / on:
12 | | push:
13 | | tags:
14 | | - 'v*'
| |____________- generally used when publishing artifacts generated at runtime
...
43 | uses: PyO3/maturin-action@v1
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this step
...
47 | sccache: 'true'
| --------------- enables caching explicitly here
|
= note: audit confidence → Low
= note: this finding has an auto-fix

help[concurrency-limits]: insufficient job-level concurrency limits
--> ./.github/workflows/release.yml:11:1
|
11 | / on:
12 | | push:
13 | | tags:
14 | | - 'v*'
| |____________^ workflow is missing concurrency setting
...
21 | name: Build wheels
| ------------------ job affected by missing workflow concurrency
...
57 | name: Build sdist
| ----------------- job affected by missing workflow concurrency
...
78 | name: Publish to PyPI
| --------------------- job affected by missing workflow concurrency
|
= note: audit confidence → High

warning[artipacked]: credential persistence through GitHub Actions artifacts
--> ./.github/workflows/rust.yml:18:7
|
18 | - uses: actions/checkout@v4
| ^^^^^^^^^^^^^^^^^^^^^^^^^ does not set persist-credentials: false
|
= note: audit confidence → Low
= note: this finding has an auto-fix

warning[excessive-permissions]: overly broad permissions
--> ./.github/workflows/rust.yml:1:1
|
1 | / name: microBioRust_test
2 | |
3 | | on:
4 | | push:
... |
21 | | - name: Run tests one-three
22 | | run: cargo test --verbose
| |________________________________^ default permissions used due to no permissions: block
|
= note: audit confidence → Medium

warning[excessive-permissions]: overly broad permissions
--> ./.github/workflows/rust.yml:13:3
|
13 | / build:
14 | |
15 | | runs-on: ubuntu-latest
... |
21 | | - name: Run tests one-three
22 | | run: cargo test --verbose
| | ^
| | |
| |________________________________this job
| default permissions used due to no permissions: block
|
= note: audit confidence → Medium

error[unpinned-uses]: unpinned action reference
--> ./.github/workflows/rust.yml:18:13
|
18 | - uses: actions/checkout@v4
| ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)
|
= note: audit confidence → High

info[anonymous-definition]: workflow or action definition without a name
--> ./.github/workflows/rust.yml:13:3
|
13 | build:
| ^^^^^ this job
|
= note: audit confidence → High
= tip: use 'name: ...' to give this job a name

help[concurrency-limits]: insufficient job-level concurrency limits
--> ./.github/workflows/rust.yml:3:1
|
3 | / on:
4 | | push:
5 | | branches: [ "main" ]
6 | | pull_request:
7 | | branches: [ "main" ]
| |________________________^ workflow is missing concurrency setting
...
13 | build:
| ----- job affected by missing workflow concurrency
|
= note: audit confidence → High

52 findings (8 unsafe fixes): 6 informational, 6 low, 11 medium, 29 high

In can find more about each audit rules on zizmor docs.

This PR fixes all findings and also adds a new Github Workflow, that runs zizmor continuously on every PR, so no new issues are introduced by mistake!

Hope you accept this contribution! Let me know if I should change anything!

@ubiratansoares

ubiratansoares commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor Author

@LCrossman I think the CI failures in R-CMD-check are happening because of this check. I think it was introduced because I removed dtonay/rust-toolchain, which also sets a few env vars like CARGO_TERM_COLOR=always, which might have changed what that particular grep catches

@ubiratansoares

ubiratansoares commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor Author

@LCrossman added this commit to fail that step only on failures, if you want to give it a try

@LCrossman

Copy link
Copy Markdown
Owner

thanks for the runner sec updates!! and fix for the R runners. All tests passing now

@LCrossman
LCrossman merged commit ffa6081 into LCrossman:main Oct 17, 2026
4 checks passed
@ubiratansoares
ubiratansoares deleted the u/zizmor-fixes branch October 17, 2026 10:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants