@aegis-scan/skills 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/ATTRIBUTION.md +71 -20
  2. package/CHANGELOG.md +43 -0
  3. package/README.md +66 -18
  4. package/dist/commands/install.d.ts.map +1 -1
  5. package/dist/commands/install.js +17 -1
  6. package/dist/commands/install.js.map +1 -1
  7. package/package.json +3 -2
  8. package/sbom.cdx.json +1 -0
  9. package/skills/compliance/aegis-native/brutaler-anwalt/SKILL.md +305 -0
  10. package/skills/compliance/aegis-native/brutaler-anwalt/references/abmahn-templates.md +306 -0
  11. package/skills/compliance/aegis-native/brutaler-anwalt/references/aegis-integration.md +241 -0
  12. package/skills/compliance/aegis-native/brutaler-anwalt/references/audit-patterns.md +277 -0
  13. package/skills/compliance/aegis-native/brutaler-anwalt/references/bgh-urteile.md +167 -0
  14. package/skills/compliance/aegis-native/brutaler-anwalt/references/branchenrecht.md +285 -0
  15. package/skills/compliance/aegis-native/brutaler-anwalt/references/checklisten.md +276 -0
  16. package/skills/compliance/aegis-native/brutaler-anwalt/references/dsgvo.md +238 -0
  17. package/skills/compliance/aegis-native/brutaler-anwalt/references/international.md +163 -0
  18. package/skills/compliance/aegis-native/brutaler-anwalt/references/it-recht.md +267 -0
  19. package/skills/compliance/aegis-native/brutaler-anwalt/references/strafrecht-steuer.md +193 -0
  20. package/skills/compliance/aegis-native/brutaler-anwalt/references/vertragsrecht.md +243 -0
  21. package/skills/defensive/README.md +33 -4
  22. package/skills/defensive/aegis-native/rls-defense/SKILL.md +174 -0
  23. package/skills/defensive/aegis-native/ssrf-defense/SKILL.md +179 -0
  24. package/skills/defensive/aegis-native/tenant-isolation-defense/SKILL.md +225 -0
  25. package/skills/mitre-mapped/README.md +36 -8
  26. package/skills/mitre-mapped/aegis-native/mapping-overview/SKILL.md +129 -0
  27. package/skills/mitre-mapped/aegis-native/t1078-valid-accounts/SKILL.md +136 -0
  28. package/skills/mitre-mapped/aegis-native/t1190-exploit-public-app/SKILL.md +108 -0
  29. package/skills/ops/README.md +39 -4
  30. package/skills/ops/aegis-native/escalation-runbook/SKILL.md +147 -0
  31. package/skills/ops/aegis-native/suppress-correctly/SKILL.md +196 -0
  32. package/skills/ops/aegis-native/triage-finding/SKILL.md +144 -0
@@ -1,6 +1,41 @@
1
- # Operations Skills
1
+ # Operations Skills — `ops/`
2
2
 
3
- Reserved for incident-response, post-build-audit, and verify-install-
4
- integrity skill modules. Target: `skills-v0.3+`.
3
+ Operational runbooks for the AEGIS workflow itself — how to triage
4
+ findings, when to suppress, when to escalate, how to respond to
5
+ exploited vulnerabilities. These skills wrap the AEGIS CLI + reporters
6
+ in process-discipline so teams use AEGIS consistently rather than
7
+ ad-hoc.
5
8
 
6
- Scope and sources TBD. AEGIS-native authoring anticipated.
9
+ ## Sources
10
+
11
+ | Source dir | License | Skills |
12
+ |---|---|---|
13
+ | `aegis-native/` | MIT (AEGIS-original) | 3 |
14
+
15
+ ## AEGIS-native skills
16
+
17
+ | Skill | When to use |
18
+ |---|---|
19
+ | `triage-finding` | Receiving a new AEGIS finding (PR comment, JSON, SARIF). Triage decision tree: severity → confidence → verify → fix-vs-suppress-vs-defer. |
20
+ | `suppress-correctly` | About to add a suppression; reviewing existing suppressions for staleness; auditing suppressions before a security review. Three legitimate cases + anti-patterns + audit-trail expectations. |
21
+ | `escalation-runbook` | A BLOCKER reached `main`; a finding suggests active exploitation; a credential leak detected; a suppression has been gamed. Severity ladders, immediate-containment playbook, notification triggers, post-incident review structure. |
22
+
23
+ License: MIT. See top-level [`ATTRIBUTION.md`](../../ATTRIBUTION.md) for
24
+ attribution chain.
25
+
26
+ ## Roadmap
27
+
28
+ Future expansions:
29
+
30
+ - `evidence-gathering` — collect evidence for review when AEGIS surfaces a real finding.
31
+ - `false-positive-handling` — FP triage workflow + scanner-rule refinement feedback loop.
32
+ - `post-incident-review` — review-meeting structure after a security incident.
33
+ - `fix-mode-discipline` — operational discipline around `aegis fix` (LLM-driven remediation safety).
34
+ - `compliance-audit-prep` — preparing AEGIS evidence for SOC 2 / ISO 27001 / PCI-DSS audits.
35
+ - `ci-gating-tuning` — when to fail the build vs warn vs annotate.
36
+
37
+ ## See also
38
+
39
+ - AEGIS suppressions docs — `docs/suppressions.md`.
40
+ - AEGIS confidence-rules — top-level `README.md` § "Scoring".
41
+ - AEGIS incident-response convention — top-level `SECURITY-INCIDENT-RESPONSE.md`.
@@ -0,0 +1,147 @@
1
+ <!-- aegis-local: AEGIS-native skill, MIT-licensed; escalation runbook for severe AEGIS findings. -->
2
+
3
+ ---
4
+ name: ops-escalation-runbook
5
+ description: "Escalation runbook for severe AEGIS findings — what to do when a BLOCKER reaches main, when a finding suggests active exploitation, when a credential leak is detected, or when a suppression has been gamed. Covers immediate-containment steps, internal communication, legal/compliance notification triggers, post-incident review structure, and the AEGIS-specific forensic tooling. Use when responding to a high-severity AEGIS finding outside normal triage."
6
+ ---
7
+
8
+ # Escalation Runbook — Severe AEGIS Findings
9
+
10
+ ## When to use this skill
11
+
12
+ You are escalating one of:
13
+
14
+ - A BLOCKER finding has reached `main` (failed CI gate, was force-merged, or AEGIS was bypassed).
15
+ - A finding suggests active exploitation (credential leak in source, public-key/private-key pair leaked, hardcoded admin password in production code).
16
+ - An AEGIS suppression has been gamed (review found a "FP" suppression covering a real vulnerability).
17
+ - A new scanner update has produced findings on previously-shipping code (regression in coverage).
18
+
19
+ ## Severity ladders — when to escalate
20
+
21
+ | Trigger | Escalate to | Within |
22
+ |---|---|---|
23
+ | BLOCKER on main | sec-team-lead + module owner | 1 hour |
24
+ | Credential leaked in source (jwt-detector / entropy-scanner) | sec-team-lead, IT ops, vendor-mgmt (if vendor cred) | 30 min — rotate IMMEDIATELY |
25
+ | RLS / tenant-isolation finding suggesting cross-tenant exposure | sec-team-lead, legal, DPO | 1 hour |
26
+ | GDPR-engine finding involving production PII handling | sec-team-lead, DPO, legal | 4 hours, GDPR Art. 33 timer starts |
27
+ | Multiple new BLOCKERs after a scanner-rule update (regression) | sec-team-lead | 2 hours |
28
+ | Suppression-gaming detected during audit | sec-team-lead + module owner + author of suppression | 24 hours |
29
+
30
+ If you're not sure whether to escalate — escalate. False alarms cost you 30 minutes; missed escalations cost you a breach.
31
+
32
+ ## Immediate-containment playbook (post-finding)
33
+
34
+ Order matters. Don't skip steps.
35
+
36
+ ### Step 1 — Stop the bleeding
37
+
38
+ For active-exposure findings:
39
+
40
+ ```
41
+ Credential leaked → rotate the credential RIGHT NOW; don't wait to investigate
42
+ Auth-bypass on prod → block the affected route at the WAF / load balancer
43
+ RLS bypass → disable the affected query at the gateway, NOT in code (deploy lag is a window)
44
+ ```
45
+
46
+ The runtime-stop happens BEFORE code-fix because deploys take time and the finding is publicly visible the moment AEGIS surfaces it.
47
+
48
+ ### Step 2 — Assess reach
49
+
50
+ ```bash
51
+ # What did this credential / route / query touch in the last N days?
52
+ aegis history . --blame --since "30 days ago"
53
+
54
+ # Forensic logs — pull the affected window
55
+ # (project-specific — ingestion logs, audit logs, app logs)
56
+ ```
57
+
58
+ Bound the exposure: which users? which data classes? which time range? The answer drives notification scope.
59
+
60
+ ### Step 3 — Patch and verify
61
+
62
+ 1. Code-fix per the appropriate defensive skill (`defensive-rls-defense`, `defensive-tenant-isolation`, `defensive-ssrf`, etc.).
63
+ 2. Add a regression test that the fix prevents re-exploitation.
64
+ 3. Re-deploy.
65
+ 4. Verify the runtime-stop can be lifted (the WAF block / route disable from Step 1).
66
+
67
+ ### Step 4 — Notify
68
+
69
+ | Trigger | Notification |
70
+ |---|---|
71
+ | PII exposure | GDPR Art. 33: 72 hours to supervisory authority. CCPA equivalent for CA residents. |
72
+ | Cardholder data exposure | PCI-DSS req 12.10 — incident response plan kicks in. |
73
+ | Vendor credentials leaked | Notify the vendor immediately — they need to rotate on their side. |
74
+ | Material breach | SEC rule 1.05 (4-day disclosure window for material cybersecurity incidents). |
75
+ | User credentials leaked | Notify affected users; recommend password change. |
76
+
77
+ If unsure whether a notification trigger applies, consult legal counsel before notifying. Premature disclosure of an unconfirmed incident has its own risks.
78
+
79
+ ### Step 5 — Post-incident review (within 7 days)
80
+
81
+ Structure:
82
+
83
+ 1. **Timeline** — when was the vulnerable code introduced (use `git blame`); when was AEGIS run on it; when did AEGIS first flag it; when was it triaged; when was it merged; when was it discovered.
84
+ 2. **Root cause** — code-level + process-level. "We bypassed the AEGIS gate because we were rushing the release" is a legitimate process root cause.
85
+ 3. **Impact** — who/what was exposed, for how long.
86
+ 4. **Action items** — code fix (already done), process fix (e.g., revoke `--no-verify` permission, mandate sec-team review for any AEGIS-bypass), tooling fix (e.g., scanner-rule that would have caught this earlier).
87
+
88
+ The review document goes to a permanent location (security-incident log) and gets auditor-readable for the next compliance review.
89
+
90
+ ## When AEGIS is the alerting source
91
+
92
+ AEGIS is a SAST + light DAST tool. It surfaces findings in:
93
+
94
+ - PR comments (CI integration)
95
+ - SARIF (GitHub Code Scanning)
96
+ - Terminal / JSON (`aegis scan` direct output)
97
+ - MCP server (AI-coding-agent surface)
98
+
99
+ When a finding ESCALATES to incident-level, AEGIS is the source of the lead, not the source of truth. The source of truth is the runtime evidence:
100
+
101
+ - Audit logs from the affected service.
102
+ - Cloud provider logs (CloudTrail, Cloud Audit Logs, Activity Logs).
103
+ - DB query logs.
104
+ - WAF / proxy logs.
105
+
106
+ Cross-reference the AEGIS finding with these to determine whether code-vulnerable + actually-exploited.
107
+
108
+ ## When AEGIS finds a regression in coverage (post-update)
109
+
110
+ If a scanner-rule update triggers new findings on shipping code, the situation is:
111
+
112
+ - The shipping code was previously vulnerable.
113
+ - AEGIS is now telling you about it.
114
+ - The exposure window is everything-since-the-vulnerable-code-shipped, NOT since-the-scanner-update.
115
+
116
+ Treat as a real finding (not as scanner noise). The right response:
117
+
118
+ 1. Verify (per `ops-triage-aegis-finding`) — false positive, or real?
119
+ 2. If real, escalate per the severity ladder above.
120
+ 3. Code-fix.
121
+ 4. Post-incident review specifically asks: "why did the previous scanner version miss this?" (and: "what other patterns might it still miss?").
122
+
123
+ ## Anti-patterns
124
+
125
+ ### Anti-pattern 1 — "It's been there forever, can't be that bad"
126
+
127
+ Tenure does not establish safety. SQL injection that's been in the codebase for 4 years is exactly as exploitable as one introduced yesterday — the attacker doesn't care about the tenure.
128
+
129
+ ### Anti-pattern 2 — "Wait for next sprint"
130
+
131
+ For BLOCKERS and credential leaks, "next sprint" is unacceptable. The exposure is active until you fix it.
132
+
133
+ ### Anti-pattern 3 — Suppress under pressure
134
+
135
+ A pressured "suppress to ship" decision is exactly when post-incident reviews most often find process root causes. Resist; document; if you must bypass AEGIS, do it explicitly with the sec-team-lead's signature, time-boxed, and post-incident-reviewed.
136
+
137
+ ### Anti-pattern 4 — Silent fix
138
+
139
+ Fixing a BLOCKER with a one-line PR titled "small fix" hides the incident from future audit. Use a clear PR title (`fix(security): SQL-injection in /api/foo route`); cross-reference the post-incident review document.
140
+
141
+ ## See also
142
+
143
+ - `ops-triage-aegis-finding` — the upstream triage decision.
144
+ - `ops-suppress-correctly` — when suppression is the right call (it isn't, in escalation context).
145
+ - `defensive-rls-defense` / `defensive-tenant-isolation` / `defensive-ssrf` — domain-specific patch playbooks.
146
+ - AEGIS `SECURITY-INCIDENT-RESPONSE.md` — the project's own incident-response convention.
147
+ - GDPR Art. 33 — https://gdpr-info.eu/art-33-gdpr/
@@ -0,0 +1,196 @@
1
+ <!-- aegis-local: AEGIS-native skill, MIT-licensed; operational runbook for suppressing AEGIS findings correctly. -->
2
+
3
+ ---
4
+ name: ops-suppress-correctly
5
+ description: "Operational runbook for suppressing AEGIS findings correctly. Covers when suppression is appropriate (verified FP, compensating control, accepted risk), the per-finding suppression syntax, the config-level suppression syntax, common anti-patterns, suppression-decay (review cadence), and the audit trail expectations. Use when adding any suppression, reviewing an existing suppression, or auditing suppressions for staleness."
6
+ ---
7
+
8
+ # Suppress Correctly — AEGIS Suppression Runbook
9
+
10
+ ## When to use this skill
11
+
12
+ - About to add a suppression — understand the policy + format first.
13
+ - Reviewing existing suppressions for staleness.
14
+ - Auditing suppressions before a security review or compliance audit.
15
+ - A scanner-rule update has produced new findings on previously-suppressed code.
16
+
17
+ ## The three legitimate suppression cases
18
+
19
+ A suppression is appropriate ONLY in these cases. Anything else is gaming the score.
20
+
21
+ ### Case 1 — Verified false positive
22
+
23
+ The scanner over-matched. Your verification (per `ops-triage-finding`) showed the code is safe. The right next steps:
24
+
25
+ 1. Add the suppression with a one-line rationale.
26
+ 2. **File a scanner-rule refinement issue** — link it from the rationale. AEGIS improves precision on real-world FPs; the issue is the feedback loop.
27
+ 3. Optionally add a regression-test fixture that captures this specific FP shape.
28
+
29
+ ```typescript
30
+ // aegis-disable: ssrf-checker — URL is hard-coded to api.partner.com after the line-38 allowlist check. Verified safe 2026-04-22, refinement issue #1234.
31
+ await fetch(allowlistedUrl);
32
+ ```
33
+
34
+ ### Case 2 — Compensating control elsewhere
35
+
36
+ The code is vulnerable in isolation but safe in context. The compensating control lives outside the scanner's view (often runtime: a WAF rule, a proxy header strip, a network-level deny).
37
+
38
+ ```typescript
39
+ // aegis-disable: auth-enforcer — endpoint runs behind internal-only ingress (network-level deny on public traffic). Compensating control: ingress.yaml line 47.
40
+ export async function GET() {
41
+ /* ... */
42
+ }
43
+ ```
44
+
45
+ The rationale MUST identify the compensating control's location precisely. "We have a firewall" is not enough; "ingress.yaml line 47" is.
46
+
47
+ ### Case 3 — Accepted risk (risk-register documented)
48
+
49
+ The team has formally accepted this risk class. There's a risk register entry (in your tracking system, ideally). The suppression references the entry.
50
+
51
+ ```typescript
52
+ // aegis-disable: rate-limit-checker — accepted risk per risk-register entry RR-2026-Q2-04 (internal admin tool, low traffic, MFA-required). Owner: sec-team. Review: 2026-Q3.
53
+ ```
54
+
55
+ The risk-register entry must include: risk description, accepting authority (CISO / sec-team-lead), review date, compensating controls.
56
+
57
+ ## Anti-patterns
58
+
59
+ ### Anti-pattern 1 — Naked suppression
60
+
61
+ ```typescript
62
+ // aegis-disable: ssrf-checker
63
+ await fetch(userInput);
64
+ ```
65
+
66
+ Why it's wrong: no rationale. The next reviewer can't tell whether this is a real FP, a compensating control, or just noise-silencing. Fail.
67
+
68
+ ### Anti-pattern 2 — Vague rationale
69
+
70
+ ```typescript
71
+ // aegis-disable: ssrf-checker — safe
72
+ await fetch(userInput);
73
+ ```
74
+
75
+ Why it's wrong: "safe" is an assertion without justification. The reviewer needs to know WHY it's safe.
76
+
77
+ ### Anti-pattern 3 — Wholesale-disable a scanner
78
+
79
+ ```json
80
+ // aegis.config.json
81
+ {
82
+ "scanners": {
83
+ "ssrf-checker": false
84
+ }
85
+ }
86
+ ```
87
+
88
+ Why it's wrong: turns off the scanner globally. One real bug in 10K lines and you've exposed the entire codebase. Always suppress per-finding, not per-scanner.
89
+
90
+ ### Anti-pattern 4 — Suppress to ship
91
+
92
+ If a BLOCKER finding is the only thing blocking a release and the team's response is "suppress it", you're not triaging — you're hiding a real exposure under a permanent rug. The right move: fix the BLOCKER. If you genuinely cannot, file an emergency risk-register entry with the CISO's signature and a 7-day-fix deadline.
93
+
94
+ ### Anti-pattern 5 — Long-lived TODO suppressions
95
+
96
+ ```typescript
97
+ // aegis-disable: xss-checker — TODO fix after refactor
98
+ ```
99
+
100
+ If the suppression has a "TODO" the rationale already concedes the code is wrong. The "TODO" rots over years. Do not. Either fix it now, or risk-register-accept it formally.
101
+
102
+ ## Suppression syntax
103
+
104
+ ### Inline (single finding at a specific line)
105
+
106
+ ```typescript
107
+ // aegis-disable: <scanner-name> — <rationale + date + owner>
108
+ <the line being suppressed>
109
+ ```
110
+
111
+ The directive applies to the next non-comment line. Place it directly above the offending code. If the scanner emits at a multi-line statement, the directive on the first line covers the whole statement.
112
+
113
+ ### Config-level (persistent suppressions across scans)
114
+
115
+ ```json
116
+ {
117
+ "suppressions": [
118
+ {
119
+ "scanner": "ssrf-checker",
120
+ "file": "lib/internal-fetch.ts",
121
+ "line": 42,
122
+ "rationale": "<rationale + date + owner>",
123
+ "owner": "sec-team",
124
+ "added": "2026-04-22",
125
+ "review_by": "2026-10-22"
126
+ }
127
+ ]
128
+ }
129
+ ```
130
+
131
+ Use config-level when:
132
+
133
+ - The finding emits at multiple lines (file-level suppression cleaner than 5 inline directives).
134
+ - The file is auto-generated (you can't add inline comments without breaking the generator).
135
+ - You need centralized auditability (the config is one diff to review, not 20 inline diffs).
136
+
137
+ ### Pattern-level (suppress a class of findings across many files)
138
+
139
+ Avoid this except for canonical platform-wide compensating controls. If you must:
140
+
141
+ ```json
142
+ {
143
+ "suppressions": [
144
+ {
145
+ "scanner": "header-checker",
146
+ "filePattern": "**/*.test.ts",
147
+ "rationale": "Test files do not serve HTTP — header-checker N/A. Reviewed 2026-04-22 by sec-team."
148
+ }
149
+ ]
150
+ }
151
+ ```
152
+
153
+ The `filePattern` field uses glob syntax. Be conservative; pattern-suppressions hide whole classes of findings.
154
+
155
+ ## Review cadence — suppressions decay
156
+
157
+ Every suppression has an implicit "decay date" — code changes, the surrounding context shifts, the compensating control gets removed. AEGIS supports a `review_by` field; suppressions past their `review_by` get a `[STALE]` flag in the report.
158
+
159
+ Recommended cadence:
160
+
161
+ - **Inline suppressions** — review at the next major refactor of the affected file.
162
+ - **Config-level suppressions** — review every 6 months minimum.
163
+ - **Pattern-level suppressions** — review every 3 months.
164
+
165
+ `aegis history . --blame --suppressions` enumerates all suppressions with age + last-reviewed date.
166
+
167
+ ## Audit trail expectations
168
+
169
+ Every suppression should answer 5 questions for the next reviewer:
170
+
171
+ 1. **Why is this safe?** (the rationale)
172
+ 2. **What compensating control covers it?** (the location of the compensating control)
173
+ 3. **Who decided?** (the owner team or individual)
174
+ 4. **When was it added?** (the date)
175
+ 5. **When does it need re-review?** (the review-by date)
176
+
177
+ Suppressions that don't answer these 5 questions are technical debt.
178
+
179
+ ## Compliance audit considerations
180
+
181
+ Auditors (SOC 2, ISO 27001, PCI-DSS) will ask:
182
+
183
+ - "Show me your suppressions."
184
+ - "Why is this one suppressed?"
185
+ - "Who approved it?"
186
+ - "When was it last reviewed?"
187
+ - "What's your stale-suppression review process?"
188
+
189
+ If your answer to any of these is "we don't track that" — you're failing audit. The structured-rationale pattern above is the audit-ready shape.
190
+
191
+ ## See also
192
+
193
+ - `ops-triage-aegis-finding` — the upstream decision: fix or suppress.
194
+ - `ops-escalation-runbook` — what to do when suppressions are gamed.
195
+ - AEGIS suppressions docs — `docs/suppressions.md`.
196
+ - AEGIS scanner-rule refinement issue tracker — file FPs as actionable feedback.
@@ -0,0 +1,144 @@
1
+ <!-- aegis-local: AEGIS-native skill, MIT-licensed; operational runbook for triaging an AEGIS finding. -->
2
+
3
+ ---
4
+ name: ops-triage-aegis-finding
5
+ description: "Operational runbook for triaging an AEGIS finding. Covers severity-priority, evidence verification, false-positive determination, fix-vs-suppress decision-tree, ownership routing, and SLA expectations. Use when receiving a new AEGIS finding (PR comment, JSON output, SARIF in code-scanning), reviewing a backlog of findings, or onboarding a team to AEGIS workflow."
6
+ ---
7
+
8
+ # Triage an AEGIS Finding — Operational Runbook
9
+
10
+ ## When to use this skill
11
+
12
+ - A PR has new AEGIS findings and you need to decide what to fix vs accept vs defer.
13
+ - You're reviewing the AEGIS backlog (existing findings on main).
14
+ - You're onboarding a new team member to the AEGIS triage workflow.
15
+ - An AEGIS finding has been disputed and you need a structured re-triage.
16
+
17
+ ## The triage decision tree
18
+
19
+ ```
20
+ For each finding:
21
+ 1. Severity check
22
+ ├── BLOCKER → Stop the line; fix before merge.
23
+ ├── HIGH → Fix in this sprint; backlog with deadline.
24
+ ├── MEDIUM → Triage: fix / suppress-with-reason / defer.
25
+ └── LOW → Triage: fix-when-touching-the-code / suppress-with-reason.
26
+
27
+ 2. Confidence check
28
+ ├── high → Trust the finding.
29
+ ├── medium → Verify before deciding. ~30% FP-rate at this level historically.
30
+ └── low → Always verify. >50% FP-rate. Many low-confidence findings exist because external tools were missing.
31
+
32
+ 3. Verification
33
+ - Open the file at the finding's line range
34
+ - Read the code; reproduce the vulnerable shape mentally
35
+ - If you can't reproduce → likely FP, suppress with rationale
36
+ - If you can reproduce → it's a real finding
37
+
38
+ 4. Decision
39
+ ├── Fix → Default for BLOCKER + verified-real findings
40
+ ├── Suppress → Verified FP or compensating control elsewhere
41
+ ├── Defer → Real but non-blocker, scheduled in backlog with owner + deadline
42
+ └── Dispute → Open issue requesting scanner-rule refinement
43
+ ```
44
+
45
+ ## Severity is not optional
46
+
47
+ AEGIS uses 4 severity levels: BLOCKER / HIGH / MEDIUM / LOW. **BLOCKER and CRITICAL are semantically equivalent**, both forcing the score to 0 / grade F.
48
+
49
+ Examples:
50
+
51
+ - BLOCKER — eval injection, hardcoded production secret, unauthed admin route, SQL injection on unscoped query.
52
+ - HIGH — missing CSRF on mutation, missing rate-limit on auth endpoint, weak crypto.
53
+ - MEDIUM — header missing, unstructured logging, missing pagination.
54
+ - LOW — debug artifact, minor doc gap.
55
+
56
+ If you're triaging a BLOCKER and considering "defer", **stop**. BLOCKERs are by definition not deferrable. Either it's actually a BLOCKER (fix it now) or it's been mis-classified (file a scanner-rule refinement issue).
57
+
58
+ ## Confidence is the FP-rate signal
59
+
60
+ AEGIS findings carry `confidence: 'high' | 'medium' | 'low'`. The signal:
61
+
62
+ - **high (default)** — scanner has high confidence based on per-CWE rules. Trust it, fix it.
63
+ - **medium** — scanner has reasonable confidence, but the rule's per-CWE FP-rate hasn't been measured at scale. Common for cross-file taint (today). Verify before fixing.
64
+ - **low** — scanner ran without one or more external tools (e.g., Semgrep not installed). The finding may be incomplete; the report shows a `[LOW-CONFIDENCE]` PR badge.
65
+
66
+ Always inspect the finding's source code before suppressing a `medium` or `low` confidence finding.
67
+
68
+ ## How to verify a finding (15-minute drill)
69
+
70
+ For each finding:
71
+
72
+ 1. **Read the rule.** AEGIS's README scanner inventory tells you what each scanner detects. If the rule description matches the code, it's likely real.
73
+ 2. **Read the code.** Open the file, read 10 lines above + below the flagged line. Mental model: "could an attacker make this code do something the author didn't intend?".
74
+ 3. **Trace the data flow.** Where does the vulnerable input come from? Where does it end up (the sink)? Are there sanitizers in between?
75
+ 4. **Check the per-CWE sanitizer awareness.** AEGIS doesn't false-positive on `parseInt` blocking SQLi, `DOMPurify` blocking XSS, etc. If a sanitizer exists and AEGIS still flags, either the sanitizer doesn't cover this CWE, or there's a real gap.
76
+ 5. **Reproduce mentally.** Walk through an attacker payload in your head. If you can construct one, fix the code. If you can't, it's likely a FP.
77
+
78
+ ## Fix-vs-suppress decision
79
+
80
+ **Fix** is the default. Suppress is for these specific cases:
81
+
82
+ 1. **Verified FP** — your verification showed the code is safe; AEGIS over-matched. Suppress with rationale; file a scanner-rule refinement issue.
83
+ 2. **Compensating control elsewhere** — the code is vulnerable in isolation but safe in context (e.g., a route is auth-bypass-prone in source, but lives behind a proxy that strips auth-bypass headers). Suppress with rationale; document the compensating control's location.
84
+ 3. **Architectural decision documented as risk-accepted** — the team has decided this risk class is accepted (e.g., "internal admin tool, accept lower auth bar"). Document in a risk register; suppress with reference.
85
+
86
+ Never suppress to silence noise without one of the above.
87
+
88
+ ## Ownership routing
89
+
90
+ | Finding category | Default owner |
91
+ |---|---|
92
+ | Security (BLOCKER + HIGH) | security team |
93
+ | Compliance (gdpr-engine, soc2-checker, etc.) | security + compliance |
94
+ | Quality (logging-checker, console-checker, http-timeout-checker) | the owning team / module owner |
95
+ | i18n | frontend team |
96
+ | Dependencies (supply-chain, dep-confusion-checker) | platform / infra team |
97
+
98
+ Wire ownership in `aegis.config.json`'s notification channels per category, or in your team's CODEOWNERS.
99
+
100
+ ## SLA defaults
101
+
102
+ The AEGIS-recommended SLA defaults (these are guidelines, not enforced):
103
+
104
+ | Severity | Time-to-fix |
105
+ |---|---|
106
+ | BLOCKER | Stop the line — fix before merge OR within 24h on main |
107
+ | HIGH | Sprint-level (1-2 weeks) |
108
+ | MEDIUM | Backlog — reviewed quarterly |
109
+ | LOW | Best-effort; fix when touching the code |
110
+
111
+ If a BLOCKER must merge for emergency reasons (e.g., the BLOCKER itself is blocking a more urgent fix), document the temporary acceptance + owner + deadline; bypass is possible via `--no-verify` on the pre-push hook (pair with explicit team Slack post).
112
+
113
+ ## How to record triage decisions
114
+
115
+ For findings that are accepted (suppressed or deferred), record the decision in a way the next person can audit:
116
+
117
+ ```typescript
118
+ // Inline suppression
119
+ // aegis-disable: <scanner-name> — <one-line rationale + date + owner>
120
+ const code = doSomething();
121
+
122
+ // Or in aegis.config.json:
123
+ {
124
+ "suppressions": [
125
+ {
126
+ "scanner": "ssrf-checker",
127
+ "file": "lib/internal-fetch.ts",
128
+ "line": 42,
129
+ "rationale": "Internal fetch wrapper; URL validated against tenant-allowlist by line 38. Reviewed by sec-team 2026-04-22.",
130
+ "owner": "sec-team",
131
+ "added": "2026-04-22"
132
+ }
133
+ ]
134
+ }
135
+ ```
136
+
137
+ The `aegis history . --blame` command exposes which suppressions are stale (older than N days, owner left team, etc.).
138
+
139
+ ## See also
140
+
141
+ - `ops-suppress-correctly` skill — when and how to suppress, with the suppression-template.
142
+ - `ops-escalation-runbook` skill — what to do when a BLOCKER reaches main without proper triage.
143
+ - AEGIS suppressions docs — `docs/suppressions.md`.
144
+ - AEGIS confidence-rules — `README.md` § "Scoring" + per-scanner README sections.