Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
1cf0e71
fix(security): make sandbox subprocess mode explicit
seonghobae Aug 20, 2026
96c42ce
λ³΄μ•ˆ: sandboxed_web_e2e.py의 subprocess ν˜ΈμΆœμ— shell=False μΆ”κ°€
seonghobae Aug 20, 2026
72f9161
fix(sandbox): satisfy Ruff and Bandit subprocess contracts
seonghobae Aug 20, 2026
64df5b6
λ³΄μ•ˆ: sandboxed_web_e2e.py의 subprocess ν˜ΈμΆœμ— shell=False μΆ”κ°€
seonghobae Aug 20, 2026
021f2a2
fix(sandbox): retain subprocess lint suppressions on current head
seonghobae Aug 20, 2026
0622231
λ³΄μ•ˆ: sandboxed_web_e2e.py의 subprocess ν˜ΈμΆœμ— shell=False μΆ”κ°€
seonghobae Aug 20, 2026
3e91f12
fix: document trusted subprocess lint suppressions
seonghobae Aug 20, 2026
b3905f9
λ³΄μ•ˆ: sandboxed_web_e2e.py의 subprocess ν˜ΈμΆœμ— shell=False μΆ”κ°€
seonghobae Aug 20, 2026
0cd77d0
fix: retain trusted subprocess lint evidence
seonghobae Aug 20, 2026
19c73a0
λ³΄μ•ˆ: sandboxed_web_e2e.py의 subprocess ν˜ΈμΆœμ— shell=False μΆ”κ°€
seonghobae Aug 20, 2026
b84e7a3
fix: retain trusted subprocess lint evidence
seonghobae Aug 20, 2026
dcf3196
λ³΄μ•ˆ: sandboxed_web_e2e.py의 subprocess ν˜ΈμΆœμ— shell=False μΆ”κ°€
seonghobae Aug 20, 2026
893f854
fix: retain trusted subprocess lint evidence
seonghobae Aug 20, 2026
71e7b4f
λ³΄μ•ˆ: sandboxed_web_e2e.py의 subprocess ν˜ΈμΆœμ— shell=False μΆ”κ°€
seonghobae Aug 20, 2026
73fdbf7
fix: retain trusted subprocess lint evidence
seonghobae Aug 20, 2026
4b9508a
λ³΄μ•ˆ: sandboxed_web_e2e.py의 subprocess ν˜ΈμΆœμ— shell=False μΆ”κ°€
seonghobae Aug 20, 2026
020c6b8
fix(security): retain subprocess lint evidence
seonghobae Aug 20, 2026
1e85ab0
λ³΄μ•ˆ: sandboxed_web_e2e.py의 subprocess ν˜ΈμΆœμ— shell=False μΆ”κ°€
seonghobae Aug 20, 2026
65246be
Merge remote-tracking branch 'origin/main' into HEAD
seonghobae Aug 20, 2026
deacb92
Merge remote-tracking branch 'origin/fix-sandboxed-web-e2e-b603-32043…
seonghobae Aug 20, 2026
d5f2d10
fix(security): keep PR scoped to sandbox subprocess
seonghobae Aug 20, 2026
7ed6f15
λ³΄μ•ˆ: sandboxed_web_e2e.py의 subprocess ν˜ΈμΆœμ— shell=False μΆ”κ°€
seonghobae Aug 20, 2026
6c77c0f
λ³΄μ•ˆ: sandboxed_web_e2e.py의 subprocess ν˜ΈμΆœμ— shell=False μΆ”κ°€
seonghobae Aug 20, 2026
209fd38
fix(security): preserve sandbox lint evidence
seonghobae Aug 20, 2026
1c00cde
λ³΄μ•ˆ: sandboxed_web_e2e.py의 subprocess ν˜ΈμΆœμ— shell=False μΆ”κ°€
seonghobae Aug 20, 2026
7c0be13
fix(security): retain sandbox subprocess contract
seonghobae Aug 20, 2026
2b88970
λ³΄μ•ˆ: sandboxed_web_e2e.py의 subprocess ν˜ΈμΆœμ— shell=False μΆ”κ°€
seonghobae Aug 20, 2026
4988c32
fix(security): restore scoped sandbox PR diff
seonghobae Aug 20, 2026
071a9ce
λ³΄μ•ˆ: sandboxed_web_e2e.py의 subprocess ν˜ΈμΆœμ— shell=False μΆ”κ°€
seonghobae Aug 20, 2026
79395ed
fix(security): restore sandbox PR scope after concurrent update
seonghobae Aug 20, 2026
1780b4d
λ³΄μ•ˆ: sandboxed_web_e2e.py의 subprocess ν˜ΈμΆœμ— shell=False μΆ”κ°€
seonghobae Aug 20, 2026
19b53a7
fix(security): keep sandbox PR limited to requested files
seonghobae Aug 20, 2026
f19549c
λ³΄μ•ˆ: sandboxed_web_e2e.py의 subprocess ν˜ΈμΆœμ— shell=False μΆ”κ°€
seonghobae Aug 20, 2026
558c437
chore: restore sentinel PR scope
seonghobae Aug 20, 2026
42ff0bb
λ³΄μ•ˆ: sandboxed_web_e2e.py의 subprocess ν˜ΈμΆœμ— shell=False μΆ”κ°€
seonghobae Aug 20, 2026
dee2528
chore: restore sentinel PR scope
seonghobae Aug 20, 2026
da0673a
λ³΄μ•ˆ: sandboxed_web_e2e.py의 subprocess ν˜ΈμΆœμ— shell=False μΆ”κ°€
seonghobae Aug 20, 2026
1f811e8
chore: restore sentinel PR scope
seonghobae Aug 20, 2026
8b0f7a7
λ³΄μ•ˆ: sandboxed_web_e2e.py의 subprocess ν˜ΈμΆœμ— shell=False μΆ”κ°€
seonghobae Aug 20, 2026
d4948f2
chore: restore sentinel PR scope
seonghobae Aug 20, 2026
86bdbc2
Merge branch 'main' into fix-sandboxed-web-e2e-b603-3204335274775172996
opencode-agent[bot] Aug 20, 2026
0270c9c
fix(security): restrict readiness checks to loopback
seonghobae Aug 20, 2026
684063a
λ³΄μ•ˆ: sandboxed_web_e2e.py의 wait_for_url ν•¨μˆ˜ SSRF 취약점 μˆ˜μ •
seonghobae Aug 20, 2026
7655ab6
Revert "λ³΄μ•ˆ: sandboxed_web_e2e.py의 wait_for_url ν•¨μˆ˜ SSRF 취약점 μˆ˜μ •"
seonghobae Aug 20, 2026
4ab419a
λ³΄μ•ˆ: sandboxed_web_e2e.py의 wait_for_url ν•¨μˆ˜ SSRF 취약점 μˆ˜μ •
seonghobae Aug 20, 2026
2ba74d0
test: complete sandboxed web E2E docstrings
seonghobae Aug 20, 2026
a0cde93
λ³΄μ•ˆ: sandboxed_web_e2e.py의 wait_for_url ν•¨μˆ˜ SSRF 취약점 μˆ˜μ •
seonghobae Aug 20, 2026
6aee33e
test: document sandboxed web e2e doubles
seonghobae Aug 20, 2026
66d65c1
λ³΄μ•ˆ: sandboxed_web_e2e.py의 wait_for_url ν•¨μˆ˜ SSRF 취약점 μˆ˜μ •
seonghobae Aug 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/agent-mention-router-quality-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
timeout-minutes: 20
steps:
- name: Harden runner
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- name: Checkout exact head with comparison history
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/audit-central-ruleset.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
GH_TOKEN: ${{ secrets.PR_REVIEW_MERGE_TOKEN || secrets.OPENCODE_APPROVE_TOKEN || github.token }}
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/codeql-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ jobs:
matrix: ${{ fromJSON(needs.detect-languages.outputs.matrix) }}
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit

