nsauditor-ai-agent-skill 0.1.30 → 0.1.32

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 CHANGED
@@ -4,6 +4,39 @@ Release notes for **`nsauditor-ai-agent-skill`** — installable knowledge packa
4
4
 
5
5
  ---
6
6
 
7
+ ## 0.1.32 — Catalog refresh: plugin 1025 GCP IAM Project-Level Auditor EXTENDED to v2 (3 dims → 7 dims) — paired with EE 0.7.1 trio-publish (EE-RT.22 v2 R2 expansion closing all 4 v1-deferred dims; +4 new dims: custom-role permission audit + SA key custody + SA impersonation graph BFS + Organization Policy constraint enumeration; NEW `utils/gcp_auth.mjs` helper honors `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT`; **17 same-session reviewer folds = NEW HIGH-WATER MARK** vs 0.7.0's 12 (1 R-CRITICAL EE-RT.20 class recurrence catch + 7 R-HIGH + 8 R-MEDIUM + 1 R-LOW(+1 grouped)); plugin count UNCHANGED at 24; +22 new soc2.json mappings; new SDK deps `googleapis` + `@google-cloud/org-policy` in optionalDependencies; twenty-second consecutive trio-publish)
8
+
9
+ **Trio-publish institutionalization continued.** Paired with EE 0.7.1 + CE 0.1.65 — **twenty-second consecutive trio-publish across EE + CE + agent-skill in a single session** (0.4.5–0.7.1).
10
+
11
+ ### Headline — EE-RT.22 v2 plugin 1025 R2 expansion
12
+
13
+ Plugin 1025 GCP IAM Project-Level Auditor extended from 3 audit dimensions to **7** via in-place R2 expansion (closes all 4 v1-deferred dims from the EE 0.7.0 cycle). Plugin count UNCHANGED at 24 (v2 = in-place expansion, not new plugin). Coverage matrix UNCHANGED at 10/4/33 — pure substrate-evidence depth uplift on already-covered CC6.1 / CC6.6 / C1.1 controls.
14
+
15
+ The 4 new dimensions: **Dim 4 custom-role permission audit** (CC6.1; admin-equivalent permission allowlist), **Dim 5 SA key custody** (CC6.1 + C1.1; user-managed long-lived keys = HIGH), **Dim 6 SA impersonation graph BFS** (CC6.1 flagship dim; mirrors plugin 1030 shadow-admin BFS adapted to GCP), **Dim 7 Organization Policy constraint enumeration** (CC6.6 + C1.1; 4 sensitive constraints).
16
+
17
+ NEW `utils/gcp_auth.mjs` helper honors `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` env var — closes the gap where GCP client libraries do NOT honor gcloud CLI's `auth/impersonate_service_account` config.
18
+
19
+ ### Reviewer fold high-water mark — 17 same-session folds
20
+
21
+ NEW HIGH-WATER MARK vs 0.7.0's 12 folds. Distribution: 1 R-CRITICAL + 7 R-HIGH + 8 R-MEDIUM + 1 R-LOW(+1 grouped). The R-CRITICAL fold (R2-CRITICAL-1) was an EE-RT.20 R1-CRITICAL-1 class recurrence — soc2.json PASS-tier SA-key patterns silently failed to match when plugin emitted `(display: 'X')` between email and `has` clause. Production false-clean impact would have been ~100% on real GCP fixtures. Patterns rewritten to `'[^']+'.*has`.
22
+
23
+ ### Cross-repo privacy scrub (parallel non-functional work)
24
+
25
+ Operator-flagged CRITICAL privacy class at 0.7.1 review: shipped npm files MUST NOT contain operator-private references. Substitutions applied across all 3 repos for personal emails / internal repo paths / real account IDs. New memory `[[npm_package_privacy]]` pinned. Force-push history rewrite applied to CE + agent-skill public repos to scrub identifiers from all historical commits.
26
+
27
+ ---
28
+
29
+ ## 0.1.31 — Catalog refresh: NEW EE-RT.22 v1 plugin 1025 GCP IAM Project-Level Auditor — paired with EE 0.7.0 trio-publish (MINOR-VERSION MILESTONE opening the v0.7.x cross-cloud-parity line; first plugin in the GCP-IAM-deep-audit cohort; 3 audit dimensions across CC6.1 + CC6.6; 12 R1 reviewer folds (0 R-CRITICAL + 2 R-HIGH + 5 R-MEDIUM + 5 R-LOW); plugin count 23 → 24; 11 new soc2.json mappings; new SDK dep `@google-cloud/resource-manager`; twenty-first consecutive trio-publish)
30
+
31
+ **Trio-publish institutionalization continued.** Paired with EE 0.7.0 + CE 0.1.64 — **twenty-first consecutive trio-publish across EE + CE + agent-skill in a single session** (0.4.5–0.7.0).
32
+
33
+ ### Changes
34
+
35
+ - **`references/plugins.md`** — added plugin 1025 row in sort order; demoted plugin 1024 (NEW EE 0.6.8) to non-NEW.
36
+ - **`SKILL.md`** — "post-EE 0.6.9" → "post-EE 0.7.0".
37
+
38
+ ---
39
+
7
40
  ## 0.1.30 — Catalog refresh: EE-RT.21 v2 R2 cleanup for plugin 1024 GCP Cloud Storage Auditor — paired with EE 0.6.9 trio-publish (patch-level R2 reviewer-deferred-items cleanup: Appendix A multi-cloud renderer extension + evidence-gap soc2.json mappings; 5 R1 reviewer folds (0 R-CRITICAL + 1 R-HIGH + 1 R-MEDIUM + 3 R-LOW); plugin count UNCHANGED at 23; 3 new soc2.json mappings; NEW pre-publish doc-consistency gate; twentieth consecutive trio-publish)
8
41
 
9
42
  **Trio-publish institutionalization continued.** Paired with EE 0.6.9 + CE 0.1.63 — **twentieth consecutive trio-publish across EE + CE + agent-skill in a single session** (0.4.5–0.6.9).
@@ -415,7 +448,7 @@ npm install nsauditor-ai-agent-skill@0.1.17
415
448
  - **Part C — SES classic GetIdentityPolicies parity** (dim 4) — `_loadSesClassicSdk` restored (was removed in v1 reviewer-fold MEDIUM as dead-code load-check). Cross-API discrepancy detection emits HIGH `ses-classic-policy-discrepancy` on classic-only policies (canonical false-NEGATIVE class). Conservative on classic SDK unavailable / AccessDenied → LOW + evidenceGap `ses-classic-policy-unverifiable`.
416
449
  - **8 same-session reviewer folds across the cycle** (1 CRITICAL + 3 HIGH + 2 MEDIUM + 2 LOW); 6 queued in Pick-up Block.
417
450
  - **First plugin in EE to depend on `node:dns/promises`** — first ship to add NETWORK-LAYER cross-reference to AWS-SDK-substrate evidence baseline; structurally distinct evidence-acquisition surface from prior 0.4.x cycles.
418
- - **Real-DNS smoke validation END-TO-END** against production DNS resolvers — `_dmarc.nsasoft.us` parsed correctly: `p=reject, sp=reject (default), pct=100`; forward-compat `fo=1` tag preserved in `rawTags`. Empty-account SESv2 enumeration baseline succeeded end-to-end against 522412052794.
451
+ - **Real-DNS smoke validation END-TO-END** against production DNS resolvers — `_dmarc.nsasoft.us` parsed correctly: `p=reject, sp=reject (default), pct=100`; forward-compat `fo=1` tag preserved in `rawTags`. Empty-account SESv2 enumeration baseline succeeded end-to-end against <operator-test-account>.
419
452
  - **EE full regression: 4787/4787** (was 4696 at EE 0.4.9 publish; +91 tests cumulative across the v2 cycle). 46-session 100% green streak preserved.
420
453
  - **Coverage matrix UNCHANGED at 10/4/33** — substrate evidence depth growth on already-covered CC6.1 + CC6.6 via 11 new aws-ses-auditor mapping rules. The 0.5.0 bump (vs the natural 0.4.10) is an institutional milestone marker — first non-0.4.x release in the 0.4.5–0.5.0 trio-publish series + first ship to add NETWORK-LAYER cross-reference.
421
454
 
@@ -440,7 +473,7 @@ npm install nsauditor-ai-agent-skill@0.1.17
440
473
  - **Part B — Subnet route-table verifier** (dim 6 subnet placement; closes v1 R-LOW-2). `elasticache:DescribeCacheSubnetGroups` + `ec2:DescribeRouteTables` walk. Per-subnet IGW-route detection via `/^igw-[a-f0-9]+$/i` (correctly excludes egress-only `eigw-`). HIGH on IGW-routed subnet(s) (with per-subnet `igwDestinationsBySubnet` evidence per R-HIGH-1 fold) / PASS on all-verified-private / **LOW + evidenceGap on main-RT-inheritance per R-MEDIUM-2 reviewer-fold false-NEGATIVE closure** (default-VPC main-RT typically routes `0.0.0.0/0 → igw-*`).
441
474
  - **7 same-session reviewer folds across the cycle** (independent `general-purpose-agent` review yielded 12 findings; 7 folded same-session, 1 deferred to cross-plugin Thread H sweep, 4 withdrawn after verification).
442
475
  - **No new SDK dependencies** — `@aws-sdk/client-kms` + `@aws-sdk/client-ec2` already declared in optionalDependencies since EE 0.4.5.
443
- - **Real-AWS smoke validation END-TO-END**: smoke against `522412052794` (no fixture changes needed). `redis-leaky-cache` → dim 6 LOW `elasticache-subnet-main-rt-inheritance` (the R-MEDIUM-2 fold escalation demonstrably firing against the real default-VPC main-RT-inheritance pattern); `findingsBySeverity: { pass:1, medium:3, high:5, low:2, info:1 }`; durationMs=1428. KMS promotion path NOT exercised against real AWS (existing fixtures use alias-form CMK keys; unit tests + plugin 1140 v2 real-AWS validation cover the promotion path).
476
+ - **Real-AWS smoke validation END-TO-END**: smoke against `<operator-test-account>` (no fixture changes needed). `redis-leaky-cache` → dim 6 LOW `elasticache-subnet-main-rt-inheritance` (the R-MEDIUM-2 fold escalation demonstrably firing against the real default-VPC main-RT-inheritance pattern); `findingsBySeverity: { pass:1, medium:3, high:5, low:2, info:1 }`; durationMs=1428. KMS promotion path NOT exercised against real AWS (existing fixtures use alias-form CMK keys; unit tests + plugin 1140 v2 real-AWS validation cover the promotion path).
444
477
  - **EE full regression: 4696/4696** (was 4642 at EE 0.4.8 publish; +54 tests). 45-session 100% green streak preserved.
445
478
  - **Coverage matrix UNCHANGED at 10/4/33** — substrate evidence depth growth on already-covered CC6.6 + C1.1 via 5 new aws-elasticache-redis-auditor mapping rules.
446
479
 
@@ -495,7 +528,7 @@ npm install nsauditor-ai-agent-skill@0.1.17
495
528
  - **Fourth EE plugin to ship without smoke-time SDK hotfix** — preemptive `@aws-sdk/client-ses` + `@aws-sdk/client-sesv2` addition.
496
529
  - **EE full regression: 4574/4574** (was 4458 at EE 0.4.6 publish; +116 tests across the cycle: 94 EE-RT.18 v1 unit-test suite + 22 reviewer-fold pin tests). 43-session 100% green streak preserved.
497
530
  - **Coverage matrix UNCHANGED at 10/4/33** — substrate-evidence depth growth on already-covered CC6.1 / CC6.6 / C1.1 via 8 new aws-ses-auditor mapping rules.
498
- - **No real-AWS smoke against violation-tier fixtures** — test-infra-builder has NO SES paired fixtures yet (full-stack fixtures deferred to EE-RT.18 v2 alongside DKIM CNAME DNS resolution + DMARC TXT record parsing). Empty-account smoke baseline against 522412052794 DID succeed end-to-end (plugin loads via CE→EE binding, all 4 SESv2 API enumerations succeed, baseline 2 INFO findings emit correctly, durationMs=842, ZDE invariant preserved).
531
+ - **No real-AWS smoke against violation-tier fixtures** — operator's internal test infrastructure has NO SES paired fixtures yet (full-stack fixtures deferred to EE-RT.18 v2 alongside DKIM CNAME DNS resolution + DMARC TXT record parsing). Empty-account smoke baseline against <operator-test-account> DID succeed end-to-end (plugin loads via CE→EE binding, all 4 SESv2 API enumerations succeed, baseline 2 INFO findings emit correctly, durationMs=842, ZDE invariant preserved).
499
532
  - **Memory tag closures:** `aws_string_case_normalization` at **20×** with explicit SPLIT-SURFACE callout (DKIM/Tls/MailFromStatus enums upcased / IAM Action/Effect lowercased); `conservative_classifier_principle` reinforced in 5 new fold sites; `emit_literal_set_drift` extended with `_DKIM_STATUS_VALID` + `_MAILFROM_STATUS_SUCCESS` + `_TLS_POLICY_VALID` named-constant discipline.
500
533
 
501
534
  **Recommended install path:** `npm install nsauditor-ai-agent-skill@0.1.13` (for AI-coding-agent users; pair with `npm install -g nsauditor-ai@0.1.46 @nsasoft/nsauditor-ai-ee@0.4.7`).
package/SKILL.md CHANGED
@@ -297,7 +297,7 @@ CE collision. CE reserves 001-099.
297
297
 
298
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
299
 
300
- **EE SOC 2 substrate-evidence coverage (post-EE 0.6.9):** 10 covered controls (CC6.1 /
300
+ **EE SOC 2 substrate-evidence coverage (post-EE 0.7.1):** 10 covered controls (CC6.1 /
301
301
  CC6.2 / CC6.6 / CC6.7 / CC6.8 / CC7.1 / CC7.2 / CC7.3 / C1.1 / C1.2) + 4 partial
302
302
  (CC6.3 / CC8.1 / A1.2 / PI1.5) + 33 OOS for static substrate scanning. Coverage matrix
303
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.30",
3
+ "version": "0.1.32",
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",
@@ -169,7 +169,8 @@ listings, and default pages.
169
169
  | 1021 | GCP Cloud Scanner | Enterprise | Firewall rule audit + IAM bindings + Storage bucket public-access | CC6.1 / CC6.6 / C1.1 |
170
170
  | 1022 | Azure Cloud Scanner | Enterprise | NSG rule analysis + RBAC role assignments + Storage account hardening | CC6.1 / CC6.6 / C1.1 |
171
171
  | 1023 | Zero Trust Checker | Enterprise | Segmentation + encryption + identity + lateral movement scoring (reads OBSERVED open ports) | CC6.6 |
172
- | 1024 | GCP Cloud Storage Auditor (NEW EE 0.6.8) | Enterprise | Multi-cloud parity sister of plugin 1020 AWS S3. 6 dimensions: bucket-level IAM public bindings (allUsers = CRITICAL, allAuthenticatedUsers = HIGH); Uniform Bucket-Level Access enforcement (closes legacy bucket-ACL false-PASS class); Object Versioning; Bucket Lock retention policy (SEC 17a-4 / FINRA 4511 WORM-alignment); CMEK via Cloud KMS (four-tier custody ladder); bucket-level access logging. NEW SDK dep `@google-cloud/storage`. | CC6.1 / CC6.6 / CC7.1 / C1.1 / C1.2 / A1.2 |
172
+ | 1024 | GCP Cloud Storage Auditor (EE 0.6.8) | Enterprise | Multi-cloud parity sister of plugin 1020 AWS S3. 6 dimensions: bucket-level IAM public bindings (allUsers = CRITICAL, allAuthenticatedUsers = HIGH); Uniform Bucket-Level Access enforcement (closes legacy bucket-ACL false-PASS class); Object Versioning; Bucket Lock retention policy (SEC 17a-4 / FINRA 4511 WORM-alignment); CMEK via Cloud KMS (four-tier custody ladder); bucket-level access logging. NEW SDK dep `@google-cloud/storage`. | CC6.1 / CC6.6 / CC7.1 / C1.1 / C1.2 / A1.2 |
173
+ | 1025 | GCP IAM Project-Level Auditor (NEW EE 0.7.0; **EXTENDED EE 0.7.1 v2** — 3 dims → 7 dims via in-place R2 expansion closing all 4 v1-deferred dims; 17 same-session reviewer folds = NEW HIGH-WATER MARK vs 0.7.0's 12) | Enterprise | First plugin in the v0.7.x GCP-IAM-deep-audit cohort. Mirrors plugin 1030 AWS IAM Deep Auditor's shadow-admin discipline adapted to the GCP IAM data model. **7 dimensions (v2 EE 0.7.1):** **v1 dims preserved:** project-scope public-member bindings (allUsers = CRITICAL, allAuthenticatedUsers = HIGH at the project root); admin-equivalent role inventory across 12 predefined sensitive roles (roles/owner, roles/editor, roles/iam.securityAdmin, roles/resourcemanager.projectIamAdmin, the iam.serviceAccount* impersonation cohort, the workloadIdentity cohort); IAM Conditions classifier on sensitive-role bindings (restrictive CEL token allowlist = PASS, absent on sensitive = MEDIUM, vacuous = LOW + evidenceGap). **v2 NEW dims (EE 0.7.1):** **dim 4 custom-role permission audit** (CC6.1; `iam.projects.roles.list` view=FULL; `*` wildcard = CRITICAL; admin-equivalent permission intersection across `_ADMIN_EQUIVALENT_PERMISSIONS` 16-entry allowlist = HIGH — expanded 11→16 via R1-MED-2 fold to include `iam.serviceAccounts.create` + `.disable` + `.enable` for audit-evasion class + `iam.denypolicies.create` + `iam.workloadIdentityPools.create` for federation backdoor) + **dim 5 SA key custody** (CC6.1 + C1.1 dual-mapped; user-managed long-lived keys = HIGH — canonical SA-credential-leakage class; 90-day rotation narrative-uplift; per-SA `keysFetchError` propagation closes silent-PASS false-clean class via R2-HIGH-5 fold) + **dim 6 SA impersonation graph BFS** (CC6.1; mirrors plugin 1030 shadow-admin BFS adapted to GCP IAM data model; per-PATH visited Set for cycle defense; default depth cap = 4; walks the 3 canonical impersonation roles `roles/iam.serviceAccountTokenCreator` + `serviceAccountUser` + `serviceAccountOpenIdTokenCreator`; 2-hop = HIGH, 3+ hop = CRITICAL; **project-scope impersonation grants surface independently as CRITICAL `_CAT_SA_IMPERSONATION_PROJECT_SCOPE`** via R1-HIGH-2 fold — real GCP privesc class entirely missed pre-fold; public-sentinel impersonation grants surface INDEPENDENTLY of BFS as CRITICAL `_CAT_SA_IMPERSONATION_PUBLIC`) + **dim 7 Organization Policy constraint enumeration** (CC6.6 + C1.1 dual-mapped; `@google-cloud/org-policy` ListPolicies; 4 sensitive constraints `iam.disableServiceAccountKeyCreation` + `.disableServiceAccountKeyUpload` + `iam.allowedPolicyMemberDomains` + `iam.automaticIamGrantsForDefaultServiceAccounts`; enforce/denyAll/allowlist = PASS; absent/not-enforced/`reset:true` = MEDIUM via R1-HIGH-4 fold). **NEW `utils/gcp_auth.mjs`** honors `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` env var (closes the gap where GCP client libraries do NOT honor gcloud CLI's `auth/impersonate_service_account` config). **R-CRITICAL fold (R2-CRITICAL-1) — EE-RT.20 R1-CRITICAL-1 class recurrence catch**: soc2.json PASS-tier SA-key patterns silently failed to match when plugin emitted `(display: 'X')` between email and `has` clause; production false-clean impact would have been ~100% on real GCP fixtures. Patterns rewritten to `'[^']+'.*has`; displayName-populated test fixtures added. **+22 new soc2.json mappings** (plugin 1025 total 11 → 33: 12 CC6.1 + 3 CC6.6 + 7 C1.1 dual-maps). **NEW SDK deps:** `googleapis` + `@google-cloud/org-policy` in optionalDependencies (lazy-loaded with graceful degradation; missing SDK skips affected dim cohort). | CC6.1 / CC6.6 / C1.1 |
173
174
  | 1030 | AWS IAM Deep Auditor | Enterprise | Shadow-admin path detection via BFS over PassRole / AssumeRole / federated trust; restrictive-Condition allowlist (Auth0 / Okta / Cognito) | CC6.1 |
