Repository navigation
Harden GitHub Actions workflows - #130
Conversation
Passing toJSON(secrets) to a third-party action on a mutable tag hands every repo secret to whoever controls that tag, and GitHub flagged the workflow as possibly malicious. Map just the vars/secrets the app reads via job-level env (folding in the fork-PR defaults) and pin pytest-coverage-comment to the v1.12.3 commit SHA. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pin codecov and the google-github-actions steps (which hold GCP deploy rights via OIDC) to the commits their current tags point at, and add Dependabot to keep the pins updated. Drop the unused write permissions from a11y, and grant pr-staging's OIDC and comment permissions only to the jobs that need them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Coverage for e2e tests for Python 3.14
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #130 +/- ##
=======================================
Coverage 66.45% 66.45%
=======================================
Files 29 29
Lines 2391 2391
=======================================
Hits 1589 1589
Misses 802 802
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
🚀 Staging Preview Deployed! URL: https://preview-seating-pr-130-137456085712.us-west1.run.app |
|
|
||
| - id: auth | ||
| uses: google-github-actions/auth@v3 | ||
| uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0 |
There was a problem hiding this comment.
It's honestly not clear to me that the security of this kind of pin vs the potential for breaking / needing to pay attention to a CI tool in the future is worth it (given this is a trusted org...)
There was a problem hiding this comment.
The added workflow in this PR .github/dependabot.yml should partially automate updating pins (i.e. open PRs when pins can be updated). We'd need to review/merge still.
A Dependabot PR runs its own updated workflows before anyone reviews it, and the preview deploy grants an OIDC token for the staging deployer, so a malicious action release would get that GCP access unreviewed. Skip both preview jobs for Dependabot PRs, and have Dependabot wait 7 days after a release before proposing it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add the pip ecosystem for the repo root, which covers both requirements.txt and requirements-dev.txt, on the same weekly schedule and 7-day cooldown as the actions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov already comments coverage on every PR, but merged the unit and e2e uploads into one number. Label each upload with its test type and show Codecov's flags table, so its comment covers both, and drop pytest-coverage-comment along with test.yml's write permissions. The per-file report now goes to the run's summary page for every run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov commented and set its checks as soon as the unit upload was processed, then updated them about 30 seconds later for e2e. Have it wait for both uploads first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GitHub flagged
test.ymlas possibly malicious, and its runs onmainhave been held for approval since. The cause was a pattern already in the workflow:toJSON(secrets)andtoJSON(vars)were passed to a third-party action on a tag its owner can move (oNaiPs/secrets-to-env-action@v1). If that tag were compromised, every repo secret would leak.Changes
test.ymlanda11y.yml: removesecrets-to-env-action. Each job'senv:block now maps only the variables and secrets the app reads. The fork-PR dummy defaults are folded in with||.codecov-actionand thegoogle-github-actionssteps inpr-staging.yml, which can get GCP deploy credentials. Each pin is the commit its current tag points to, so the actions run the same code as before..github/dependabot.ymlso pinned versions get weekly update PRs:github-actions: the SHA pins in the workflows.pip: the pinned packages in bothrequirements.txtandrequirements-dev.txt(Dependabot reads every requirements.txtfile in the directory). For example,pip-auditcurrently reports PYSEC-2026-4312 inWerkzeug==3.1.8, fixed in 3.1.9. It only affects Windows/NTFS, so not this app, but the Audit workflow'spip-audit || truenever fails CI on it.pr-staging.yml): a Dependabot PR runs its own updated workflows before review, and the deploy job'spermissions:grantid-token: writeeven on Dependabot runs. A bumpedgoogle-github-actionspin would otherwise run, unreviewed, with the staging deployer's GCP access. That account has project-wide roles instaging-cdss-web-apps, includingrun.adminandiam.serviceAccountUser. Dependabot PRs only change action pins and requirement pins, which the test workflows still check; a preview isn't worth giving them that access. To preview a package bump anyway, open your own PR with it.a11y.ymlgoes down tocontents: read; it never comments.pr-staging.ymlmovesid-token,issuesandpull-requestswrite from the whole workflow onto only the jobs that need them.test.ymlusesactions/checkout@v7to match the other workflows.pytest-coverage-commentwith Codecov flags:MishaKav/pytest-coverage-commentaction added two more comments.flags: unit/flags: e2e), andcodecov.ymladds the flags table to Codecov's comment, so one comment shows both. Codecov waits for both uploads (after_n_builds: 2) before commenting or setting its checks, so neither ever reflects only the unit tests.test.ymldropspull-requests: writeandissues: writeand is read-only.audit.yml,lint.ymlandcodeql.ymlare read-only and use only GitHub's own actions, so they're unchanged.Note
If tests later need a new repo variable or secret, it has to be added to the
env:block intest.yml/a11y.yml. The jobs no longer receive every variable and secret automatically.🤖 Generated with Claude Code