nsauditor-ai-agent-skill 0.1.26 → 0.1.28
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/CHANGELOG.md +52 -0
- package/SKILL.md +31 -7
- package/package.json +1 -1
- package/references/plugins.md +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,58 @@ Release notes for **`nsauditor-ai-agent-skill`** — installable knowledge packa
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## 0.1.28 — Catalog refresh: plugin 1170 v3.1 SG-reference-graph edge dedup + plugin 1200 v6.1 CloudWatch Logs probe retry-on-empty parity — paired with EE 0.6.7 trio-publish (patch-level R2 reviewer-deferred-items cleanup cycle: closes both R2 items from 0.6.6 reviewer pass; 4 R1 reviewer folds (0 R-CRITICAL + 0 R-HIGH + 1 R-MEDIUM + 3 R-LOW — clean review pass) + 1 unanticipated `_retryOnNotFound` two-phase restructure (caught by test interaction); plugin count UNCHANGED at 22; soc2.json UNCHANGED; eighteenth consecutive trio-publish)
|
|
8
|
+
|
|
9
|
+
**Trio-publish institutionalization continued.** Paired with EE 0.6.7 + CE 0.1.61 — **eighteenth consecutive trio-publish across EE + CE + agent-skill in a single session** (0.4.5–0.6.7).
|
|
10
|
+
|
|
11
|
+
### What changed
|
|
12
|
+
|
|
13
|
+
- **`references/plugins.md`** — two plugin rows updated:
|
|
14
|
+
- **Plugin 1170 v3.1** — extended row with edge-dedup discipline in `_buildSgReferenceGraph`: edges deduped by `(sourceGroupId, targetGroupId)` with `ports` aggregated as array of `{protocol, fromPort, toPort}`. Pre-fold a real-world ALB-fronting-app SG with 3 ingress perms on different ports (80/443/8080) referencing the same source SG emitted 3 distinct edges A→B; the BFS treated each as a separate chain, inflating `chainCount` 2-5× and exhausting per-target chain caps on noise. Post-fold the BFS sees exactly 1 chain per distinct (source, target) pair. `isCrossVpc` aggregation is AND-semantic — if ANY contributing pair is same-VPC, the merged edge is same-VPC (per `[[conservative_classifier_principle]]`). Classifier `_classifyTransitiveReachability` port-render accepts both v3.1 array shape and v3 single-object shape (back-compat preserved).
|
|
15
|
+
- **Plugin 1200 v6.1** — extended row with CloudWatch Logs probe retry-on-empty parity. Pre-fold the CWL Logs probe was asymmetric: `DescribeLogGroups` returns `logGroups: []` (NOT a thrown exception) on missing groups, so the shared `_retryOnNotFound` helper's thrown-NotFound retry path never fired. A freshly-created CWL log group probed within seconds of creation could false-DEAD. Post-fold `_retryOnNotFound` accepts an optional retry-on-result predicate; the CWL call site passes a predicate that fires retry when the response carries no exact-name match (covers both empty and prefix-only-sibling responses). Eventual-consistency parity now uniform across IAM / Lambda / SNS / SQS / EventBridge API destination / CloudWatch Logs.
|
|
16
|
+
- **Two-phase restructure of `_retryOnNotFound`** — initially the result-based retry was added inside the existing try block, but a compound-path test interaction (transient empty → second-call throws `ResourceNotFoundException`) caused 3 total network calls. Restructured to two mutually-exclusive phases — Phase 1 = initial call + thrown-NotFound retry; Phase 2 = result-based retry — capping total calls at 2 on all compound paths. The per-call-site outer catch routes a second-call thrown error (NotFound → DEAD; AccessDenied → UNVERIFIABLE).
|
|
17
|
+
- **4 R1 reviewer folds applied** (0 R-CRITICAL + 0 R-HIGH + 1 R-MEDIUM + 3 R-LOW — clean review pass): R-MEDIUM-1 arrival-order-independent AND-aggregation (locked with 2 regression fixtures + JSDoc tightening) + R-LOW-1 partial-render contract on malformed port specs (locked with 2 regression fixtures) + R-LOW-2 `_portKeys` scratch-lifetime documented at function-signature comment + R-LOW-1 compound-path coverage (transient empty → second-call AccessDenied → UNVERIFIABLE / transient empty → second-call thrown RNF → DEAD; drives the two-phase restructure decision).
|
|
18
|
+
- **`SKILL.md`** — "post-EE 0.6.6" → "post-EE 0.6.7"; plugin 1170 v3.1 + plugin 1200 v6.1 highlights surfaced in plugin narratives; plugin count enumeration stays at 22.
|
|
19
|
+
- **`peerDependencies`** floor: unchanged at `nsauditor-ai >=0.1.40`.
|
|
20
|
+
|
|
21
|
+
### R2 reviewer-deferred (queued for 0.6.8+)
|
|
22
|
+
|
|
23
|
+
- **R-NIT (plugin 1200 v6.1)** — `retryOnResultPredicate` could be renamed to `shouldRetryOnResult` for question-form consistency with other EE predicates. Pure naming preference.
|
|
24
|
+
- **R-NIT (plugin 1200 v6.1)** — symmetry of comments between Phase 1 retry and Phase 2 retry blocks. Pure readability.
|
|
25
|
+
- **R-NIT (plugin 1170 — pre-existing)** — `// out-of-scope for v3 v1` typo at the cross-VPC BFS branch (pre-existing from 0.6.6).
|
|
26
|
+
- **Cross-plugin extraction candidate** — the `(source, target)` dedup pattern with aggregated-attribute array transfers to IAM trust-policy graphs, VPC peering graphs, KMS principal-reference graphs. Lift to `_lib/graph_edge_dedup.mjs` when the next plugin adopts it.
|
|
27
|
+
|
|
28
|
+
### Tests + regression
|
|
29
|
+
|
|
30
|
+
- **EE full regression: 5314/5314 across 834 suites** (was 5304/5304 at 0.6.6 publish; +10 tests, suite count unchanged). **59-session 100% green streak preserved.**
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 0.1.27 — Catalog refresh: plugin 1170 v3 SG→SG transitive reachability + plugin 1200 v6 dead-target probe warm-up — paired with EE 0.6.6 trio-publish (minor cycle: EE-RT.16 v3 transitive chain reachability + EE-RT.20.5 v6 IAM/API-destination/CW-Logs target probes; 5 R1 reviewer folds (1 R-HIGH + 2 R-MEDIUM + 2 R-LOW; 0 R-CRITICAL — clean review pass); plugin count UNCHANGED at 22; seventeenth consecutive trio-publish)
|
|
35
|
+
|
|
36
|
+
**Trio-publish institutionalization continued.** Paired with EE 0.6.6 + CE 0.1.60 — **seventeenth consecutive trio-publish across EE + CE + agent-skill in a single session** (0.4.5–0.6.6).
|
|
37
|
+
|
|
38
|
+
### What changed
|
|
39
|
+
|
|
40
|
+
- **`references/plugins.md`** — two plugin rows updated:
|
|
41
|
+
- **Plugin 1170 v3** — extended row with SG→SG transitive chain reachability dimension: BFS from public-CIDR roots through `UserIdGroupPairs` SG-references; 2-hop emits HIGH, 3+ hop emits CRITICAL (operator-blindness principle); cycle defense + depth cap (default 5, max 20) + per-target chain cap (default 10, max 100); cross-VPC edges skipped as INFO trailer; per-hop port-flow tracked but NOT intersected (v3 v1 simplification — walkthroughRequired=true). New operator opts: `skipTransitiveReachability` / `transitiveChainDepthCap` / `transitiveChainsPerTargetCap` / `transitiveChainSamplesPerFindingCap`. 3 new soc2.json mappings under CC6.6 (transitive-public HIGH + CRITICAL + INFO truncation).
|
|
42
|
+
- **Plugin 1200 v6** — extended row with three new dead-target probe branches: IAM role (`iam:GetRole` on path-stripped role NAME) + EventBridge API destination (`events:DescribeApiDestination` reuses `_EventBridgeSdk`) + CloudWatch Logs (`logs:DescribeLogGroups` with `logGroupNamePrefix` filter + exact-name disambiguation guard). New SDK deps `@aws-sdk/client-iam` + `@aws-sdk/client-cloudwatch-logs` (both in optionalDependencies). Companion-LOW emission contract unchanged (existing CC7.1 titlePattern target-type-agnostic). **Operator note**: `iam:GetRole` is a global API resolving per-partition — orchestrators wiring `opts._iamClient` must construct a single global IAM client per-partition.
|
|
43
|
+
- **5 v6 R1 reviewer folds applied** (0 R-CRITICAL — clean review pass; 1 R-HIGH + 2 R-MEDIUM + 2 R-LOW): R-HIGH-1 (plugin 1170 v3) BFS short-circuits enqueue past per-target cap (closes path-enumeration explosion on hub-and-spoke topologies — pre-fold the BFS marked the target truncated but kept cloning `path` and `visited` Sets and walking past the cap) + R-MEDIUM-1 (plugin 1200 v6) IAM `NoSuchEntityException` / `NoSuchEntity` lifted into `_DEAD_TARGET_NOTFOUND_ERROR_NAMES` Set (bare disjunction collapsed; eventual-consistency retry restored for IAM — the canonical worst case for AWS eventual consistency, with IAM lag 10-30s documented; **9th cumulative recurrence** of the `[[emit_literal_set_drift]]` class across the EE codebase) + R-MEDIUM-2 (plugin 1200 v6) IAM partition-routing contract documented at `_loadIamSdk` (orchestrator must construct global IAM client per-partition; doc-only fold) + R-LOW-2 (plugin 1170 v3) depth-cap-hit surfaced separately from per-target-cap (closes silent-deep-truncation false-CLEAN class — pre-fold a graph deeper than `transitiveChainDepthCap` silently truncated without operator-visible signal) + R-LOW-2 (plugin 1200 v6) API destination ARN regex future-proofed against alias-only ARN shapes.
|
|
44
|
+
- **`SKILL.md`** — "post-EE 0.6.5" → "post-EE 0.6.6"; plugin 1170 v3 + plugin 1200 v6 highlights surfaced in plugin-1200 narrative; plugin count enumeration stays at 22.
|
|
45
|
+
- **`peerDependencies`** floor: unchanged at `nsauditor-ai >=0.1.40`.
|
|
46
|
+
|
|
47
|
+
### R2 reviewer-deferred (queued for 0.6.7)
|
|
48
|
+
|
|
49
|
+
- **R-LOW-1 (plugin 1200 v6)**: CloudWatch Logs probe doesn't retry on empty result (logs:DescribeLogGroups returns `logGroups: []` not an exception, so `_retryOnNotFound` doesn't apply). Lower priority than IAM since CWL eventual-consistency is much narrower.
|
|
50
|
+
- **R-MEDIUM-1 (plugin 1170 v3)**: Edge dedup absent in `_buildSgReferenceGraph` — multi-rule references to the same SG (e.g., one perm per port) inflate chain counts 2-5×. Defer until operator feedback on chain-count noise.
|
|
51
|
+
- **R-NIT** documentation folds.
|
|
52
|
+
|
|
53
|
+
### Tests + regression
|
|
54
|
+
|
|
55
|
+
- **EE full regression: 5304/5304 across 834 suites** (was 5261/5261 across 825 at 0.6.5 publish; +43 tests, +9 suites — most are pre-fold v3/v6 base fixtures; 5 are fold-regression pins: hub-and-spoke per-target-cap + depthCapHit-true + depthCapHit-false + IAM transient-retry-succeeds + IAM lowercase-name-retry-then-DEAD). **58-session 100% green streak preserved.**
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
7
59
|
## 0.1.26 — Catalog refresh: plugin 1200 v5 v4-reviewer-cleanup cycle — paired with EE 0.6.5 trio-publish (patch-level cycle: R-NIT named-constants + sentinel observability + sessionToken cross-plugin sweep + dead-target companion-LOW; 5 R1 reviewer folds; plugin count UNCHANGED at 22; sixteenth consecutive trio-publish)
|
|
8
60
|
|
|
9
61
|
**Trio-publish institutionalization continued.** Paired with EE 0.6.5 + CE 0.1.59 — **sixteenth consecutive trio-publish across EE + CE + agent-skill in a single session** (0.4.5–0.6.5).
|
package/SKILL.md
CHANGED
|
@@ -221,8 +221,8 @@ on DMARC sp subdomain-policy override per R-HIGH-1 fold + new MEDIUM
|
|
|
221
221
|
ses-dkim-dns-partial-with-transients per v2.1 R-MEDIUM-2 fold + silent-loss-class
|
|
222
222
|
closure on SES classic API quota exhaustion via cause: "classic-sdk-quota-exhausted"
|
|
223
223
|
per v2.1 R-HIGH-2 reviewer-fold; first plugin in EE to depend on node:dns/promises
|
|
224
|
-
for live DNS cross-reference), AWS Inspector2 / GuardDuty Enablement Auditor (1200
|
|
225
|
-
NEW in EE 0.6.1, extended through EE 0.6.
|
|
224
|
+
for live DNS cross-reference), AWS Inspector2 / GuardDuty Enablement Auditor (1200 v6 —
|
|
225
|
+
NEW in EE 0.6.1, extended through EE 0.6.6; first AWS-managed-threat-detection
|
|
226
226
|
substrate audit; bundles two services per the plugin 1150 precedent.
|
|
227
227
|
**v4 EE 0.6.4 reviewer-cleanup cycle** (closes 3 of 4 R2-deferred items from
|
|
228
228
|
EE-RT.20.2): **R-HIGH-2 EventBridge target verification** — new `_listEventBridgeRuleTargets`
|
|
@@ -262,10 +262,32 @@ timeout. One-retry on NotFound with 750ms backoff (eventual-consistency defense)
|
|
|
262
262
|
Case-insensitive NotFound matching per `[[aws_string_case_normalization]]`.
|
|
263
263
|
Sentinel observability — `targetVerificationReason` enum (AccessDenied /
|
|
264
264
|
SdkUnavailable / BeyondCap / SkippedByOpts) on rule shape. R-NIT
|
|
265
|
-
`SH_HUB_NOT_ENABLED_ERROR_NAMES` frozen Set.
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
265
|
+
`SH_HUB_NOT_ENABLED_ERROR_NAMES` frozen Set. **v6 EE 0.6.6 closes the long
|
|
266
|
+
tail of unverifiable ARN shapes**: IAM role (`iam:GetRole` on path-stripped role
|
|
267
|
+
NAME; new SDK dep `@aws-sdk/client-iam`) + EventBridge API destination
|
|
268
|
+
(`events:DescribeApiDestination` reuses `_EventBridgeSdk`) + CloudWatch Logs
|
|
269
|
+
(`logs:DescribeLogGroups` with `logGroupNamePrefix` filter + exact-name
|
|
270
|
+
disambiguation guard so prefix-match siblings don't false-LIVE; new SDK dep
|
|
271
|
+
`@aws-sdk/client-cloudwatch-logs`). **Operator note (v6 R-MEDIUM-2)**:
|
|
272
|
+
`iam:GetRole` is a global API resolving per-partition; orchestrators wiring
|
|
273
|
+
`opts._iamClient` must construct a single global IAM client per-partition (NOT
|
|
274
|
+
per-region). **v6 R-MEDIUM-1 fold**: IAM `NoSuchEntityException` /
|
|
275
|
+
`NoSuchEntity` lifted into `_DEAD_TARGET_NOTFOUND_ERROR_NAMES` Set; bare
|
|
276
|
+
disjunction collapsed; eventual-consistency retry restored for IAM (the canonical
|
|
277
|
+
worst case — 9th cumulative recurrence of `[[emit_literal_set_drift]]` class).
|
|
278
|
+
**v6 R-LOW-2 fold**: API destination ARN regex future-proofed against alias-only
|
|
279
|
+
ARN shapes. **v6.1 EE 0.6.7 closes the Logs probe retry-on-empty parity**:
|
|
280
|
+
`_retryOnNotFound` accepts an optional retry-on-result predicate; CWL Logs probe
|
|
281
|
+
fires retry when the response carries no exact-name match (covers both empty
|
|
282
|
+
and prefix-only-sibling responses). **Restructured to two-phase to cap total
|
|
283
|
+
network calls at 2 on compound paths** — Phase 1 = initial call + thrown-
|
|
284
|
+
NotFound retry; Phase 2 = result-based retry; phases are mutually exclusive
|
|
285
|
+
(per-call-site outer catch routes a second-call thrown error). Existing call
|
|
286
|
+
sites (Lambda / SNS / SQS / IAM / EventBridge API destination) pass only two
|
|
287
|
+
args; default `retryOnResultPredicate = null` cleanly skips Phase 2. Dim 5
|
|
288
|
+
org-scope still deferred to a future cycle. Total folds across all cycles:
|
|
289
|
+
6 v1 + 4 v2 + 4 v3 (1 R-CRITICAL) + 5 v4 + 5 v5 + 4 v6 (0 R-CRITICAL) + 1 v6.1
|
|
290
|
+
(0 R-CRITICAL / 0 R-HIGH) = 29 R1 folds applied same-session.
|
|
269
291
|
|
|
270
292
|
**v5 also brings a cross-plugin contract change**: all 18 EE AWS plugins
|
|
271
293
|
(1020-1200) now thread `sessionToken` through their AWS-SDK credentials block,
|
|
@@ -273,7 +295,9 @@ unblocking AssumeRole-style auditor credentials uniformly across the catalog).
|
|
|
273
295
|
**EE plugin IDs use the disjoint 1000+ range** (per EE 0.3.9 renumbering) to avoid
|
|
274
296
|
CE collision. CE reserves 001-099.
|
|
275
297
|
|
|
276
|
-
**EE
|
|
298
|
+
**Plugin 1170 v3 (EE 0.6.6) SG→SG transitive chain reachability** — `aws-ec2-sg-perimeter-auditor` v3 extension. Pre-v3 each Security Group was audited in isolation; a SG with no direct public-CIDR ingress would emit the PASS-tier "no direct public-internet ingress CIDR rules" finding even if transitively reachable from the internet through a `UserIdGroupPairs` chain. v3 builds the SG-reference graph (`_buildSgReferenceGraph`), identifies public-CIDR roots (`_findPubliclyReachableSgs` — 0.0.0.0/0 / ::/0 ingress), and BFS-walks the graph (`_walkTransitiveReachability`) with cycle defense + depth cap (default 5, max 20) + per-target chain cap (default 10, max 100). 2-hop chains emit **HIGH**; 3+ hop chains emit **CRITICAL** (operator-blindness principle — deeper chains less likely to be noticed). Cross-VPC edges skipped (out-of-scope for v3 v1; INFO trailer). v3 v1 simplification: per-hop port-flow tracked but NOT intersected (`walkthroughRequired=true`). New operator opts: `skipTransitiveReachability` / `transitiveChainDepthCap` / `transitiveChainsPerTargetCap` / `transitiveChainSamplesPerFindingCap`. **v3 R-HIGH-1 fold**: BFS short-circuits enqueue past per-target cap (closes path-enumeration explosion on hub-and-spoke topologies — pre-fold the BFS kept cloning `path` and `visited` Sets and walking past the cap). **v3 R-LOW-2 fold**: depth-cap-hit surfaced separately from per-target-cap (closes silent-deep-truncation false-CLEAN class). 3 new soc2.json mappings under CC6.6 (transitive HIGH + CRITICAL + INFO truncation). **v3.1 EE 0.6.7 closes the edge-dedup R2-deferred item**: `_buildSgReferenceGraph` now dedupes edges by `(sourceGroupId, targetGroupId)` with `ports` aggregated as array of `{protocol, fromPort, toPort}`. Pre-fold a real-world ALB-fronting-app SG with 3 ingress perms on different ports (80/443/8080) referencing the same source SG emitted 3 distinct edges A→B; the BFS treated each as a separate chain, inflating `chainCount` 2-5× and exhausting per-target chain caps on noise. Post-fold the BFS sees exactly 1 chain per distinct (source, target) pair. `isCrossVpc` aggregation is AND-semantic — if ANY contributing pair is same-VPC, the merged edge is same-VPC (per `[[conservative_classifier_principle]]`: walk possibly-same-VPC chains rather than silently skip). Classifier port-render accepts both v3.1 array shape and v3 single-object shape (back-compat). **v3.1 R-MEDIUM-1 fold**: arrival-order independence locked with 2 regression fixtures + JSDoc tightening. **v3.1 R-LOW-1 fold**: partial-render contract on malformed port specs locked with 2 fixtures. **v3.1 R-LOW-2 fold**: `_portKeys` scratch-lifetime documented (MUST NOT escape).
|
|
299
|
+
|
|
300
|
+
**EE SOC 2 substrate-evidence coverage (post-EE 0.6.7):** 10 covered controls (CC6.1 /
|
|
277
301
|
CC6.2 / CC6.6 / CC6.7 / CC6.8 / CC7.1 / CC7.2 / CC7.3 / C1.1 / C1.2) + 4 partial
|
|
278
302
|
(CC6.3 / CC8.1 / A1.2 / PI1.5) + 33 OOS for static substrate scanning. Coverage matrix
|
|
279
303
|
is institutionally honest: substrate-evidence depth grows release-over-release without
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nsauditor-ai-agent-skill",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.28",
|
|
4
4
|
"description": "AI Agent Skill for NSAuditor AI — gives any AI coding agent built-in knowledge of NSAuditor's MCP tools, schemas, plugins, and security audit workflows.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nsauditor",
|
package/references/plugins.md
CHANGED
|
@@ -183,9 +183,9 @@ listings, and default pages.
|
|
|
183
183
|
| 1140 | AWS RDS Auditor (v3 — extended in EE 0.4.8) | Enterprise | **10 SOC 2 substrate-evidence dimensions** (v1=3 + v2=4 + v3=3). **v1+v2 (preserved):** Multi-AZ (A1.2) + storage encryption at rest with KMS-key custody classification + **kms:DescribeKey cross-reference promotes UNVERIFIABLE `:key/UUID` ARN shapes to deterministic PASS/MEDIUM** + parameter-group SSL enforcement (postgres rds.force_ssl + mysql require_secure_transport) + BackupRetentionPeriod (7-day baseline) + PubliclyAccessible + IAMDatabaseAuthenticationEnabled + snapshot encryption. **v3 NEW (database audit-logging, EE 0.4.8 EE-RT.14 v3):** **dim 8 pgAudit enabled** (postgres-only — `DescribeDBParameters → pgaudit.log` non-empty AND `shared_preload_libraries` contains `pgaudit` token per R-MEDIUM-2 reviewer-fold **false-PASS closure** — Postgres silently ignores the GUC when SPL omits pgaudit; new MEDIUM `rds-pgaudit-misconfigured` category; non-postgres engines = INFO + engine-not-applicable) + **dim 9 CloudWatch Logs exports** (`EnabledCloudwatchLogsExports` engine-dispatched: postgres essential=`postgresql`; mysql/mariadb essential=`error`; oracle essential=`audit`+`trace`; sqlserver essential=`error`; empty=HIGH / partial=MEDIUM / complete=PASS) + **dim 10 CloudWatch Logs retention** (`logs:DescribeLogGroups` enumeration on engine-dispatched prefix per R-HIGH-1 reviewer-fold **false-INFO closure**: `/aws/rds/instance/<id>/` for non-Aurora, `/aws/rds/cluster/<DBClusterIdentifier>/` for `aurora-*` engines — pre-fold hard-coded the instance path → 0 log groups on every Aurora node = false-INFO MEDIUM across the whole Aurora fleet; 30-day institutional baseline operator-tunable via `opts.auditLogRetentionPassMinDays` clamped 1..3653). **9 same-session v3 reviewer folds** (HIGH-1 Aurora cluster log-path; MEDIUM-2 pgAudit-SPL cross-check; MEDIUM-3/4/5 cwl-opt-out + retentionDistribution + transient-error distinct categories; LOW-8/9/10 + NIT-12). **Real-AWS smoke END-TO-END against `522412052794`** (in-place modification of rds-compliant-cluster; cost $0): ALL 3 v3 PASS-path classifiers validated + unmodified rds-violator-db validates HIGH path. **First 0.4.x extension cycle to validate BOTH PASS-path AND HIGH-path classifiers** against real AWS in the same smoke run. | A1.2 / CC6.1 / CC6.6 / C1.1 / CC7.2 / CC7.3 |
|
|
184
184
|
| 1150 | AWS SQS/SNS Auditor (NEW EE 0.4.4 v1; **EXTENDED EE 0.5.1 v2** — 5 → 7 dimensions: CloudWatch alarm coverage on SQS ApproximateAgeOfOldestMessage + SNS NumberOfNotificationsFailed; first plugin-1150 dim to cross an SDK boundary — SQS+SNS → CloudWatch) | Enterprise | First multi-service plugin in EE codebase. **7 dimensions total** (v1: 5; v2 EE 0.5.1 added dims 6 + 7). **v1 dims preserved:** SQS encryption at rest (SqsManagedSseEnabled OR KmsMasterKeyId; four-tier classification) + SQS transit-encryption policy (aws:SecureTransport Deny statement) + SNS topic encryption at rest + SNS topic-policy permissive-Principal (full NotAction-Allow + NotPrincipal-Allow + Resource-scope filtering per plugin 1070 + 1110 precedent) + SQS dead-letter queue presence (dual-mapped A1.2 + CC7.1). **v2 EE 0.5.1 NEW dims:** **dim 6 — SQS ApproximateAgeOfOldestMessage CloudWatch alarm coverage** (CC7.2 + A1.2 dual-mapped) — per-queue classifier `_classifySqsAgeAlarmCoverage` checks for at least one `AWS/SQS:ApproximateAgeOfOldestMessage` MetricAlarm with the queue's `QueueName` dimension AND **both** `ActionsEnabled=true` AND non-empty `AlarmActions[]`. Four outcomes: PASS `sqs-age-alarm-covered` / MEDIUM `sqs-age-alarm-missing` (silent backlog growth class) / LOW `sqs-age-alarm-actions-disabled` (matching alarm with all disabled OR empty AlarmActions — informational-only) / LOW + evidenceGap `sqs-age-alarm-coverage-unverifiable` (CW SDK unavailable / DescribeAlarms AccessDenied / queue name un-extractable / pagination truncated). **dim 7 — SNS NumberOfNotificationsFailed CloudWatch alarm coverage** (CC7.2 + A1.2 dual-mapped) — per-topic analogue with `AWS/SNS:NumberOfNotificationsFailed` metric + `TopicName` dimension; same four-tier severity ladder. **v2 single-fetch budget pattern** (mirrors plugin 1040): `_enumerateMetricAlarms` paginates `cloudwatch:DescribeAlarms` ONCE per scan; `_buildAlarmIndex` builds per-resource Maps (`sqsAgeByQueueName` + `snsFailureByTopicName`) for O(1) per-resource lookup. Pagination cap default 20 pages × 100 alarms = 2000 alarm ceiling, operator-tunable via `opts.cwAlarmPageCap`. **Soft-degrade contract** — CW SDK load failure routes per-resource classifier to LOW + evidenceGap rather than blocking SQS+SNS primary substrate audit. **R-CRITICAL v2 fold (false-CLEAN closure)**: `actionable` requires BOTH `ActionsEnabled=true` AND non-empty `AlarmActions[]` array — CloudWatch fires NO operator paging when AlarmActions=[] even with ActionsEnabled=true; pre-fold an `{ActionsEnabled:true, AlarmActions:[]}` alarm passed as PASS-tier evidence on a structurally broken alarm. Discriminates "all disabled" vs "all empty actions" in remediation narrative. **R-HIGH v2 fold**: soc2.json PASS-tier titlePatterns narrowed to anchor on `AWS/SQS:ApproximateAgeOfOldestMessage` / `AWS/SNS:NumberOfNotificationsFailed` clauses. **R-MEDIUM/R-LOW v2 folds**: defensive shape guard + multi-alarm collision tests + FIFO end-to-end + corrupted-shape defensive tests. **7 same-session v2 reviewer folds** (1 CRITICAL + 1 HIGH + 2 MEDIUM + 1 LOW + 1 NIT; 6 folded same-session, 1 NIT deferred). **No new SDK dependencies** — `@aws-sdk/client-cloudwatch` already declared in optionalDependencies since EE 0.4.0 (used by plugin 1040). **23 soc2.json titlePattern entries total** (11 v1 + 12 v2: 8 CC7.2 + 4 A1.2 dual-mapped). **Synthetic-mock validation only** this cycle for v2 — real-AWS smoke deferred (no SQS/SNS paired fixtures yet in test-infra-builder; ship-without per documented gap, EE 0.5.0 SES precedent). Closes the **"messaging monitoring" SOC 2 dimension** per `tasks/things-to-check.md` §4 institutional checklist: *"Track SQS ApproximateAgeOfOldestMessage and SNS delivery failure metrics inside CloudWatch to prove operational monitoring."* | C1.1 / CC6.6 / A1.2 / CC7.1 / CC7.2 |
|
|
185
185
|
| 1160 | AWS VPC Endpoints / PrivateLink Auditor (**NEW EE 0.6.0** — first new plugin since EE 0.4.7; first plugin to audit the PrivateLink isolation boundary; plugin count 20 → 21) | Enterprise | Audits AWS VPC endpoints (Interface + Gateway flavors) against **4 SOC 2 substrate-evidence dimensions** — VPC endpoints govern VPC-to-managed-service traffic without public-internet traversal (PrivateLink primitive). **Complements plugin 1170 SG perimeter** (1170 = layer-4 ingress; 1160 = service-layer perimeter). **Dim 1 — Endpoint policy permissive principals** (CC6.6 segmentation; wildcard-Principal classifier mirroring plugin 1150 SNS topic-policy discipline; NotPrincipal-Allow + Action-sensitivity filter via `_VPCE_SENSITIVE_ACTIONS` frozen Set; unconditional wildcard on sensitive action = CRITICAL — PrivateLink isolation BROKEN at policy layer; WITH Condition = HIGH walkthroughRequired). **Dim 2 — PrivateDNS enabled** (CC6.6; Interface + PrivateDnsEnabled=false = MEDIUM silent-bypass class — clients still resolve service-public hostname → traffic over public internet; Gateway = INFO not-applicable). **Dim 3 — Endpoint state** (A1.2 + CC7.2; `available` = PASS / `failed` = HIGH silent-failure / transient = INFO / unknown enum = LOW + evidenceGap). **Dim 4 — Endpoint type substrate disclosure** (Privacy + CC6.6; INFO substrate evidence per VPC). **2 same-session reviewer folds** (R-MEDIUM unknown-type fail-safe defaults to Interface — safer audit path; R-NIT Effect case-insensitivity regression pin). **No new SDK deps** — `@aws-sdk/client-ec2` already declared since EE 0.4.5 (used by plugin 1170 + plugin 1180 v2). 7 new soc2.json titlePattern entries (5 CC6.6 + 2 CC7.2/A1.2 dual-mapped). 57 plugin tests + 2 reviewer-fold pins (59 total). Synthetic-mock validation only — no VPC endpoint paired fixtures yet in test-infra-builder. | CC6.6 / A1.2 / CC7.2 / Privacy (substrate) |
|
|
186
|
-
| 1170 | AWS EC2 SG Perimeter Auditor (
|
|
186
|
+
| 1170 | AWS EC2 SG Perimeter Auditor (v3.1 — extended in EE 0.6.7 with `_buildSgReferenceGraph` edge-dedup; v3 EE 0.6.6 SG→SG transitive chain reachability; v2 EE 0.4.6 RESTRICTED_PORTS 23-port baseline; v1 EE 0.4.5 base) | Enterprise | Orthogonal evidence to plugin 1023 zero-trust-checker (1023 reads OBSERVED open ports; 1170 reads DECLARED SG policy via DescribeSecurityGroups). **v3 dimensions: 6 v2 dims + 1 NEW v3 transitive-reachability dim.** **v3 EE 0.6.6 SG→SG transitive chain reachability** — `_buildSgReferenceGraph` builds nodes + directed edges per UserIdGroupPairs reference (cross-VPC edges flagged at edge-build time). `_findPubliclyReachableSgs` identifies SGs with 0.0.0.0/0 or ::/0 ingress as BFS roots. `_walkTransitiveReachability` BFS-walks the graph with cycle defense (per-traversal `visited` Set cloned at each branch), depth cap (default 5, max 20 — operator-tunable via `transitiveChainDepthCap`), per-target chain cap (default 10, max 100 — operator-tunable via `transitiveChainsPerTargetCap`). `_classifyTransitiveReachability` emits per-target findings: **2-hop = HIGH** (direct from public root, one indirection) / **3+ hop = CRITICAL** (operator-blindness principle — deeper chains less likely to be noticed). Cross-VPC edges skipped (out-of-scope for v3 v1 — cross-VPC peering / Transit Gateway is a separate audit surface); surfaced as INFO trailer. **v3 v1 simplifications**: per-hop port-flow tracked but NOT intersected (`walkthroughRequired=true` on every transitive finding — operator walkthrough verifies port-flow alignment across the chain); cross-VPC out of scope. **v3 R-HIGH-1 reviewer fold (EE 0.6.6)**: BFS short-circuits enqueue past per-target cap (closes path-enumeration explosion on hub-and-spoke topologies — pre-fold the BFS marked the target truncated but kept cloning `path` and `visited` Sets and walking past the cap, causing O(paths × depth) heap usage on 200+ SG accounts with fan-out ≥10). **v3 R-LOW-2 reviewer fold**: depth-cap-hit surfaced separately from per-target-cap (closes silent-deep-truncation false-CLEAN class — pre-fold a graph deeper than `transitiveChainDepthCap` silently truncated without operator-visible signal). New operator opts: `skipTransitiveReachability` / `transitiveChainDepthCap` / `transitiveChainsPerTargetCap` / `transitiveChainSamplesPerFindingCap`. **v3.1 EE 0.6.7 closes the edge-dedup R2-deferred item**: `_buildSgReferenceGraph` now dedupes edges by `(sourceGroupId, targetGroupId)` with `ports` aggregated as array of `{protocol, fromPort, toPort}`. Pre-fold a real-world ALB-fronting-app SG with 3 ingress perms on different ports (80/443/8080) referencing the same source SG emitted 3 distinct edges A→B; BFS treated each as separate chain, inflating `chainCount` 2-5× and exhausting per-target chain caps on noise. Post-fold the BFS sees exactly 1 chain per distinct (source, target) pair. `isCrossVpc` AND-aggregation per `[[conservative_classifier_principle]]` (any same-VPC pair → merged edge same-VPC → walked rather than silently skipped). Classifier port-render accepts both v3.1 array shape and v3 single-object shape (back-compat preserved). **v3.1 R-MEDIUM-1 fold**: arrival-order independence locked with 2 regression fixtures + JSDoc tightening. **v3.1 R-LOW-1 fold**: partial-render contract on malformed port specs locked with 2 fixtures. **v3.1 R-LOW-2 fold**: `_portKeys` scratch lifetime documented (MUST NOT escape). 3 new soc2.json mappings under CC6.6 (transitive-public HIGH `Security Group ... shortest = 2 hops` + transitive-public CRITICAL `... shortest = 3+ hops` + INFO truncation trailer `SG→SG transitive reachability walk truncated:`). **v2 EE 0.4.6 preserved**: 6 dimensions — IPv4 0.0.0.0/0 ingress to **RESTRICTED_PORTS (v2: 23 ports per CIS AWS Foundations v3.0)** — SSH/RDP/MS SQL/MySQL/Postgres/Redshift/Redis/Memcached/MongoDB/Elasticsearch/CouchDB/Docker/Kubelet/K8s-API/etcd/Kibana/InfluxDB/Kafka/Consul/ZooKeeper/Vault CRITICAL + IPv6 ::/0 sibling CRITICAL + all-protocol (-1) wildcard CRITICAL + public ingress to non-restricted ports INFO + egress 0.0.0.0/0 INFO + orphan SG (no attached ENI) LOW governance. **v2: `opts.additionalRestrictedPorts` operator-config knob** + **per-SG cardinality cap with rollup trailer** (defends against finding-size DoS on 1000+ SG accounts) + **system-managed-SG name-prefix exclusion list** (ElasticMapReduce- / eks-cluster-sg- / AWSServiceRole / awseb- prefixes excluded from orphan-detection). UserIdGroupPairs rules surfaced as INFO + evidenceGap at v2; **v3 (EE 0.6.6) now closes transitive SG→SG chain analysis** | CC6.6 / CC6.2 |
|
|
187
187
|
| 1180 | AWS ElastiCache Redis Auditor (v2 — extended in EE 0.4.9) | Enterprise | First plugin in 1170-1180 ID range. **6 SOC 2 substrate-evidence dimensions** (v1 unchanged in count; v2 grew dims 2 + 6 in scope). **v1 dims preserved:** transit encryption (TransitEncryptionEnabled wraps RESP in TLS; HIGH on disabled) + Redis AUTH/IAM-auth user groups (PASS on UserGroupIds; MEDIUM no-authentication) + Multi-AZ deployment (HIGH disabled / INFO standalone-not-applicable / INFO+evidenceGap on transient enabling/disabling states) + SnapshotRetentionLimit cadence (HIGH=0 / MEDIUM 1-6 / PASS ≥7; operator-tunable `opts.snapshotRetentionPassMinDays`). Dual API enumeration (DescribeReplicationGroups + DescribeCacheClusters) with inter-API dedup. **v2 GROWN dims (EE 0.4.9 EE-RT.17 v2):** **dim 2 at-rest encryption + KMS key custody** — original four-tier ladder (HIGH disabled → MEDIUM AWS-owned-default → MEDIUM `alias/aws/elasticache` → PASS customer-managed CMK + LOW+evidenceGap on `:key/UUID` per conservative-classifier-principle) **PLUS v2 kms:DescribeKey cross-reference promotion** (mirrors plugin 1140 v2): UNVERIFIABLE `:key/UUID` ARN shapes promoted via KeyMetadata.KeyManager to deterministic PASS `elasticache-at-rest-customer-managed-kms-promoted` (CUSTOMER) / MEDIUM `elasticache-at-rest-aws-managed-kms-promoted` (AWS); conservative on AccessDenied/NotFound/unknown KeyManager. **dim 6 subnet routing** — v1 INFO substrate (`elasticache-subnet-group-substrate`) plus **v2 ec2:DescribeRouteTables verifier** that walks the cache subnet group's subnets via elasticache:DescribeCacheSubnetGroups + filtered ec2:DescribeRouteTables, classifying each subnet on Internet Gateway route presence via /^igw-[a-f0-9]+$/i (correctly excludes egress-only eigw-): HIGH `elasticache-subnet-public-route-detected` (with per-subnet `igwDestinationsBySubnet` evidence per R-HIGH-1 fold) / PASS `elasticache-subnet-private-verified` (all subnets verified IGW-free) / LOW + evidenceGap `elasticache-subnet-main-rt-inheritance` per R-MEDIUM-2 false-NEGATIVE closure (default-VPC main-RT typically routes `0.0.0.0/0 → igw-*`) / LOW + evidenceGap `elasticache-subnet-verification-unverifiable` on AccessDenied. **Cross-plugin sister of plugin 1170 SG perimeter** (layer-3 subnet→IGW vs layer-4 SG ingress policy). **7 same-session v2 reviewer folds** (HIGH-1 IGW destination evidence; MEDIUM-2 main-RT-inheritance false-NEGATIVE closure; MEDIUM-3 cache-key naming; LOW-6/7/9/10/11 + NIT-12). **Per-resource caching** prevents N×M API explosion (kmsKeyManagerCache + subnetGroupCache + subnetSetRoutingCache). **No new SDK deps** — @aws-sdk/client-kms + @aws-sdk/client-ec2 reused from EE 0.4.5. **Real-AWS smoke END-TO-END against 522412052794**: R-MEDIUM-2 fold escalation demonstrably firing in production (`redis-leaky-cache` → dim 6 LOW main-RT-inheritance). | CC6.1 / CC6.2 / CC6.6 / A1.2 / C1.1 |
|
|
188
|
-
| 1200 | AWS Inspector2 / GuardDuty Enablement Auditor (NEW EE 0.6.1, EXTENDED EE 0.6.2 v2 multi-region + FindingPublishingFrequency + Inspector2 baseline expansion, EXTENDED EE 0.6.3 v3 alerting-destination dim closes substrate-without-sink false-PASS class, EXTENDED EE 0.6.4 v4 EventBridge target verification + multi-failedAccount + trigger uniformity, **EXTENDED EE 0.6.5 v5** — dead-target companion-LOW + sentinel observability + R-NIT named-constants; plugin count UNCHANGED at 22 — existing plugin grew ~870 → ~1400 → ~2100 → ~2400 → ~2800 lines) | Enterprise | **v5 EE 0.6.5 v4-reviewer-cleanup cycle** (closes 4 R2-deferred items from EE-RT.20.3): **Dead-target companion-LOW** — closes the EE 0.6.4 R-HIGH-2 documented limitation. Per-target liveness probes for Lambda (`lambda:GetFunction` on full qualified ARN — alias/version correctness verified server-side) + SNS (`sns:GetTopicAttributes`) + SQS (`sqs:GetQueueUrl` + `GetQueueAttributes` — partition-aware via SDK URL resolution; works on aws-cn / aws-us-gov / aws-iso). New `_probeTargetLiveness` helper with parallel probes via Promise.all + per-target timeout (default 2s; operator-tunable via `deadTargetProbeTimeoutMs`). One-retry on NotFound with 750ms backoff (eventual-consistency defense). New MEDIUM verdict `*-alerting-destination-dead-targets` emitted as companion alongside PASS when at least one Target.Arn points to deleted resource. `deadTargetArnsTotal` + `deadTargetArnsTruncated` for JSON-consumer visibility on 11+ case. IAM role + API destination + CloudWatch Logs target probes deferred to 0.6.6 (3-4 more IAM grants). New operator opt `skipTargetLivenessProbe: true`. **Sentinel observability** — rule shape extended with `targetVerificationReason` (AccessDenied / SdkUnavailable / BeyondCap / SkippedByOpts) stable enum; classifier surfaces `targetVerificationReasonBreakdown` in unverifiable verdict details. **R-NIT named-constants** — `SH_HUB_NOT_ENABLED_ERROR_NAMES` frozen Set replaces 2 bare-string sites in SecurityHub helpers per `[[emit_literal_set_drift]]`. **Cross-plugin sessionToken sweep (catalog-wide)** — 18 EE AWS plugins (1020-1200) all thread `sessionToken` through their AWS-SDK credentials block. Closes AssumeRole-style auditor credential gap — auditors using `aws sts assume-role` (canonical cross-account audit pattern) had all auto-loaded clients fail signing pre-fold. **5 v5 R1 reviewer folds** (0 R-CRITICAL — clean review pass): R-HIGH-1 case-insensitive NotFound matching (defends against future AWS SDK case changes per `[[aws_string_case_normalization]]` 15× recurrent class) + R-HIGH-2 one-retry on NotFound (eventual-consistency defense; freshly-created resources transiently return NotFound for ~30s) + R-HIGH-3 Lambda probe passes FULL ARN to GetFunction.FunctionName (alias `PROD` pointing to deleted version surfaces as DEAD instead of false-LIVE) + R-HIGH (Explore) parallel probes via Promise.all + per-target timeout + R-MEDIUM-1 SQS partition-aware via `GetQueueUrl` (pre-fold synthesized `amazonaws.com` URL would have crashed on aws-cn / aws-us-gov / aws-iso partitions) + R-LOW-1 cap-constant lift to module-level + R-MEDIUM-2 truncation fields + R-NIT JSDoc accuracy. **R2 reviewer-deferred** (queued for 0.6.6): IAM role + API destination + CloudWatch Logs target liveness probes. 1 new soc2.json mapping rule (CC7.1 companion-LOW dead-target). New SDK deps `@aws-sdk/client-lambda` + `@aws-sdk/client-sns` + `@aws-sdk/client-sqs` (all already in optionalDependencies from prior cycles). v5 tests: +48 (1 R-NIT + 8 sentinel + 20 sessionToken-sweep + 15 dead-target base + 4 R-HIGH-fold regression pins). **v4 EE 0.6.4 reviewer-cleanup cycle** (closes 3 of 4 R2-deferred items from EE-RT.20.2): **R-HIGH-2 EventBridge target verification** — new `_listEventBridgeRuleTargets` helper with defensive NextToken pagination (hard cap 500); per-rule target verification via `events:ListTargetsByRule` (cap default 10 via `opts.targetVerificationRuleCap`; opt-out via `opts.skipEventBridgeTargetVerification`); new MEDIUM verdict `*-alerting-destination-targetless` for sink-less rules (zero Targets — substrate-without-sink at the rule level). **R-MEDIUM-2 multi-failedAccount surface** — Inspector2 helper return-shape `{accountStatus, accessDenied, failedAccounts: array}` (renamed plural; capped at AWS-documented 100); caller emits one LOW per failed account with per-region emission cap 10 + rollup LOW per region. **R-LOW-2 trigger uniformity** — GuardDuty alerting-destination trigger gates on `detector.Status === ENABLED` (matches Inspector2 enabled-only semantic). **5 v4 R1 reviewer folds** (0 R-CRITICAL — clean review pass): R-HIGH-1 cap-skew classifier branch (LOW UNVERIFIABLE not MEDIUM TARGETLESS when cap-exceeded rules could be the actual sink per `[[conservative_classifier_principle]]`) + R-HIGH consolidated `_listEventBridgeRuleTargets` pagination + JSDoc clarity + R-MEDIUM-1 multi-failedAccount per-region emission cap (10 + rollup LOW) + R-MEDIUM-4 boundary tests + R-HIGH-2 dead-target documented-limitation note (per-target liveness probes deferred to 0.6.5 companion-LOW; ~6 new IAM grants). **R2 reviewer-deferred** (queued for 0.6.5): R-LOW-3 sessionToken cross-plugin sweep (18 plugins) + companion-LOW for dead-target ARNs + `targetCount: null` sentinel observability + R-NIT named-constants for InvalidAccessException / ResourceNotFoundException. 1 new soc2.json mapping rule (CC7.1 MEDIUM TARGETLESS). v4 tests: +29 (3 R-LOW-2 + 6 R-MEDIUM-2 + 14 R-HIGH-2 base + 6 R1-fold regression pins). **v3 EE 0.6.3 alerting-destination dim (item c)** — closes the substrate-without-sink false-PASS class. Verifies at least one of EventBridge rule (source=`aws.guardduty`/`aws.inspector2`; `_eventBridgeSourceMatches` recognizes string + `{prefix}` + `{wildcard}` content-filter forms case-insensitively, regex-meta escape in wildcard glob defends against operator IaC) AND/OR SecurityHub product subscription (`_shArnMatchesProduct` boundary-anchored helper; constants `/aws/guardduty` + `/aws/inspector2` strict — does NOT match deprecated Inspector Classic). Verdict tiers per service per region: PASS `*-alerting-destination-present` (EB rule present) / MEDIUM `*-alerting-destination-sh-only` (R-HIGH-1 fold — SH aggregates but doesn't guarantee proactive paging; auditor walkthrough to confirm `aws.securityhub` EventBridge downstream rule) / HIGH `*-alerting-destination-missing` (no path; substrate-without-sink class) / LOW `*-alerting-destination-unverifiable` (AccessDenied / SDK unavailable; conservative classifier). New SDK deps `@aws-sdk/client-eventbridge` + `@aws-sdk/client-securityhub` (optionalDependencies). Operator opt: `skipAlertingDestination: true`. Soft-degrade on auto-load failure → fall back to LOW UNVERIFIABLE. **v3 R-MEDIUM-2 fold** — `_getInspector2AccountStatus` returns `{accountStatus, accessDenied, failedAccount}` distinguishing true AccessDenied from empty-body / SDK-unavailable (was `null | <obj>` pre-fold; caller emitted false `_CAT_INS_ACCESSDENIED` LOW on empty body). **v3 item (d) fold** — surfaces AWS-published `failedAccounts[].errorCode + errorMessage` via new `_CAT_INS_FAILED_ACCOUNT` LOW. **v3 R1 reviewer folds applied** (4 total; 1 R-CRITICAL + 2 R-HIGH + 1 R-LOW): R-CRITICAL-1 SH product ARN substring collision closure (`/aws/inspector` would have matched BOTH Inspector Classic deprecated-2024 AND Inspector2 — false-PASS for stale Classic subscriptions emitting zero findings; boundary-anchored helper + strict `/aws/inspector2` constant) + R-HIGH-1 SH-only PASS narrative split (PASS requires EB rule; SH-only → MEDIUM) + R-HIGH-3 EventBridge content-filter grammar (prefix + wildcard matchers) + R-LOW-1 source case normalization. **R2 reviewer-deferred** (queued for 0.6.4): R-HIGH-2 EB target verification (events:ListTargetsByRule + IAM grant) + R-LOW-2 asymmetric trigger uniformity + R-MEDIUM-2 multi-failedAccount surface + R-LOW-3 sessionToken support cross-plugin sweep. 5 new soc2.json titlePattern entries (4 CC7.1 + 1 CC7.2 PASS) all anchored to actual emission strings per `[[soc2_titlepattern_anchor_drift]]`. v3 tests: +61 (+8 suites) — 5 R-MEDIUM-2 + 5 item-(d) + 30 item-(c) base + 21 R1-fold regression pins. **v2 EE 0.6.2 dims preserved** (4 dims; v2 (a) multi-region enumeration via ec2:DescribeRegions + (b) FindingPublishingFrequency check + (e) Inspector2 baseline expansion +lambdaCode +codeRepository per Inspector2 GA 2024+; operator opts `regions[]` / `skipMultiRegion` / `regionListCap` / `gdFrequencyPassFrequency`; closes FedRAMP / StateRAMP / IL5+ false-PASS class for GovCloud + ISO regions via 4-part region regex fold). **v1 EE 0.6.1 base** — 4 active dims (dim 5 org-scope deferred to 0.6.4): Dim 1 GuardDuty Detector enablement per region (CC7.1 — HIGH `gd-not-enabled`) + Dim 2 GuardDuty protection-feature coverage (CC7.1 institutional baseline) + Dim 3 Inspector2 enablement (CC7.1 + CC7.2 — DISABLED/SUSPENDED = HIGH) + Dim 4 Inspector2 scan-target coverage (CC7.1 zero / CC7.2 partial). Plugin 1200 audits AWS GuardDuty + AWS Inspector2 enablement state across **all opted-in regions** — **foundation-layer institutional evidence for CC7.1 detection procedures + CC7.2 monitoring** (an audit pack without managed-threat-detection evidence has no AWS-native anomaly-detection or CVE-detection stream). **v2 EE 0.6.2 GROWN scope** (closes 3 of 4 R2-deferred items from EE-RT.20 v1): **(a) Multi-region enumeration** — `ec2:DescribeRegions` enumerates opted-in regions (AllRegions=false defensively); per-region GuardDuty + Inspector2 dispatch; per-region findings carry region tag. Operator opts: `regions: string[]` (filter to subset, validated + deduped + capped 64 default), `skipMultiRegion: true` (cost-sensitive opt-out), `regionListCap` (1..256 clamp). Soft-degrade: EC2 SDK load failure / DescribeRegions AccessDenied → fall back to `config.region` + distinct `_CAT_REGION_ENUM_ACCESSDENIED` LOW finding. Back-compat: legacy single-region opts (`_guardDutyClient` / `_inspector2Client` singular) still respected. **(b) GuardDuty FindingPublishingFrequency check** — CC7.1 detection-latency. `_classifyGuardDutyFrequency` 4 outcomes: PASS `gd-frequency-optimal` / LOW `gd-frequency-suboptimal` / LOW `gd-frequency-unverifiable` (null detector or unknown enum). Operator-tunable: `gdFrequencyPassFrequency` (FIFTEEN_MINUTES / ONE_HOUR / SIX_HOURS; default FIFTEEN_MINUTES). **Ordering-based comparison** via `_GD_FREQUENCY_RANK` map (R-HIGH-2 fold) — stricter actual = PASS even when operator tuned baseline upward. **(e) Inspector2 baseline expansion** — `lambdaCode` (Lambda code scanning) + `codeRepository` (Inspector2 GitHub/GitLab scanning, GA 2024+) added to `_INS_INSTITUTIONAL_BASELINE_RESOURCES` (was {ec2, ecr, lambda}; now {ec2, ecr, lambda, lambdaCode, codeRepository}). **v1 dims preserved (4 active dims; dim 5 org-scope deferred to 0.6.3):** Dim 1 GuardDuty Detector enablement per region (CC7.1 — HIGH `gd-not-enabled`) + Dim 2 GuardDuty protection-feature coverage (CC7.1 — institutional baseline S3_DATA_EVENTS / EKS_AUDIT_LOGS / EBS_MALWARE_PROTECTION / RDS_LOGIN_EVENTS / LAMBDA_NETWORK_LOGS / RUNTIME_MONITORING) + Dim 3 Inspector2 enablement (CC7.1 + CC7.2 — DISABLED/SUSPENDED = HIGH) + Dim 4 Inspector2 scan-target coverage (CC7.1 zero / CC7.2 partial). **4 same-session R1 v2 reviewer folds** (network-security + Explore in parallel; 0 R-CRITICAL clean review pass): **R-HIGH-1 region regex GovCloud + ISO support** — pre-fold `^[a-z]{2,}-[a-z]+-[0-9]+$` silently dropped 4-part region IDs (`us-gov-east-1` / `us-iso-east-1` / `us-isob-east-1` / `us-isof-south-1`); operator passing `regions: ["us-gov-east-1"]` got silent skip + false-PASS — institutional-critical for FedRAMP / StateRAMP / IL5+ scope. Post-fold `^[a-z]{2,}(-[a-z]+){1,2}-[0-9]+$` admits 3- AND 4-part IDs. + **R-HIGH-2 frequency ordering not equality** (described above). + **R-MEDIUM-1 `_REGION_LIST_CAP` defensibility** — pre-fold hardcoded 32 silently truncated 4-part regions (AWS has ~40+ regions in 2026); post-fold default raised to 64 + operator-tunable + explicit truncation warning. + **R-LOW-1 EC2 client instrumentation** — operator-supplied `_ec2Client` now receives Thread-H AccessDenied counter + throttle-retry contract uniformly. **R2 reviewer-deferred** (queued in EE-RT.20.2 / 0.6.3): alerting-destination check (item c — needs `@aws-sdk/client-eventbridge` + `@aws-sdk/client-securityhub` integrations) + BatchGetAccountStatus contract verification (item d) + R-MEDIUM-2 `_getInspector2AccountStatus` return-shape refactor + optional dim 5 org-scope. **6 R1 v1 folds (EE 0.6.1) preserved as regression pins**: R1-CRITICAL-1 soc2.json titlePattern misalignment closure (4 patterns) + R1-CRITICAL-1 AccessDenied distinct findings + R1-CRITICAL-2 legacy DataSources case normalization + R1-HIGH-2 SUSPENDED/DISABLED Detector Status guard + R1-HIGH-3/4 dead-code drift closures. **No new SDK deps** — `@aws-sdk/client-guardduty` + `@aws-sdk/client-inspector2` + `@aws-sdk/client-ec2` already in optionalDependencies. 7 new soc2.json titlePattern entries from v1 still anchored. v2 tests: +27 (21 base + 6 R1-fold regression pins). Synthetic-mock validation only — no multi-region GuardDuty/Inspector2 paired fixtures yet in test-infra-builder. | CC7.1 / CC7.2 |
|
|
188
|
+
| 1200 | AWS Inspector2 / GuardDuty Enablement Auditor (NEW EE 0.6.1, EXTENDED EE 0.6.2 v2 multi-region + FindingPublishingFrequency + Inspector2 baseline expansion, EXTENDED EE 0.6.3 v3 alerting-destination dim closes substrate-without-sink false-PASS class, EXTENDED EE 0.6.4 v4 EventBridge target verification + multi-failedAccount + trigger uniformity, EXTENDED EE 0.6.5 v5 dead-target companion-LOW + sentinel observability + R-NIT named-constants, **EXTENDED EE 0.6.6 v6** — dead-target probe warm-up (IAM role + EventBridge API destination + CloudWatch Logs); plugin count UNCHANGED at 22 — existing plugin grew ~870 → ~1400 → ~2100 → ~2400 → ~2800 → ~3000 lines) | Enterprise | **v6 EE 0.6.6 dead-target probe warm-up** (closes the 0.6.5 R2-deferred long tail of unverifiable ARN shapes): three new branches in `_probeTargetLiveness` — **IAM role** (`iam:GetRole` on path-stripped role NAME extracted from `arn:aws:iam::ACCOUNT:role/[path/]NAME`; new SDK dep `@aws-sdk/client-iam`) + **EventBridge API destination** (`events:DescribeApiDestination` reuses existing `_EventBridgeSdk`) + **CloudWatch Logs log group** (`logs:DescribeLogGroups` with `logGroupNamePrefix` filter + **exact-name disambiguation guard** `groups.some((g) => g.logGroupName === logGroupName)` so prefix-match siblings don't false-LIVE; new SDK dep `@aws-sdk/client-cloudwatch-logs`). Companion-LOW emission contract unchanged (existing CC7.1 titlePattern is target-type-agnostic). **5 v6 R1 reviewer folds** (0 R-CRITICAL — clean review pass; 1 R-HIGH + 2 R-MEDIUM + 2 R-LOW): R-HIGH-1 (plugin 1170 v3) BFS short-circuits enqueue past per-target cap + **R-MEDIUM-1 IAM `NoSuchEntityException` / `NoSuchEntity` lifted into `_DEAD_TARGET_NOTFOUND_ERROR_NAMES` Set** (pre-fold the bare disjunction `err.name === "NoSuchEntityException"` at the IAM catch site bypassed the Set AND silently disabled `_retryOnNotFound` for IAM — the canonical worst-case for AWS eventual consistency with IAM lag 10-30s documented; **9th cumulative recurrence** of the `[[emit_literal_set_drift]]` class across the EE codebase; post-fold bare disjunction collapsed to `_isDeadTargetNotFoundError(err)` and eventual-consistency retry restored for IAM) + **R-MEDIUM-2 IAM partition-routing contract documented** at `_loadIamSdk` (`iam:GetRole` is a global API resolving per-partition — orchestrators wiring `opts._iamClient` must construct a single global IAM client per-partition NOT per-region; passing a commercial region in GovCloud / aws-cn / ISO flips the partition and routes to a wrong endpoint) + **R-LOW-2 (plugin 1200 v6) API destination ARN regex future-proofed** (trailing `/` made optional in `:api-destination\/([^/]+)` so future AWS ARN shapes without UUID suffix don't false-malformed). **v6.1 EE 0.6.7 closes the CloudWatch Logs probe retry-on-empty parity R2-deferred item**: `_retryOnNotFound` accepts an optional retry-on-result predicate; CWL Logs call site passes a predicate that fires retry when the response carries no exact-name match (covers both empty and prefix-only-sibling responses). **Restructured to two-phase to cap total network calls at 2 on compound paths** — Phase 1 = initial call + thrown-NotFound retry; Phase 2 = result-based retry; phases are MUTUALLY EXCLUSIVE (single retry total). A nested-try design would have layered both retries on compound paths (first-call empty → retry → second-call throws RNF → retry again), producing 3 network calls. The per-call-site outer catch routes a second-call thrown error (NotFound → DEAD; AccessDenied → UNVERIFIABLE). Existing call sites (Lambda / SNS / SQS / IAM / EventBridge API destination) pass only two args; the default `retryOnResultPredicate = null` cleanly skips Phase 2. **v6.1 R-LOW-1 fold**: compound-path coverage locked with 2 tests — transient empty → second-call AccessDenied → UNVERIFIABLE / transient empty → second-call thrown RNF → DEAD; both verify total network calls = 2 (drove the two-phase restructure decision). No new soc2.json mappings (companion-LOW pattern target-type-agnostic). v6 tests: +5 (2 IAM retry-regression: transient-NoSuchEntity-retry-succeeds + lowercase-NoSuchEntity-retry-then-DEAD; reviewer-fold regression pins also include 3 plugin 1170 v3 fixtures: hub-and-spoke per-target-cap + depthCapHit-true + depthCapHit-false). **v5 EE 0.6.5 v4-reviewer-cleanup cycle** (closes 4 R2-deferred items from EE-RT.20.3): **Dead-target companion-LOW** — closes the EE 0.6.4 R-HIGH-2 documented limitation. Per-target liveness probes for Lambda (`lambda:GetFunction` on full qualified ARN — alias/version correctness verified server-side) + SNS (`sns:GetTopicAttributes`) + SQS (`sqs:GetQueueUrl` + `GetQueueAttributes` — partition-aware via SDK URL resolution; works on aws-cn / aws-us-gov / aws-iso). New `_probeTargetLiveness` helper with parallel probes via Promise.all + per-target timeout (default 2s; operator-tunable via `deadTargetProbeTimeoutMs`). One-retry on NotFound with 750ms backoff (eventual-consistency defense). New MEDIUM verdict `*-alerting-destination-dead-targets` emitted as companion alongside PASS when at least one Target.Arn points to deleted resource. `deadTargetArnsTotal` + `deadTargetArnsTruncated` for JSON-consumer visibility on 11+ case. IAM role + API destination + CloudWatch Logs target probes deferred to 0.6.6 (3-4 more IAM grants). New operator opt `skipTargetLivenessProbe: true`. **Sentinel observability** — rule shape extended with `targetVerificationReason` (AccessDenied / SdkUnavailable / BeyondCap / SkippedByOpts) stable enum; classifier surfaces `targetVerificationReasonBreakdown` in unverifiable verdict details. **R-NIT named-constants** — `SH_HUB_NOT_ENABLED_ERROR_NAMES` frozen Set replaces 2 bare-string sites in SecurityHub helpers per `[[emit_literal_set_drift]]`. **Cross-plugin sessionToken sweep (catalog-wide)** — 18 EE AWS plugins (1020-1200) all thread `sessionToken` through their AWS-SDK credentials block. Closes AssumeRole-style auditor credential gap — auditors using `aws sts assume-role` (canonical cross-account audit pattern) had all auto-loaded clients fail signing pre-fold. **5 v5 R1 reviewer folds** (0 R-CRITICAL — clean review pass): R-HIGH-1 case-insensitive NotFound matching (defends against future AWS SDK case changes per `[[aws_string_case_normalization]]` 15× recurrent class) + R-HIGH-2 one-retry on NotFound (eventual-consistency defense; freshly-created resources transiently return NotFound for ~30s) + R-HIGH-3 Lambda probe passes FULL ARN to GetFunction.FunctionName (alias `PROD` pointing to deleted version surfaces as DEAD instead of false-LIVE) + R-HIGH (Explore) parallel probes via Promise.all + per-target timeout + R-MEDIUM-1 SQS partition-aware via `GetQueueUrl` (pre-fold synthesized `amazonaws.com` URL would have crashed on aws-cn / aws-us-gov / aws-iso partitions) + R-LOW-1 cap-constant lift to module-level + R-MEDIUM-2 truncation fields + R-NIT JSDoc accuracy. **R2 reviewer-deferred** (queued for 0.6.6): IAM role + API destination + CloudWatch Logs target liveness probes. 1 new soc2.json mapping rule (CC7.1 companion-LOW dead-target). New SDK deps `@aws-sdk/client-lambda` + `@aws-sdk/client-sns` + `@aws-sdk/client-sqs` (all already in optionalDependencies from prior cycles). v5 tests: +48 (1 R-NIT + 8 sentinel + 20 sessionToken-sweep + 15 dead-target base + 4 R-HIGH-fold regression pins). **v4 EE 0.6.4 reviewer-cleanup cycle** (closes 3 of 4 R2-deferred items from EE-RT.20.2): **R-HIGH-2 EventBridge target verification** — new `_listEventBridgeRuleTargets` helper with defensive NextToken pagination (hard cap 500); per-rule target verification via `events:ListTargetsByRule` (cap default 10 via `opts.targetVerificationRuleCap`; opt-out via `opts.skipEventBridgeTargetVerification`); new MEDIUM verdict `*-alerting-destination-targetless` for sink-less rules (zero Targets — substrate-without-sink at the rule level). **R-MEDIUM-2 multi-failedAccount surface** — Inspector2 helper return-shape `{accountStatus, accessDenied, failedAccounts: array}` (renamed plural; capped at AWS-documented 100); caller emits one LOW per failed account with per-region emission cap 10 + rollup LOW per region. **R-LOW-2 trigger uniformity** — GuardDuty alerting-destination trigger gates on `detector.Status === ENABLED` (matches Inspector2 enabled-only semantic). **5 v4 R1 reviewer folds** (0 R-CRITICAL — clean review pass): R-HIGH-1 cap-skew classifier branch (LOW UNVERIFIABLE not MEDIUM TARGETLESS when cap-exceeded rules could be the actual sink per `[[conservative_classifier_principle]]`) + R-HIGH consolidated `_listEventBridgeRuleTargets` pagination + JSDoc clarity + R-MEDIUM-1 multi-failedAccount per-region emission cap (10 + rollup LOW) + R-MEDIUM-4 boundary tests + R-HIGH-2 dead-target documented-limitation note (per-target liveness probes deferred to 0.6.5 companion-LOW; ~6 new IAM grants). **R2 reviewer-deferred** (queued for 0.6.5): R-LOW-3 sessionToken cross-plugin sweep (18 plugins) + companion-LOW for dead-target ARNs + `targetCount: null` sentinel observability + R-NIT named-constants for InvalidAccessException / ResourceNotFoundException. 1 new soc2.json mapping rule (CC7.1 MEDIUM TARGETLESS). v4 tests: +29 (3 R-LOW-2 + 6 R-MEDIUM-2 + 14 R-HIGH-2 base + 6 R1-fold regression pins). **v3 EE 0.6.3 alerting-destination dim (item c)** — closes the substrate-without-sink false-PASS class. Verifies at least one of EventBridge rule (source=`aws.guardduty`/`aws.inspector2`; `_eventBridgeSourceMatches` recognizes string + `{prefix}` + `{wildcard}` content-filter forms case-insensitively, regex-meta escape in wildcard glob defends against operator IaC) AND/OR SecurityHub product subscription (`_shArnMatchesProduct` boundary-anchored helper; constants `/aws/guardduty` + `/aws/inspector2` strict — does NOT match deprecated Inspector Classic). Verdict tiers per service per region: PASS `*-alerting-destination-present` (EB rule present) / MEDIUM `*-alerting-destination-sh-only` (R-HIGH-1 fold — SH aggregates but doesn't guarantee proactive paging; auditor walkthrough to confirm `aws.securityhub` EventBridge downstream rule) / HIGH `*-alerting-destination-missing` (no path; substrate-without-sink class) / LOW `*-alerting-destination-unverifiable` (AccessDenied / SDK unavailable; conservative classifier). New SDK deps `@aws-sdk/client-eventbridge` + `@aws-sdk/client-securityhub` (optionalDependencies). Operator opt: `skipAlertingDestination: true`. Soft-degrade on auto-load failure → fall back to LOW UNVERIFIABLE. **v3 R-MEDIUM-2 fold** — `_getInspector2AccountStatus` returns `{accountStatus, accessDenied, failedAccount}` distinguishing true AccessDenied from empty-body / SDK-unavailable (was `null | <obj>` pre-fold; caller emitted false `_CAT_INS_ACCESSDENIED` LOW on empty body). **v3 item (d) fold** — surfaces AWS-published `failedAccounts[].errorCode + errorMessage` via new `_CAT_INS_FAILED_ACCOUNT` LOW. **v3 R1 reviewer folds applied** (4 total; 1 R-CRITICAL + 2 R-HIGH + 1 R-LOW): R-CRITICAL-1 SH product ARN substring collision closure (`/aws/inspector` would have matched BOTH Inspector Classic deprecated-2024 AND Inspector2 — false-PASS for stale Classic subscriptions emitting zero findings; boundary-anchored helper + strict `/aws/inspector2` constant) + R-HIGH-1 SH-only PASS narrative split (PASS requires EB rule; SH-only → MEDIUM) + R-HIGH-3 EventBridge content-filter grammar (prefix + wildcard matchers) + R-LOW-1 source case normalization. **R2 reviewer-deferred** (queued for 0.6.4): R-HIGH-2 EB target verification (events:ListTargetsByRule + IAM grant) + R-LOW-2 asymmetric trigger uniformity + R-MEDIUM-2 multi-failedAccount surface + R-LOW-3 sessionToken support cross-plugin sweep. 5 new soc2.json titlePattern entries (4 CC7.1 + 1 CC7.2 PASS) all anchored to actual emission strings per `[[soc2_titlepattern_anchor_drift]]`. v3 tests: +61 (+8 suites) — 5 R-MEDIUM-2 + 5 item-(d) + 30 item-(c) base + 21 R1-fold regression pins. **v2 EE 0.6.2 dims preserved** (4 dims; v2 (a) multi-region enumeration via ec2:DescribeRegions + (b) FindingPublishingFrequency check + (e) Inspector2 baseline expansion +lambdaCode +codeRepository per Inspector2 GA 2024+; operator opts `regions[]` / `skipMultiRegion` / `regionListCap` / `gdFrequencyPassFrequency`; closes FedRAMP / StateRAMP / IL5+ false-PASS class for GovCloud + ISO regions via 4-part region regex fold). **v1 EE 0.6.1 base** — 4 active dims (dim 5 org-scope deferred to 0.6.4): Dim 1 GuardDuty Detector enablement per region (CC7.1 — HIGH `gd-not-enabled`) + Dim 2 GuardDuty protection-feature coverage (CC7.1 institutional baseline) + Dim 3 Inspector2 enablement (CC7.1 + CC7.2 — DISABLED/SUSPENDED = HIGH) + Dim 4 Inspector2 scan-target coverage (CC7.1 zero / CC7.2 partial). Plugin 1200 audits AWS GuardDuty + AWS Inspector2 enablement state across **all opted-in regions** — **foundation-layer institutional evidence for CC7.1 detection procedures + CC7.2 monitoring** (an audit pack without managed-threat-detection evidence has no AWS-native anomaly-detection or CVE-detection stream). **v2 EE 0.6.2 GROWN scope** (closes 3 of 4 R2-deferred items from EE-RT.20 v1): **(a) Multi-region enumeration** — `ec2:DescribeRegions` enumerates opted-in regions (AllRegions=false defensively); per-region GuardDuty + Inspector2 dispatch; per-region findings carry region tag. Operator opts: `regions: string[]` (filter to subset, validated + deduped + capped 64 default), `skipMultiRegion: true` (cost-sensitive opt-out), `regionListCap` (1..256 clamp). Soft-degrade: EC2 SDK load failure / DescribeRegions AccessDenied → fall back to `config.region` + distinct `_CAT_REGION_ENUM_ACCESSDENIED` LOW finding. Back-compat: legacy single-region opts (`_guardDutyClient` / `_inspector2Client` singular) still respected. **(b) GuardDuty FindingPublishingFrequency check** — CC7.1 detection-latency. `_classifyGuardDutyFrequency` 4 outcomes: PASS `gd-frequency-optimal` / LOW `gd-frequency-suboptimal` / LOW `gd-frequency-unverifiable` (null detector or unknown enum). Operator-tunable: `gdFrequencyPassFrequency` (FIFTEEN_MINUTES / ONE_HOUR / SIX_HOURS; default FIFTEEN_MINUTES). **Ordering-based comparison** via `_GD_FREQUENCY_RANK` map (R-HIGH-2 fold) — stricter actual = PASS even when operator tuned baseline upward. **(e) Inspector2 baseline expansion** — `lambdaCode` (Lambda code scanning) + `codeRepository` (Inspector2 GitHub/GitLab scanning, GA 2024+) added to `_INS_INSTITUTIONAL_BASELINE_RESOURCES` (was {ec2, ecr, lambda}; now {ec2, ecr, lambda, lambdaCode, codeRepository}). **v1 dims preserved (4 active dims; dim 5 org-scope deferred to 0.6.3):** Dim 1 GuardDuty Detector enablement per region (CC7.1 — HIGH `gd-not-enabled`) + Dim 2 GuardDuty protection-feature coverage (CC7.1 — institutional baseline S3_DATA_EVENTS / EKS_AUDIT_LOGS / EBS_MALWARE_PROTECTION / RDS_LOGIN_EVENTS / LAMBDA_NETWORK_LOGS / RUNTIME_MONITORING) + Dim 3 Inspector2 enablement (CC7.1 + CC7.2 — DISABLED/SUSPENDED = HIGH) + Dim 4 Inspector2 scan-target coverage (CC7.1 zero / CC7.2 partial). **4 same-session R1 v2 reviewer folds** (network-security + Explore in parallel; 0 R-CRITICAL clean review pass): **R-HIGH-1 region regex GovCloud + ISO support** — pre-fold `^[a-z]{2,}-[a-z]+-[0-9]+$` silently dropped 4-part region IDs (`us-gov-east-1` / `us-iso-east-1` / `us-isob-east-1` / `us-isof-south-1`); operator passing `regions: ["us-gov-east-1"]` got silent skip + false-PASS — institutional-critical for FedRAMP / StateRAMP / IL5+ scope. Post-fold `^[a-z]{2,}(-[a-z]+){1,2}-[0-9]+$` admits 3- AND 4-part IDs. + **R-HIGH-2 frequency ordering not equality** (described above). + **R-MEDIUM-1 `_REGION_LIST_CAP` defensibility** — pre-fold hardcoded 32 silently truncated 4-part regions (AWS has ~40+ regions in 2026); post-fold default raised to 64 + operator-tunable + explicit truncation warning. + **R-LOW-1 EC2 client instrumentation** — operator-supplied `_ec2Client` now receives Thread-H AccessDenied counter + throttle-retry contract uniformly. **R2 reviewer-deferred** (queued in EE-RT.20.2 / 0.6.3): alerting-destination check (item c — needs `@aws-sdk/client-eventbridge` + `@aws-sdk/client-securityhub` integrations) + BatchGetAccountStatus contract verification (item d) + R-MEDIUM-2 `_getInspector2AccountStatus` return-shape refactor + optional dim 5 org-scope. **6 R1 v1 folds (EE 0.6.1) preserved as regression pins**: R1-CRITICAL-1 soc2.json titlePattern misalignment closure (4 patterns) + R1-CRITICAL-1 AccessDenied distinct findings + R1-CRITICAL-2 legacy DataSources case normalization + R1-HIGH-2 SUSPENDED/DISABLED Detector Status guard + R1-HIGH-3/4 dead-code drift closures. **No new SDK deps** — `@aws-sdk/client-guardduty` + `@aws-sdk/client-inspector2` + `@aws-sdk/client-ec2` already in optionalDependencies. 7 new soc2.json titlePattern entries from v1 still anchored. v2 tests: +27 (21 base + 6 R1-fold regression pins). Synthetic-mock validation only — no multi-region GuardDuty/Inspector2 paired fixtures yet in test-infra-builder. | CC7.1 / CC7.2 |
|
|
189
189
|
| 1190 | AWS SES Email Integrity Auditor (NEW EE 0.4.7; EXTENDED EE 0.5.0 v2; CONSOLIDATED EE 0.5.2 v2.1; **EXTENDED EE 0.5.3 v3** — Part A DKIM public-key fingerprint capture/pin + Part B in-band DMARC alignment classifier; 5 same-session reviewer folds incl. 1 R-CRITICAL false-CLEAN closure on truncated DKIM keys via new `_stripControlCharsNoTruncate` helper; v2.1 closed — 7 deferred reviewer-fold items closed + new MEDIUM `ses-dkim-dns-partial-with-transients` category + module-load-time disjointness IIFE + silent-loss-class closure on SES classic API quota exhaustion via `cause: "classic-sdk-quota-exhausted"`) | Enterprise | **v2 EE 0.5.0 GROWN dims:** **dim 1 DKIM** — original substrate **PLUS v2 DKIM CNAME DNS resolution promotion**: each `<token>._domainkey.<domain>` CNAME resolved via node:dns/promises + matched against `<token>.dkim.amazonses.com` (case-insensitive per RFC 1035 §2.3.3); four outcomes PASS `ses-dkim-dns-verified` / MEDIUM `ses-dkim-dns-partial` / **HIGH `ses-dkim-dns-missing` (false-CLEAN closure: SES Status=SUCCESS but DNS removed)** / LOW + evidenceGap `ses-dkim-dns-unverifiable`. **dim 2 MailFrom** — original substrate **PLUS v2 DMARC TXT record parser + MailFrom promotion**: RFC 7489 §6.4 tag-list parser + `_dmarc.<identityDomain>` TXT lookup; five outcomes PASS `ses-dmarc-policy-reject` / MEDIUM `ses-dmarc-policy-quarantine` / HIGH `ses-dmarc-policy-none` / HIGH `ses-dmarc-missing` / LOW + evidenceGap `ses-dmarc-unverifiable`. **R-CRITICAL-1 fold (false-CLEAN closure)**: `pct=0` on `p=reject`/`p=quarantine` functionally equivalent to `p=none`; now routes to HIGH `ses-dmarc-policy-none`. **R-HIGH-1 fold (subdomain-takeover false-NEGATIVE closure)**: `sp` subdomain-policy override now evaluated — `p=reject; sp=none` downgrades to HIGH with `dmarcSpWeakens` (subdomain phishing wide open while apex protected). **dim 4 sending-auth policies** — original IAM-policy classifier **PLUS v2 SES classic GetIdentityPolicies parity**: `_loadSesClassicSdk` restored; cross-API discrepancy emits HIGH `ses-classic-policy-discrepancy` (classic-only — canonical false-NEGATIVE class) / MEDIUM (`_canonicalSort` JSON deep-equal ignores whitespace + key-order drift) / INFO (v2-only benign). Conservative on classic SDK unavailable / AccessDenied → LOW + evidenceGap. **v1 dims preserved unchanged:** TLS enforcement (dim 3) + dedicated IP pool (dim 5) + suppression list (dim 6 ZDE — count + reason only). **v2 promoter pattern**: sync v1 classifiers unchanged; async promoters walk collected findings post-classification. **R-HIGH-2 fold**: brittle `inTestMode = !!opts._client` coupling replaced with explicit `_skipV2Promotion` master switch + 3 orthogonal kill-switches. **First plugin in EE to depend on node:dns/promises** for live DNS cross-reference. **8 same-session v2 reviewer folds** (1 CRITICAL + 3 HIGH + 2 MEDIUM + 2 LOW); 6 queued in Pick-up Block. **Real-DNS smoke validation END-TO-END** against production resolvers (`_dmarc.nsasoft.us` parsed correctly: `p=reject, sp=reject, pct=100`; forward-compat `fo=1` tag preserved). Empty-account SESv2 enumeration baseline succeeded end-to-end against 522412052794. **v1 base (preserved):** First plugin in 1190-1199 ID range. Closes the next-highest-priority gap from `tasks/things-to-check.md` AWS SOC 2 audit-canonical compliance checklist after Redis closed in 0.4.6. **6 audit dimensions:** **DKIM enablement + signing status** (CC6.1 / Privacy — HIGH on `SigningEnabled=false`; transient PENDING/TEMPORARY_FAILURE/NOT_STARTED INFO + walkthroughRequired; FAILED MEDIUM on DNS drift; unknown enum LOW + evidenceGap per conservative-classifier-principle) + **custom MailFrom domain alignment** (Privacy substrate — INFO + walkthroughRequired on default amazonses.com / PASS on custom + Status=SUCCESS) + **configuration set TLS enforcement** (C1.1 — REQUIRE PASS / OPTIONAL HIGH SMTP-downgrade-attack window / non-string-but-truthy distinct LOW with `tlsPolicyType` evidence per R-MEDIUM-7 fold) + **identity sending authorization policy permissive principals** (CC6.6 — multi-class wildcard detector covering bare `"*"` / `{AWS:"*"}` / `{Service:"*"}` / `{Federated:"*"}` / `{CanonicalUser:"*"}` / array-form `[*]` per R-HIGH-4 fold + distinct HIGH `ses-sending-auth-notprincipal-allow` per R-CRITICAL-1 fold catching NotPrincipal+Allow wildcard-EQUIVALENT class + LOW + evidenceGap `ses-sending-auth-malformed-statement` per R-HIGH-2 fold) + **dedicated IP pool sending posture** (CC7.1 substrate, account-level — INFO + walkthroughRequired on configured pools / INFO on shared-pool default) + **suppression list state** (CC7.1 deliverability substrate — **ZDE invariant: NEVER reads suppressed-destination email addresses**; count + reason only; verified at run() envelope boundary via sentinel-string assertion per R-LOW-8 fold). Dual API surface discipline: v1 uses SESv2 only (canonical modern API); `@aws-sdk/client-ses` declared in optionalDependencies for v2+ cross-API parity. **11 same-session reviewer folds** — ties single-cycle reviewer-fold record. **CRITICAL-1 closure**: NotPrincipal+Allow false-CLEAN class (matches plugins 1070 + 1150 discipline). **HIGH-4 closure**: `_isWildcardPrincipal` walks every Principal class value (pre-fold only `principal.AWS` inspected, leaking `{Service:"*"}` + `{Federated:"*"}` as silent CLEAN). **No real-AWS smoke against violation-tier fixtures** — test-infra-builder has NO SES paired fixtures yet (full-stack fixtures deferred to v2 alongside DKIM CNAME DNS resolution + DMARC TXT record parsing); empty-account smoke baseline against 522412052794 DID succeed end-to-end. | CC6.1 / CC6.6 / C1.1 / CC7.1 (substrate) / Privacy (substrate) |
|
|
190
190
|
|
|
191
191
|
---
|