Skip to content

ci: the weekly advisory scan could not report what it found (#782) - #878

Merged
raeq merged 2 commits into
mainfrom
ci/audit-issues-write
Sep 1, 2026
Merged

ci: the weekly advisory scan could not report what it found (#782)#878
raeq merged 2 commits into
mainfrom
ci/audit-issues-write

Conversation

@raeq

@raeq raeq commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Closes #782. Refs #762.

The failure, from the run log

Run cargo audit
  ...
  No vulnerabilities were found
  ##[warning]2 warnings found!
  [@octokit/request] "POST https://api.github.com/repos/raeq/disarm/issues" is deprecated...
  ##[error]Resource not accessible by integration - https://docs.github.com/rest/issues/issues#create-an-issue

On schedule there is no pull request to annotate, so rustsec/audit-check reports by opening an issue. ci.yml grants contents: 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.

$ gh run list --workflow ci.yml --event schedule --limit 8
2026-08-31 failure
2026-08-24 failure
...
2026-07-13 failure

Twelve consecutive red Mondays, each one a security report nobody received. And none of it shows on the pull_request path — 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 (a push path broken for 13 straight runs while PRs stayed green).

For the record, the audit itself is fine: no vulnerabilities, two unmaintained informational warnings (bincode, proc-macro-error2, both transitive).

The fix

Job-scoped, so the write reaches this job alone:

    permissions:
      contents: read
      issues: write

contents: read is 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:

ci.yml: job 'cargo-audit' runs an issue-opening action on a schedule with no job-level permissions; it inherits the workflow's and cannot report

pytest 6,274 green.

🤖 Generated with Claude Code

Copilot AI lite review requested due to automatic review settings September 1, 2026 16:32
@raeq
raeq enabled auto-merge (squash) September 1, 2026 16:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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: write to the cargo-audit job so rustsec/audit-check can 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.

Comment thread .github/workflows/ci.yml
Comment thread tests/test_workflow_baselines.py
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
raeq force-pushed the ci/audit-issues-write branch from 98e74b6 to a61f5ef Compare September 1, 2026 16:46
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
raeq force-pushed the ci/audit-issues-write branch from a61f5ef to 23774b8 Compare September 1, 2026 17:04
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
raeq force-pushed the ci/audit-issues-write branch from 23774b8 to 107038d Compare September 1, 2026 17:11
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 added 2 commits September 1, 2026 20:03
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
raeq force-pushed the ci/audit-issues-write branch from 107038d to 864afe3 Compare September 1, 2026 18:03
@raeq
raeq merged commit 4b1fd46 into main Sep 1, 2026
21 checks passed
@raeq
raeq deleted the ci/audit-issues-write branch September 1, 2026 18:09
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.

The weekly advisory scan fails whenever it finds something: cargo-audit posts its report with a contents:read token

2 participants