feat(strix): documented accepted-risk suppression (<= MEDIUM, never HIGH/CRITICAL)#609
Open
seonghobae wants to merge 5 commits into
Open
feat(strix): documented accepted-risk suppression (<= MEDIUM, never HIGH/CRITICAL)#609seonghobae wants to merge 5 commits into
seonghobae wants to merge 5 commits into
Conversation
…IGH/CRITICAL)
Adds a per-finding accepted-risk mechanism so a scanned repository can
document a specific, reasoned by-design finding and stop it from hard-failing
the required gate — without weakening enforcement for genuine issues.
Declaration lives in the scanned repo at .security/strix-accepted-risks.txt,
one entry per line: `SEVERITY | title-substring | reason`. A finding is
suppressed only when ALL hold:
- its severity is at or below STRIX_MAX_SUPPRESSIBLE_SEVERITY (default
MEDIUM) — HIGH and CRITICAL are never suppressible;
- the entry's own declared severity is within that ceiling and >= the
finding severity;
- the finding title contains the entry substring; and
- the entry carries a non-empty reason.
Every suppression is emitted as a ::warning (title + reason) so it is
auditable in the required check output, and the declaration is part of the
PR diff so adding/loosening it is reviewable.
The skip is wired into all three finding-blocking verdict paths
(evaluate_pull_request_findings, has_blocking_vulnerability_reports,
has_unmapped_threshold_report), and the console-log fallback in
evaluate_pull_request_findings now only re-derives severity when NO
per-finding reports exist — so accepted per-finding reports are not
resurrected from the aggregate log. The declaration is read from the PR head
(trusted) with a checkout fallback.
Tests: static assertions for the caps/wiring/fallback guard, plus a
functional matcher test proving a documented MEDIUM is suppressed while a
title-matching HIGH and an undeclared MEDIUM both still block.
Motivating case: ContextualWisdomLab/gyeot#11 VULN-0008 (on-device SQLite
at-rest plaintext), a documented on-device-first design tradeoff.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds an “accepted risk” suppression mechanism to the Strix quick gate so repositories can document specific by-design findings (capped at <= MEDIUM) and avoid hard-failing required checks, while keeping HIGH/CRITICAL findings unsuppressible and auditable.
Changes:
- Introduces
STRIX_MAX_SUPPRESSIBLE_SEVERITYand.security/strix-accepted-risks.txtparsing + matching to suppress documented findings (with reason) and emit an audit::warning. - Wires suppression into all finding-blocking verdict paths and tightens the console-log fallback so aggregate logs don’t resurrect already-evaluated per-finding reports.
- Extends the Strix gate self-test harness with assertions for wiring and functional matching behavior.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| scripts/ci/strix_quick_gate.sh | Implements accepted-risk declaration reading, matching, logging, and integrates it into the gate’s verdict paths and fallback behavior. |
| scripts/ci/test_strix_quick_gate.sh | Adds contract + functional tests ensuring suppression wiring and expected MEDIUM/HIGH behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Addresses #609 review (Copilot): - Glob injection: the declared substring was used in a [[ == *"$s"* ]] pattern, so glob metacharacters (*, ?, [) in .security/strix-accepted-risks .txt could broaden the match. Switch to a fixed-string grep -F so a declared substring matches literally and can never over-match (a lone '*' now matches only titles containing an asterisk, not all findings). - Workflow-command injection: the ::warning message embedded the finding title and repo-supplied reason unescaped. Add escape_workflow_command_ message (%, CR, LF -> %25/%0D/%0A) so untrusted content cannot break the command format or inject additional workflow commands into the Actions log. - Reword the misleading "trusted" comment: PR-head blobs are immutable for the run but remain untrusted PR-controlled data, consistent with how the rest of this script treats them. Functional test extended with a bare-'*' declaration that must not match a non-asterisk title, locking in the literal-match fix. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (1)
scripts/ci/strix_quick_gate.sh:2046
- The
::warningmessage escapes the (untrusted) finding title and accepted-risk reason, but it interpolatesSTRIX_ACCEPTED_RISKS_PATHwithout escaping. If this value ever contains%, CR, or LF (e.g. via environment/config), it could break the workflow command format or inject additional commands. Escaping it keeps the workflow-command hardening consistent.
local safe_title safe_reason
safe_title="$(escape_workflow_command_message "$finding_title")"
safe_reason="$(escape_workflow_command_message "$entry_reason")"
echo "::warning title=Strix accepted risk::Suppressing documented accepted-risk finding (${entry_severity}) '${safe_title}' — reason: ${safe_reason}. HIGH/CRITICAL findings are never suppressible; see ${STRIX_ACCEPTED_RISKS_PATH}." >&2
return 0
seonghobae
enabled auto-merge
July 21, 2026 07:28
seonghobae
disabled auto-merge
July 21, 2026 07:28
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.
목적
스캔 대상 repo가 설계상 수용된(by-design) 특정 finding을 사유와 함께 문서화해 필수 게이트가 그것 때문에 hard-fail 하지 않게 하되, 진짜 이슈에 대한 강제력은 그대로 유지하는 accepted-risk 억제 기구.
안전 설계
STRIX_MAX_SUPPRESSIBLE_SEVERITY(기본 MEDIUM). VULN-0008이 MEDIUM.::warning(제목+사유)로 로깅 → 필수 체크 출력에서 감사 가능..security/strix-accepted-risks.txt는 PR diff에 포함 → 추가·완화가 리뷰 대상. PR head(신뢰)에서 읽고 체크아웃 폴백.구현
evaluate_pull_request_findings,has_blocking_vulnerability_reports,has_unmapped_threshold_report) — 한 경로만 고치면 다른 경로가 재차단하므로 일관 처리.evaluate_pull_request_findings의 콘솔-로그 폴백은 이제 per-finding 리포트가 하나도 없을 때만 severity 재도출 → 억제된 per-finding이 집계 로그에서 되살아나지 않음.테스트
동기 사례
ContextualWisdomLab/gyeot#11VULN-0008(온디바이스 SQLite at-rest 평문) — README가 "서버 미전송"만 약속하고 기기 내 암호화는 미약속인, 문서화된 on-device-first 설계 트레이드오프.🤖 Generated with Claude Code