Expand Down Expand Up @@ -186,7 +186,7 @@ jobs:
matrix: ${{ fromJSON(needs.detect-languages.outputs.matrix) }}
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit

Expand Down
7 changes: 0 additions & 7 deletions .github/workflows/hourly-nvidia-nim-review-repair.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ on:
- .github/workflows/hourly-nvidia-nim-review-repair.yml
- .github/workflows/nonnest2-hourly-review-repair.yml
- .github/workflows/originweave-hourly-review-repair.yml
- .github/workflows/quarantine-sandbox-hourly-review-repair.yml
- scripts/ci/pr_review_conflict_scope.py
- scripts/ci/pr_review_autofix_context.py
- tests/test_bandscope_hourly_review_caller.py
Expand All @@ -26,7 +25,6 @@ on:
- tests/test_hourly_scheduler_runtime_budget.py
- tests/test_nonnest2_hourly_review_caller.py
- tests/test_originweave_hourly_review_caller.py
- tests/test_quarantine_sandbox_hourly_review_caller.py
- tests/test_hourly_autofix_context_quality_gate.py
- tests/test_pr_review_conflict_scope.py
- tests/test_pr_review_conflict_scope_control_files.py
Expand All @@ -50,7 +48,6 @@ on:
- docs/doctoring/hourly-nvidia-nim-autofix.md
- docs/doctoring/nonnest2-hourly-review-caller.md
- docs/doctoring/originweave-hourly-review-caller.md
- docs/doctoring/quarantine-sandbox-hourly-review-caller.md
push:
paths:
- .github/workflows/pr-review-fix-scheduler.yml
Expand All @@ -65,7 +62,6 @@ on:
- .github/workflows/hourly-nvidia-nim-review-repair.yml
- .github/workflows/nonnest2-hourly-review-repair.yml
- .github/workflows/originweave-hourly-review-repair.yml
- .github/workflows/quarantine-sandbox-hourly-review-repair.yml
- scripts/ci/pr_review_conflict_scope.py
- scripts/ci/pr_review_autofix_context.py
- tests/test_bandscope_hourly_review_caller.py
Expand All @@ -76,7 +72,6 @@ on:
- tests/test_hourly_scheduler_runtime_budget.py
- tests/test_nonnest2_hourly_review_caller.py
- tests/test_originweave_hourly_review_caller.py
- tests/test_quarantine_sandbox_hourly_review_caller.py
- tests/test_hourly_autofix_context_quality_gate.py
- tests/test_pr_review_conflict_scope.py
- tests/test_pr_review_conflict_scope_control_files.py
Expand All @@ -100,7 +95,6 @@ on:
- docs/doctoring/hourly-nvidia-nim-autofix.md
- docs/doctoring/nonnest2-hourly-review-caller.md
- docs/doctoring/originweave-hourly-review-caller.md
- docs/doctoring/quarantine-sandbox-hourly-review-caller.md

