@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.
- package/ATTRIBUTION.md +71 -20
- package/CHANGELOG.md +43 -0
- package/README.md +66 -18
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +17 -1
- package/dist/commands/install.js.map +1 -1
- package/package.json +3 -2
- package/sbom.cdx.json +1 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/SKILL.md +305 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/abmahn-templates.md +306 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/aegis-integration.md +241 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/audit-patterns.md +277 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/bgh-urteile.md +167 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/branchenrecht.md +285 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/checklisten.md +276 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/dsgvo.md +238 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/international.md +163 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/it-recht.md +267 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/strafrecht-steuer.md +193 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/vertragsrecht.md +243 -0
- package/skills/defensive/README.md +33 -4
- package/skills/defensive/aegis-native/rls-defense/SKILL.md +174 -0
- package/skills/defensive/aegis-native/ssrf-defense/SKILL.md +179 -0
- package/skills/defensive/aegis-native/tenant-isolation-defense/SKILL.md +225 -0
- package/skills/mitre-mapped/README.md +36 -8
- package/skills/mitre-mapped/aegis-native/mapping-overview/SKILL.md +129 -0
- package/skills/mitre-mapped/aegis-native/t1078-valid-accounts/SKILL.md +136 -0
- package/skills/mitre-mapped/aegis-native/t1190-exploit-public-app/SKILL.md +108 -0
- package/skills/ops/README.md +39 -4
- package/skills/ops/aegis-native/escalation-runbook/SKILL.md +147 -0
- package/skills/ops/aegis-native/suppress-correctly/SKILL.md +196 -0
- package/skills/ops/aegis-native/triage-finding/SKILL.md +144 -0
package/skills/ops/README.md
CHANGED
|
@@ -1,6 +1,41 @@
|
|
|
1
|
-
# Operations Skills
|
|
1
|
+
# Operations Skills — `ops/`
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
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
|
-
|
|
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.
|