mirror of
https://github.com/Sea-Haven-Industries/seahaven-org-baseline.git
synced 2026-09-30 05:43:17 +00:00
feat: harden CIS 4.1 detection depth with M-of-N alarm tuning and CloudTrail Insights (#38)
Switch UnauthorizedApiCalls alarm from 3/3 consecutive to 3/6 M-of-N so a single quiet 5-min window can't reset detection. The 3/3 setting pre-dates #36 and was sized to suppress CFN/Config noise that #36 now removes at the filter level, making a wider M-of-N evaluation window safe from flap risk. Enable CloudTrail Insights (ApiCallRateInsight + ApiErrorRateInsight) on seahaven-org-trail as a compensating control for the residual risk accepted in #36 — the CFN/Config-proxied denials intentionally excluded from CIS 4.1 — and as a backstop for low-and-slow patterns the 5-min alarm may miss. Cost ≈$35–$53/month at current org trail volume. Refs: #37 Co-authored-by: amoussa1229 <166072409+amoussa1229@users.noreply.github.com>
This commit is contained in:
parent
0d654edb35
commit
142e221c47
3 changed files with 22 additions and 6 deletions
|
|
@ -30,7 +30,7 @@ The canonical map of Sea Haven's AWS infrastructure lives in Confluence. This pr
|
|||
|
||||
| Resource | Logical ID | Notes |
|
||||
|---|---|---|
|
||||
| Multi-region trail | `Trail` (`seahaven-org-trail`) | Management events read+write, global service events, **log-file validation on** |
|
||||
| Multi-region trail | `Trail` (`seahaven-org-trail`) | Management events read+write, global service events, **log-file validation on**, **CloudTrail Insights on** (ApiCallRate + ApiErrorRate, §37) |
|
||||
| Log bucket | `TrailLogBucket` (`seahaven-cloudtrail-logs-328440206208`) | Private (Block Public Access all), SSE-KMS, versioned, **TLS-only**, **Object Lock GOVERNANCE 365d**, lifecycle (Glacier @90d, expire @365d), server access logging → `seahaven-s3-access-logs` |
|
||||
| KMS CMK | `TrailKey` (`alias/cloudtrail-logs`) | Encrypts log files; **automatic rotation enabled** |
|
||||
| CloudWatch Logs group | created by the L2 `Trail` | 365-day retention; this is the group the CIS Section 4 metric filters (H-1) attach to |
|
||||
|
|
|
|||
|
|
@ -208,6 +208,19 @@ export class AccountBaselineStack extends cdk.Stack {
|
|||
sendToCloudWatchLogs: true,
|
||||
cloudWatchLogGroup: trailLogGroup,
|
||||
managementEvents: cloudtrail.ReadWriteType.ALL,
|
||||
// CloudTrail Insights (§37): compensating control for the residual risk
|
||||
// accepted in #36 (CFN/Config-proxied denials excluded from CIS 4.1) and
|
||||
// the low-and-slow evasion surface in the UnauthorizedApiCalls alarm.
|
||||
// ApiCallRateInsight flags anomalous write-API spikes; ApiErrorRateInsight
|
||||
// flags anomalous errored/denied call rates — including the denials CIS
|
||||
// 4.1 intentionally filters out. Per-event cost (≈$0.35/100k management
|
||||
// events); an org trail with 10–15M management events/month adds roughly
|
||||
// $35–$53/month. CIS 4.1 alarm + GuardDuty + Security Hub (CIS v3.0) are
|
||||
// already live, so this is defence-in-depth, not an urgent gap-fill.
|
||||
insightTypes: [
|
||||
cloudtrail.InsightType.API_CALL_RATE,
|
||||
cloudtrail.InsightType.API_ERROR_RATE,
|
||||
],
|
||||
});
|
||||
|
||||
// ── Day 1 detective layer + governance toggles ──
|
||||
|
|
|
|||
|
|
@ -72,11 +72,14 @@ const CIS_CONTROLS: CisControl[] = [
|
|||
pattern:
|
||||
'{ (($.errorCode = "*UnauthorizedOperation") || ($.errorCode = "AccessDenied*")) && ($.sourceIPAddress != "*cloudformation.amazonaws.com") && ($.sourceIPAddress != "config.amazonaws.com") && ($.sourceIPAddress != "delivery.logs.amazonaws.com") && ($.eventName != "HeadBucket") }',
|
||||
description: "CIS 4.1 — unauthorized API calls",
|
||||
// Belt-and-suspenders after the service-noise exclusion above: still require
|
||||
// 3 consecutive breaching 5-min periods so a one-off human fat-finger that
|
||||
// self-recovers doesn't page, while sustained unauthorized activity (e.g. a
|
||||
// misconfigured role failing every call) still trips within ~15 minutes.
|
||||
evaluationPeriods: 3,
|
||||
// M-of-N with N > M so a single quiet 5-min window cannot reset detection.
|
||||
// Before #36, false positives from CFN/Config-proxied denials forced a
|
||||
// conservative 3/3 consecutive; now that #36 scoped the metric-filter
|
||||
// exclusion to those benign sources, we can widen the evaluation window
|
||||
// while keeping the same alarm threshold. An attacker pacing denied calls to
|
||||
// leave every third window empty would evade a 3/3 alarm but still trips a
|
||||
// 3/6 — three breaching windows in any rolling 30-min span fire the alarm.
|
||||
evaluationPeriods: 6,
|
||||
datapointsToAlarm: 3,
|
||||
},
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue