Skip to content

allowlist-check: match owner/repo case-insensitively (closes #1304) - #1305

Merged
raboof merged 1 commit into
mainfrom
allowlist-case-insensitive
Sep 18, 2026
Merged

raboof merged 1 commit into
mainfrom
allowlist-case-insensitive

Conversation

@potiuk

@potiuk potiuk commented Sep 18, 2026

Copy link
Copy Markdown
Member

Closes #1304. Follow-up to #1300, which fixed the one miscased entry; this removes the class.

GitHub resolves owner and repository identifiers case-insensitively, so uses: Swatinem/rust-cache@v2 and uses: swatinem/rust-cache@v2 name the same action. fnmatch applies os.path.normcase, which is the identity on POSIX, so on the Linux runners:

>>> fnmatch.fnmatch("Swatinem/rust-cache@v2", "swatinem/rust-cache@*")
False

An entry whose casing differed from what a consumer wrote therefore rejected a legitimately approved action, reporting only that it was not on the allowlist - which is not what was actually wrong. apache/sedona-spatialbench hit exactly that (#950).

  • fold_ref_case() lower-cases the owner/repo half of a ref or pattern and leaves the part after @ alone.
  • The trusted-owner check needed the same treatment: Actions/checkout@v4 was not recognised as belonging to the actions owner.
  • The reporting site folds identically, so the printed reason cannot disagree with the verdict.

Only owner/repo folds. Tags and SHAs are case-sensitive on GitHub, so folding the ref would let an exactly-pinned entry match something it never approved. Two precision tests pin that (owner/action@v1.0.0-RC1 must not match ...-rc1), plus one asserting the fold cannot make a different repo match (Swatinem/rust-cache-evil, evil/rust-cache).

Test plan: five new tests, written first - the three case-insensitivity ones failed against the old matcher and the two precision guards passed, so they pin behaviour that already held. allowlist-check suite 53 passed; uv run pytest utils/tests/ 357 passed; prek clean. Verified against the real #950 shape.

🤖 Generated with Claude Code

GitHub resolves owner and repository identifiers case-insensitively, so
`uses: Swatinem/rust-cache@v2` and `uses: swatinem/rust-cache@v2` name the
same action. fnmatch applies os.path.normcase, which is the identity on
POSIX, so on the Linux runners an entry whose casing differed from what a
consumer wrote rejected a legitimately approved action -- and said only that
it was not on the allowlist, which is not what was actually wrong.
apache/sedona-spatialbench hit exactly that (#950, entry fixed in #1300).

Folds only the owner/repo half. Tags and SHAs are case-sensitive on GitHub,
so folding the part after "@" would let an exactly-pinned entry match a ref
it never approved; two precision tests pin that, along with one asserting
the fold cannot make a different repo match.

The trusted-owner check needed the same treatment: `Actions/checkout@v4`
was not recognised as belonging to the `actions` owner.

Generated-by: Claude Opus 5
@raboof
raboof merged commit 47b297b into main Sep 18, 2026
7 checks passed
@raboof
raboof deleted the allowlist-case-insensitive branch September 18, 2026 13:37
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.

allowlist-check: match owner/repo case-insensitively

2 participants