feat(scripts): add local Codex security review runner - #897
Conversation
Reuses the CI workflow's model and prompt via hermit-pinned yq so the review can run locally against the merge-base diff before pushing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3ec03cd9e3
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| fi | ||
|
|
||
| # yq resolves the `prompt: |` block scalar natively (no indent arithmetic). | ||
| PROMPT=$(yq '.jobs.security-review.steps[] | select(.id == "run_codex") | .with.prompt // ""' "$WORKFLOW_FILE") |
There was a problem hiding this comment.
Load the review prompt from a trusted ref
When this local runner is used on an untrusted branch that edits .github/workflows/codex-security-review.yml, this line reads the run_codex prompt from the checked-out branch and passes it as the top-level codex exec task. That lets the branch remove or replace the security boundary before Codex starts, so the external-binary guard does not protect the developer's authenticated run. Read the prompt/model from a trusted base ref, or embed a trusted prompt, and use the branch only as diff input.
Useful? React with 👍 / 👎.
| if ! command -v yq >/dev/null 2>&1; then | ||
| echo "yq not found on PATH. Activate hermit first: . ./bin/activate-hermit" >&2 |
There was a problem hiding this comment.
Avoid adding unapproved toolchain entries
This makes the new local runner depend on a newly added yq toolchain entry, while the repo guidance says not to introduce new tooling without asking. If this lands without explicit approval, everyone gets an expanded Hermit toolchain and the script depends on it contrary to that policy; either use existing repo tooling or document the approval for adding yq/shellcheck.
Useful? React with 👍 / 👎.
🔐 Codex Security Review
Review SummaryOverall Risk: HIGH Findings[HIGH] Local reviewer executes tooling from the untrusted checkout
[HIGH] Attacker-controlled workflow content becomes the privileged review prompt
NotesThe authoritative diff was well-formed. Shell syntax and ShellCheck validation passed; the material risks are the new local reviewer's broken trust boundary. Generated by Codex Security Review | |
Summary
Adds
scripts/codex-security-review-local.sh, which runs the same Codex Security Review that CI runs on PRs, but locally against the merge-base diff (including uncommitted tracked changes) so findings surface before pushing.How it works
CODEX_MODEL,CODEX_REASONING_EFFORT, and therun_codexstep'spromptblock directly from.github/workflows/codex-security-review.ymlwithyq, so the local run can't drift from CI — the workflow stays the single source of truth.${{ env.* }}prompt refs with local equivalents, with honest provenance for dirty trees (no fake HEAD pin or blob links when the diff includes uncommitted changes).codex exec --sandbox read-only, then applies the same output validation as CI (overall_riskenum, non-emptyreview_markdown) viayq -p=jsonand prints the review to the terminal.codexbinary that resolves inside the checkout, so a reviewed branch can't substitute the agent binary.Tooling
yq4.53.3 andshellcheck0.11.0 added to hermit (bin/); the script uses bareyqfrom the activated hermit environment and passes shellcheck clean.🤖 Generated with Claude Code