174
175
  | 1040 | AWS CloudTrail Operational Integrity | Enterprise | Trail health + log-file validation + KMS-CMK; CloudWatch alarm coverage vs CIS AWS Foundations Benchmark v1.5 §3.1–3.14; cross-account S3 trail-destination WORM verification (SEC 17a-4 / FINRA 4511) | CC7.2 / CC7.3 |
175
176
  | 1050 | AWS API Gateway Assurance | Enterprise | Per-method/route authorization classifier; custom-domain TLS policy; stage-level access logging / throttling / WAF; public-endpoint exposure; Lambda authorizer cross-reference via lambda:GetFunction | CC6.1 / CC6.6 / CC6.7 / CC7.1 / A1.2 |
@@ -181,13 +182,13 @@ listings, and default pages.
181
182
  | 1110 | AWS IAM Effective Decrypt-Path Auditor | Enterprise | Cross-plugin reconciler: walks IAM policies for kms:Decrypt / kms:ReEncrypt / kms:GenerateDataKey grants and cross-references against destination KMS key policies (plugin 1070) to compute effective decrypt path; closes NotAction-implicit-decrypt false-PASS class | CC6.1 / CC6.6 / C1.1 / C1.2 |
182
183
  | 1120 | AWS S3 Lifecycle + Cross-Region Replication Auditor | Enterprise | S3 lifecycle policy enumeration (CC7.1 retention-cadence) + cross-region replication topology (A1.2 DR substrate); destination-bucket reachability verification closes silent-PASS class where replication source FAILED but emitted clean | C1.1 / C1.2 / A1.2 |