permissions:
contents: read
Expand Down Expand Up @@ -156,7 +150,6 @@ jobs:
tests/test_hourly_scheduler_runtime_budget.py \
tests/test_nonnest2_hourly_review_caller.py \
tests/test_originweave_hourly_review_caller.py \
tests/test_quarantine_sandbox_hourly_review_caller.py \
tests/test_pr_review_conflict_scope_control_files.py \
tests/test_hourly_autofix_context_quality_gate.py \
tests/test_pr_review_conflict_scope_git_executable.py \
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr-review-autofix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
REPAIR_MODE: ${{ github.event.client_payload.repair_mode || 'review' }}
steps:
- name: Harden runner
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit

Expand Down
39 changes: 2 additions & 37 deletions .github/workflows/pr-review-merge-scheduler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -773,14 +773,6 @@ jobs:
echo "::error::ORG_SWEEP_MAX_UNAVAILABLE must be a non-negative integer; got '${ORG_SWEEP_MAX_UNAVAILABLE}'. Fix the ORG_SWEEP_MAX_UNAVAILABLE repository variable."
exit 1
fi
if ! [[ "$ORG_SWEEP_REVIEW_DISPATCH_LIMIT" =~ ^(-1|[0-9]+)$ ]]; then
echo "::error::ORG_SWEEP_REVIEW_DISPATCH_LIMIT must be -1 or a non-negative integer; got '${ORG_SWEEP_REVIEW_DISPATCH_LIMIT}'. Fix the ORG_SWEEP_REVIEW_DISPATCH_LIMIT repository variable."
exit 1
fi
if ! [[ "$ORG_SWEEP_BRANCH_UPDATE_LIMIT" =~ ^(-1|[0-9]+)$ ]]; then
echo "::error::ORG_SWEEP_BRANCH_UPDATE_LIMIT must be -1 or a non-negative integer; got '${ORG_SWEEP_BRANCH_UPDATE_LIMIT}'. Fix the ORG_SWEEP_BRANCH_UPDATE_LIMIT repository variable."
exit 1
fi

repositories_json="$(
gh api \
Expand All @@ -800,11 +792,6 @@ jobs:
failures=0
unavailable=0
unavailable_repos=()
# These are organization-wide budgets. They must be consumed across
# the repository loop, not reset for every target repository; resetting
# them here can enqueue hundreds of long-running review jobs per sweep.
org_review_dispatches_used=0
org_branch_updates_used=0
for target in "${sweep_targets[@]}"; do
repo_full_name="${target%%$'\t'*}"
default_branch="${target##*$'\t'}"
Expand Down Expand Up @@ -832,31 +819,14 @@ jobs:
*) project_flow="github-flow" ;;
esac

