feat: fix 7 read-only gaps found by audit log analysis - #19
Merged
Merged
Conversation
gh api graphql: check the GraphQL operation type (deny mutation/ subscription anywhere in the document, and any operationName field) instead of the REST write-method heuristic, which doesn't apply since the query document is itself passed as a -f/-F field. Endpoint detection now uses a dedicated flags-with-value map for `gh api`, so a flag's own value (e.g. "graphql" passed to -X/--preview) can no longer be mistaken for the endpoint positional and skip the write-method check entirely. hasFieldOrInputFlag also recognizes -f/-F forms with the value glued to the flag. gcloud: Cloud Run (`run <resource> <verb>`, optionally behind alpha/beta) is no longer swept into the generic "run" write-verb blacklist; its own verb is checked at its expected position instead of scanning every token, so an unrecognized flag's separate-argument value can't be mistaken for it. auth application-default restricted to the read-only token printers. git reset: allow the forms that don't touch the working tree (no mode flag, --soft, --mixed) via an allowlist of flags rather than a blacklist of destructive ones — git accepts unambiguous abbreviations of long flags (`--har` for `--hard`), which a blacklist can't reliably catch. npx: strip a trailing "@Version" before matching against the allowlist, so "prettier@3" works like "prettier". Left untouched when what follows "@" is an alias/path/URL reference (contains ":" or "/"), which isn't a version. Also allow systemctl show/list-timers and comm (read-only). uv run --with-requirements <file> -- <cmd> is left as-is: the real subcommand sits after "--", which every other allowlisted tool also treats as a hard stop on purpose.
grams
force-pushed
the
audit-log-quick-fixes
branch
from
August 31, 2026 20:51
09577f0 to
94323ff
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.
Summary
Fixes found by replaying blocked audit-log entries through
--audit: real commands that were being denied despite doing nothing but read.gh api graphql: checked by GraphQL operation type (mutation/subscriptionanywhere in the document, or anoperationNamefield) instead of the REST write-method heuristic, which doesn't apply since the query document is itself passed as a-f/-Ffield. Endpoint detection uses a dedicated flags-with-value map so a flag's own value (e.g.graphqlpassed to-X/--preview) can't be mistaken for the endpoint and skip the write-method check.gcloud run <resource> <verb>(including behindalpha/beta) no longer swept into the genericrunwrite-verb blacklist; its own verb is checked at its expected position.auth application-defaultrestricted to the read-only token printers.git reset: non-destructive forms (no mode flag,--soft,--mixed) allowed via a flag allowlist rather than blacklisting--hard/--merge/--keep— git accepts unambiguous abbreviations (--harfor--hard) that a blacklist misses.npx: strips a trailing@versionbefore matching the allowlist (prettier@3), left untouched for alias/path/URL references (prettier@npm:x) which aren't a version.systemctl show/list-timersandcommadded (read-only).uv run --with-requirements <file> -- <cmd>left as-is: the real subcommand sits after--, which every allowlisted tool treats as a hard stop on purpose (tested elsewhere against smuggling a value past a positional check).Test plan
go build ./... && go vet ./... && go test ./...gofmt -l .cleanpr-review-toolkit:code-reviewer(3 rounds — found and fixed real bypasses: GraphQL mutation-detection evasion via leading comment/fragment/comma andoperationName,gh apiendpoint-detection shadowing via-X/--previewvalues, npm alias/file/git-URL references treated as a version, Cloud Run write verbs reachable via an unrecognized flag shifting token positions, glued-form-f/-FREST fields) + Kilroy (clean, one comment tightened)git/gh/gcloud/npxbinaries, not just unit testsgh api -if title=pwned) — this tool targets prompt reduction for commands an LLM writes innocently, not hardening against a deliberately adversarial one (already the file's stated posture: "best-effort filter, not a security boundary")