183
184
  | 1130 | AWS Backup Auditor — headline thread | Enterprise | The largest single-plugin institutional-hardening arc in the EE codebase (~7800 lines, 545 tests). Audits Plans + Vaults + Recovery Points + Selections + Frameworks + Restore Testing + ReportPlans + Legal Holds + VaultType + Vault Tags + Vault Access Policy. **12-dimension air-gapped vault attestation arc** for LogicallyAirGappedBackupVault: 6 cryptographic-isolation mechanisms (vault TYPE + ARN account-segment-separation + destination KMS key-policy clean + destination KMS Grants clean + MRK-replica topology clean + source-account VPC-endpoint policy clean) + 6 substrate dimensions (PITR/retention/encryption/RestoreTesting/Legal Holds/vault Access Policy) | CC6.3 / CC6.6 / CC7.1 / CC8.1 / C1.1 / C1.2 / A1.2 |
184
- | 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 |
185
- | 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 |
186
- | 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) |
185
+ | 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 `<operator-test-account>`** (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 |
186
+ | 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 operator's internal test infrastructure; 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 |
187
+ | 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 operator's internal test infrastructure. | CC6.6 / A1.2 / CC7.2 / Privacy (substrate) |
187
188
  | 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 |
188
- | 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 |
189
- | 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 |
190
- | 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) |
189
+ | 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 <operator-test-account>**: 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 |
190
+ | 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 operator's internal test infrastructure. | CC7.1 / CC7.2 |
191
+ | 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 <operator-test-account>. **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** — operator's internal test infrastructure 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 <operator-test-account> DID succeed end-to-end. | CC6.1 / CC6.6 / C1.1 / CC7.1 (substrate) / Privacy (substrate) |
191
192
 
192
193
  ---
193
194