if [ "$ORG_SWEEP_REVIEW_DISPATCH_LIMIT" = "-1" ]; then
review_dispatch_limit=-1
else
review_dispatch_limit=$((ORG_SWEEP_REVIEW_DISPATCH_LIMIT - org_review_dispatches_used))
if (( review_dispatch_limit < 0 )); then
review_dispatch_limit=0
fi
fi
if [ "$ORG_SWEEP_BRANCH_UPDATE_LIMIT" = "-1" ]; then
branch_update_limit=-1
else
branch_update_limit=$((ORG_SWEEP_BRANCH_UPDATE_LIMIT - org_branch_updates_used))
if (( branch_update_limit < 0 )); then
branch_update_limit=0
fi
fi

args=(
--repo "$repo_full_name"
--base-branch "$default_branch"
--project-flow "$project_flow"
--max-prs "$ORG_SWEEP_MAX_PRS"
--review-workflow "Required OpenCode Review"
--review-dispatch-limit "$review_dispatch_limit"
--branch-update-limit "$branch_update_limit"
--review-dispatch-limit "$ORG_SWEEP_REVIEW_DISPATCH_LIMIT"
--branch-update-limit "$ORG_SWEEP_BRANCH_UPDATE_LIMIT"
Comment on lines +828 to +829

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.

πŸ”΄ Organization-wide review budget resets for every repository, flooding CI each sweep

The review and branch-update budgets are handed to each repository in full (--review-dispatch-limit "$ORG_SWEEP_REVIEW_DISPATCH_LIMIT" at .github/workflows/pr-review-merge-scheduler.yml:828) instead of being shared and drawn down across the whole run, so every repository restarts the entire budget.
Impact: A single scheduled sweep can start many long-running review and branch-update jobs across all organization repositories every 15 minutes, instead of the intended small org-wide cap.

Removed org-wide budget accumulation across the repository loop

The previous code initialized org_review_dispatches_used=0 / org_branch_updates_used=0 before the loop, computed a per-target remaining limit (review_dispatch_limit=$((ORG_SWEEP_REVIEW_DISPATCH_LIMIT - org_review_dispatches_used))), passed that remaining amount to the scheduler, and after each repository incremented the used counters by parsing the sweep output. This PR removes all of that (see the deleted lines around .github/workflows/pr-review-merge-scheduler.yml:803-806 and :835-884 on the LEFT side) and now passes the raw env vars ORG_SWEEP_REVIEW_DISPATCH_LIMIT / ORG_SWEEP_BRANCH_UPDATE_LIMIT directly at .github/workflows/pr-review-merge-scheduler.yml:828-829. With the default value '1' per repository and dozens of target repositories, the effective total becomes limit Γ— repository_count per sweep. The deleted code explicitly warned: "These are organization-wide budgets. They must be consumed across the repository loop, not reset for every target repository; resetting them here can enqueue hundreds of long-running review jobs per sweep." The matching contract assertions in tests/test_required_workflow_queue_contract.py were also removed.

Prompt for agents
The organization queue sweep in pr-review-merge-scheduler.yml previously enforced an org-wide budget for review dispatches and branch updates by tracking cumulative usage across the repository loop (org_review_dispatches_used / org_branch_updates_used), computing the remaining budget per target, passing the remaining amount to the scheduler via --review-dispatch-limit / --branch-update-limit, and incrementing the counters by grepping the per-repository sweep output. This PR removed that accumulation and now passes the raw ORG_SWEEP_REVIEW_DISPATCH_LIMIT / ORG_SWEEP_BRANCH_UPDATE_LIMIT env vars to every repository, so each repository gets the full budget rather than a shared one. With the default limit of 1 across many repositories, a single 15-minute sweep can enqueue many long-running review/branch-update jobs. Restore the org-wide budget bookkeeping (initialize counters before the loop, subtract used from the configured ceiling clamped at 0, pass the remaining per-target value, and re-accumulate from the sweep output), along with the integer/-1 validation of the two limit variables, and re-add the corresponding contract assertions in tests/test_required_workflow_queue_contract.py.
Open in Devin Review

Was this helpful? React with πŸ‘ or πŸ‘Ž to provide feedback.

--stale-opencode-minutes "$STALE_OPENCODE_MINUTES"
--merge-mode "$ORG_SWEEP_MERGE_MODE"
)
Expand All @@ -877,11 +847,6 @@ jobs:
sweep_rc=$?
set -e
printf '%s\n' "$sweep_output"
repo_review_dispatches="$(printf '%s\n' "$sweep_output" | grep -Ec '^PR #[0-9]+: (review_dispatch|security_dispatch):' || true)"
repo_branch_updates="$(printf '%s\n' "$sweep_output" | grep -Ec '^PR #[0-9]+: (update_branch|restamp_head):' || true)"
org_review_dispatches_used=$((org_review_dispatches_used + repo_review_dispatches))
org_branch_updates_used=$((org_branch_updates_used + repo_branch_updates))
echo "Org sweep budget consumed: review dispatches=${org_review_dispatches_used}/${ORG_SWEEP_REVIEW_DISPATCH_LIMIT}, branch updates=${org_branch_updates_used}/${ORG_SWEEP_BRANCH_UPDATE_LIMIT}."
if [ "$sweep_rc" -ne 0 ]; then
# A structural access denial ("Resource not accessible by
# integration") means the sweep credential cannot read this
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/python-security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ jobs:
actions: read
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- name: Checkout
Expand Down Expand Up @@ -215,7 +215,7 @@ jobs:
contents: read
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- name: Checkout
Expand Down
31 changes: 0 additions & 31 deletions .github/workflows/quarantine-sandbox-hourly-review-repair.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/sast-semgrep.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
SEMGREP_SEND_METRICS: "off"
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- name: Checkout
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/scheduled-security-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ jobs:
matrix: ${{ fromJSON(needs.detect-languages.outputs.matrix) }}
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- name: Checkout
Expand All @@ -109,7 +109,7 @@ jobs:
actions: read
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- name: Checkout
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/secret-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
GITLEAKS_SHA256: "551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb"
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- name: Checkout (full history for schedule/push, base+head for PR)
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/strix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ jobs:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
steps:
- name: Harden runner
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
disable-file-monitoring: true
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/trusted-uv-materializer-quality-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
timeout-minutes: 10
steps:
- name: Harden runner
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit

Expand Down Expand Up @@ -89,7 +89,7 @@ jobs:
timeout-minutes: 20
steps:
- name: Harden runner
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit

Expand Down
4 changes: 4 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,7 @@
**Vulnerability:** Command Injection
**Learning:** Fixing a `shell=True` vulnerability by replacing it with `shell=False` and wrapping the command string in `["/bin/bash", "-lc", command]` is incomplete and still leaves the code vulnerable to shell injection. It acts as security theater, as it misleads linters while executing untrusted input via the bash wrapper. The vulnerability was still present in `sandboxed_web_e2e.py`.
**Prevention:** Remove `/bin/bash` wrapper from `subprocess` calls in CI scripts. Always use `shlex.split(command)` to safely parse strings into a list of arguments and pass the list directly to `subprocess.Popen` or `subprocess.run`.
## 2026-08-20 - Prevent SSRF via Readiness URL Validation
**Vulnerability:** Server-Side Request Forgery (SSRF) / Internal Network Scanning
**Learning:** Functions designed to poll "readiness" URLs (like `wait_for_url` in CI scripts) can be manipulated to scan internal networks or cloud metadata APIs if they only validate the URL scheme (`http`/`https`) and neglect to restrict the host. A malicious payload can supply an internal IP, and the script will confirm its existence or status.
**Prevention:** When implementing readiness probes or fetching dynamically provided URLs to verify service availability, explicitly restrict the allowed hostnames to localhost (`localhost`, `127.0.0.1`, `::1`) using `urllib.parse.urlparse` to prevent SSRF vulnerabilities and internal network scanning.
2 changes: 0 additions & 2 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,6 @@ trusted `uv` exporter is downloaded from the literal GitHub Releases URL for
ecosystem.
- [`docs/agent-github-project-protocol.md`](docs/agent-github-project-protocol.md)
β€” Project #1 operation.
- [`docs/pr-review-and-merge-procedure.md`](docs/pr-review-and-merge-procedure.md)
β€” bot/agent exact-head review and merge procedure.
- [`PR_GOVERNANCE_AUDIT.md`](PR_GOVERNANCE_AUDIT.md) β€” live review/merge
contract.
- [`docs/doctoring/hourly-nvidia-nim-autofix.md`](docs/doctoring/hourly-nvidia-nim-autofix.md)
Expand Down
Loading
Loading