ci: the weekly advisory scan could not report what it found (#782) - #878
Merged
Conversation
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
The new gate has a robustness bug around non-mapping permissions, and the CI job permissions likely still don’t cover the check-run reporting path referenced by the closing issue (#782).
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Fixes a long-running CI failure where the scheduled RustSec advisory scan could not publish findings because the workflow token lacked the permissions required to open issues, and adds a regression gate to prevent the same class of failure recurring.
Changes:
- Grant job-scoped
issues: writeto thecargo-auditjob sorustsec/audit-checkcan open issues on scheduled runs. - Add a workflow-baseline test gate that asserts scheduled issue-opening actions have appropriate job-level permissions.
- Document the failure mode and fix in the changelog.
File summaries
| File | Description |
|---|---|
tests/test_workflow_baselines.py |
Adds a new regression gate for scheduled workflows using issue-opening actions. |
CHANGELOG.md |
Records the scheduled advisory-scan failure mode and the permissions-based fix. |
.github/workflows/ci.yml |
Adds job-level permissions to allow scheduled RustSec reporting via issue creation. |
Review details
- Files reviewed: 3/3 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
raeq
added a commit
that referenced
this pull request
Sep 1, 2026
#878 review. `permissions:` is legally a scalar as well as a mapping — `write-all` and `read-all` are both valid — and the gate called `.get` on it unconditionally. A workflow using the scalar form would have raised `AttributeError`, which reports as an error rather than a failure and says nothing about the workflow it was checking. The scalar is now answered as the answer it is: `write-all` satisfies the rule, `read-all` does not and fails by name. Mutation-checked in both directions. Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Richard Quinn <quinn.richard@gmail.com>
raeq
force-pushed
the
ci/audit-issues-write
branch
from
September 1, 2026 16:46
98e74b6 to
a61f5ef
Compare
raeq
added a commit
that referenced
this pull request
Sep 1, 2026
#878 review. `permissions:` is legally a scalar as well as a mapping — `write-all` and `read-all` are both valid — and the gate called `.get` on it unconditionally. A workflow using the scalar form would have raised `AttributeError`, which reports as an error rather than a failure and says nothing about the workflow it was checking. The scalar is now answered as the answer it is: `write-all` satisfies the rule, `read-all` does not and fails by name. Mutation-checked in both directions. Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Richard Quinn <quinn.richard@gmail.com>
raeq
force-pushed
the
ci/audit-issues-write
branch
from
September 1, 2026 17:04
a61f5ef to
23774b8
Compare
raeq
added a commit
that referenced
this pull request
Sep 1, 2026
#878 review. `permissions:` is legally a scalar as well as a mapping — `write-all` and `read-all` are both valid — and the gate called `.get` on it unconditionally. A workflow using the scalar form would have raised `AttributeError`, which reports as an error rather than a failure and says nothing about the workflow it was checking. The scalar is now answered as the answer it is: `write-all` satisfies the rule, `read-all` does not and fails by name. Mutation-checked in both directions. Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Richard Quinn <quinn.richard@gmail.com>
raeq
force-pushed
the
ci/audit-issues-write
branch
from
September 1, 2026 17:11
23774b8 to
107038d
Compare
raeq
added a commit
that referenced
this pull request
Sep 1, 2026
#878 review. `permissions:` is legally a scalar as well as a mapping — `write-all` and `read-all` are both valid — and the gate called `.get` on it unconditionally. A workflow using the scalar form would have raised `AttributeError`, which reports as an error rather than a failure and says nothing about the workflow it was checking. The scalar is now answered as the answer it is: `write-all` satisfies the rule, `read-all` does not and fails by name. Mutation-checked in both directions. Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Richard Quinn <quinn.richard@gmail.com>
On `schedule` there is no pull request to annotate, so `rustsec/audit-check` reports by opening an issue — `POST /repos/:owner/:repo/issues`. `ci.yml` grants `contents: read` at the workflow level, so that call returned "Resource not accessible by integration" and the job failed *after* a clean audit. The direction is what makes this worth more than a one-line fix. The job passed every week it had nothing to say and failed every week it did: twelve consecutive red Mondays, each one a security report nobody received. And none of it was visible on the `pull_request` path, which is the only path that gates a merge — so a workflow's non-PR triggers can rot indefinitely with nothing going red anywhere anyone looks. The last run is on record and the audit itself is fine: no vulnerabilities, two `unmaintained` informational warnings (`bincode`, `proc-macro-error2`, both transitive). Job-scoped rather than workflow-scoped, so the write reaches this job alone. `contents: read` is restated because job permissions REPLACE the workflow's rather than adding to them — omitting it would have left the job unable to check out. `tests/test_workflow_baselines.py` gains the gate. It already exists for this exact class (#832: a `push` path broken for 13 consecutive runs while the PR path stayed green), so this belongs beside it rather than in a new file. It is anchored to the *action* rather than to the job name, with a companion test that fails if no scheduled issue-opening job is found — a gate that silently matches nothing is how the last one of these was missed. Mutation-checked: removing the permissions block fails it by name. Refs #762 Closes #782 Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Richard Quinn <quinn.richard@gmail.com>
#878 review. `permissions:` is legally a scalar as well as a mapping — `write-all` and `read-all` are both valid — and the gate called `.get` on it unconditionally. A workflow using the scalar form would have raised `AttributeError`, which reports as an error rather than a failure and says nothing about the workflow it was checking. The scalar is now answered as the answer it is: `write-all` satisfies the rule, `read-all` does not and fails by name. Mutation-checked in both directions. Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Richard Quinn <quinn.richard@gmail.com>
raeq
force-pushed
the
ci/audit-issues-write
branch
from
September 1, 2026 18:03
107038d to
864afe3
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #782. Refs #762.
The failure, from the run log
On
schedulethere is no pull request to annotate, sorustsec/audit-checkreports by opening an issue.ci.ymlgrantscontents: read, so that call is refused and the job fails — after a clean audit.Why this is worth a gate, not just a line
The job passed every week it had nothing to say and failed every week it did.
Twelve consecutive red Mondays, each one a security report nobody received. And none of it shows on the
pull_requestpath — the only path that gates a merge — so a workflow's non-PR triggers rot indefinitely with nothing going red anywhere anyone looks. That is the same shape as #832 (apushpath broken for 13 straight runs while PRs stayed green).For the record, the audit itself is fine: no vulnerabilities, two
unmaintainedinformational warnings (bincode,proc-macro-error2, both transitive).The fix
Job-scoped, so the write reaches this job alone:
contents: readis restated deliberately — job permissions replace the workflow's rather than adding to them, so omitting it would leave the job unable to check out.The gate
Added to
tests/test_workflow_baselines.py, which already exists for this class rather than a new file. It is anchored to the action (rustsec/audit-check), not to the job name, so renaming or moving the job keeps it covered — and a companion test fails if no scheduled issue-opening job is found at all, because a gate that silently matches nothing is how this kind of thing gets missed twice.Mutation-checked — removing the permissions block fails it by name:
pytest6,274 green.🤖 Generated with Claude Code