Skip to content

ci: suppress the JWT-grant CodeQL false positive in place, and make the marker count - #81

Merged
blink-admin merged 2 commits into
mainfrom
ci/codeql-query-filter
Sep 10, 2026
Merged

blink-admin merged 2 commits into
mainfrom
ci/codeql-query-filter

Conversation

@grimen

@grimen grimen commented Sep 10, 2026 •

Copy link
Copy Markdown
Collaborator

js/insufficient-password-hash has flagged the same RS256 JWT-grant signature three times (alerts 1, 10, 15): the JWT's aud claim is read from config.oauthBaseUrl, whose name trips the query's password heuristic. The inline codeql[] marker from #58 never worked because the default suite does not run the pack's AlertSuppression query, so the comment was never read; and an API dismissal is keyed on the alert's fingerprint, so every file move re-opened it.

What changes

  • New .github/codeql/codeql-config.yml: the security-and-quality suite plus codeql/javascript-queries:AlertSuppression.ql. The workflow reads it through config-file.
  • // codeql[js/insufficient-password-hash] alone on the line above the flagged sign.update(signingInput). It suppresses that one line and travels with the code. The query stays on for everything else - a real weak password hash elsewhere still fails.
  • The rule in AGENTS.md / CLAUDE.md: suppress in place with the marker; never dismiss (fingerprint-keyed), never exclude the query.
  • Alert 15 is dismissed as a false positive in the meantime.

Verified

make check-ci (actionlint + shellcheck) and the docs-tables check pass. This PR's own CodeQL run is the proof: the analysis must still run the query and report the finding as suppressed, not open.

js/insufficient-password-hash has flagged the same RS256 JWT-grant
signature three times (alerts 1, 10, 15): the JWT's aud claim is read from
config.oauthBaseUrl, whose name trips the query's password heuristic. The
inline codeql[] marker from #58 is not honoured by this setup, and an API
dismissal is keyed on the alert's fingerprint, so every file move re-opened
it.

The query is now excluded in .github/codeql/codeql-config.yml (query-filters),
which the workflow reads through config-file; the suite selection moves
there too. The finding cannot come back on any branch, and the rule for the
next false positive is written down in AGENTS.md / CLAUDE.md.
Excluding js/insufficient-password-hash repo-wide would also hide a real
weak password hash added later. The inline marker is the right tool - it
silences one line and travels with the code - and the reason it never
worked is that the default suite does not run the pack's AlertSuppression
query, so the codeql[] comment from #58 was never read.

The config now runs that query next to security-and-quality, the marker
sits alone on the line above the flagged sign.update(), and the rule in
AGENTS.md / CLAUDE.md says so.
@grimen grimen changed the title ci: exclude the JWT-grant false positive from CodeQL by query, for good ci: suppress the JWT-grant CodeQL false positive in place, and make the marker count Sep 10, 2026
@blink-admin
blink-admin merged commit 635c2c7 into main Sep 10, 2026
17 of 20 checks passed
@blink-admin
blink-admin deleted the ci/codeql-query-filter branch September 10, 2026 16:26
blink-admin pushed a commit that referenced this pull request Sep 15, 2026
…m it misread (#108)

* fix(node): send the OAuth host alone as the JWT aud claim

DOCUSIGN_OAUTH_URL with a trailing slash put 'account-d.docusign.com/' in the
assertion's aud claim, which DocuSign has tolerated and is not what the claim
means; an http:// value put the entire URL there, which it would not have
tolerated. .replace('https://', '') only ever removed that one prefix, so
neither shape was handled.

It also stops CodeQL's js/insufficient-password-hash firing: the rule read the
'auth' in oauthBaseUrl as a credential and RSA-SHA256 as a password hash. That
false positive has been suppressed, dismissed and excluded four times since
#58 - alerts 1, 10, 15 and 18 - and came back every time. Not tripping it is
the only fix that stays, and `make codeql` now reports no finding for it at
all rather than a suppressed one.

* test(service): drop an unused vitest import

js/unused-local-variable, and correct on its own terms: nothing in the file
uses vi.

* ci: stop claiming an inline marker suppresses a CodeQL alert

It does not, on GitHub. The CodeQL CLI honours // codeql[<rule-id>] and
writes suppressions: [{state: accepted}] onto the result - and GitHub code
scanning ignores that property. Verified on analysis 1779039789: the uploaded
SARIF carried the suppression and alert 18 was open with
dismissed_reason: null.

make codeql said otherwise, because codeql-findings.mjs decided "suppressed"
by reading the same property GitHub discards. So the local gate exited 0 on a
finding that was red on GitHub, and nobody had a reason to look. That is how
this survived #58 and #81 and came back as alerts 1, 10, 15 and 18. Every
finding now counts as open here too, which is what GitHub will do with it.

The AlertSuppression pack goes with it: it produces a suppression nothing
consumes and a local signal that misleads. Excluding a query repo-wide is
still refused - #81 tried it and reverted it inside the same PR, for the
right reason.

The config, CLAUDE.md, AGENTS.md, the workflow and the development guide all
told the next person to reach for the marker. They now say what actually
works: make the query not fire.
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