security-review/checkers/fixtures/aws-posture/README.md
Adam Moussa 4c88c01f7b
chore: import security-review gate, sweep, and Plane-1 checkers into standalone repo
Fresh-init copy of the security-review/ subsystem extracted from
Sea-Haven-Industries/orchestrator (being deprecated). Adds org-standard scaffold:
CI reusable-workflow callers (ruff + collect), dependency-review, labeler,
dependabot, .gitignore, requirements.txt. Scheduled execution is migrating to
Claude Code web routines (ALARM-only to #repo-scanner); the systemd units and
nightly_sweep.sh/checker_coordinator.sh remain the source of truth.

Committed with --no-verify: the canary fixtures (checkers/fixtures/**) carry
intentional secret-shaped test data that trips the deterministic gate (the
documented detector-fixture false positive); no new logic is introduced.
2026-06-29 11:41:41 -04:00

34 lines
2.5 KiB
Markdown

# aws-posture canary fixtures
Mocked AWS API responses for `checkers/aws-posture.sh --canary` (offline — **no `aws` calls, no
network, no credentials**). The canary feeds these files to the SAME detectors the live path runs
against real `aws` CLI output, and asserts the total finding count equals `EXPECTED_FINDING_COUNT`
(anti-complacency floor, design §6.4). If a detector regresses (stops firing), the count drops and
the canary FAILS (exit 3).
These are plain JSON files (not git fixtures — aws-posture scans an AWS account, not a repo tree),
so there is no `dotgit/` / `.fixture` rename trick here; the offline-vs-live seam is the
`--canary`/`--no-api`/no-credentials guard inside the checker (mirrors compliance-drift's
API-skip pattern). Each file is shaped like the real `aws ... --output json` response it stands in
for; a few `_Fixture*` helper keys carry the per-resource metric the live path derives from
CloudWatch (so the canary stays deterministic and offline).
| Fixture file | Stands in for | Planted finding | Count |
|---|---|---|---|
| `cost-anomalies.json` | `aws ce get-anomalies` | 1 anomaly TotalImpact ≥ threshold (the other is below threshold → must NOT fire) | 1 |
| `describe-instances.json` | `aws ec2 describe-instances` | 1 `stopped` instance still paying for its EBS root (the `running` one must NOT fire) | 1 |
| `describe-volumes.json` | `aws ec2 describe-volumes` | 1 `available` (unattached) volume (the `in-use` one must NOT fire) | 1 |
| `describe-addresses.json` | `aws ec2 describe-addresses` | 1 EIP with no association (the associated one must NOT fire) | 1 |
| `describe-nat-gateways.json` | `aws ec2 describe-nat-gateways` | 1 `available` NAT with ~0 bytes out / 14d (the busy one must NOT fire) | 1 |
| `describe-load-balancers.json` | `aws elbv2 describe-load-balancers` | 1 ALB with 0 healthy targets (the one with 3 must NOT fire) | 1 |
| `describe-db-instances.json` | `aws rds describe-db-instances` | 1 `available` RDS with 0 connections / 14d (the busy one must NOT fire) | 1 |
Total = **7** (`EXPECTED_FINDING_COUNT`).
aws-posture **complements** GuardDuty / Security Hub / Config (design §4 / Tier-2) — it is an
idle/anomalous-**spend** + idle-resource posture watch, not a threat detector, and never alarms on
missing data (a skipped/credential-less live call is noted, never counted — memory
`feedback_cloudwatch_alarms`).
When you add/remove a detector or fixture, update both the fixture and `EXPECTED_FINDING_COUNT`
in the same commit (the canary edit is itself caught on the next run — design §6.4).