| 1 | Overview | 2 | Architecture Overview |
| 3 | AWS Service Topology | 4 | Implementation Guide |
| 5 | Decision Criteria | 6 | Cost Model |
| 7 | Anti-Patterns to Avoid | 8 | References |
Overview
The AWS security baseline is a layered stack of managed services applied consistently across all production accounts. GuardDuty detects threats using ML across VPC flow logs, DNS queries, and CloudTrail events. Security Hub aggregates findings from GuardDuty, Inspector, Macie, and partner tools into a unified posture view. Config continuously evaluates resource configurations against your defined rules. WAF filters malicious traffic at the HTTP layer. CloudTrail records every API call. IAM governs who can do what with what.
Architecture Overview
%%{init:{'theme':'base','themeVariables':{'fontSize':'14px','fontFamily':'Inter, system-ui, sans-serif','primaryColor':'#DBEAFE','primaryTextColor':'#1e3a5f','primaryBorderColor':'#2563EB','lineColor':'#374151','clusterBkg':'#F9FAFB','clusterBorder':'#D1D5DB','edgeLabelBackground':'#FFFFFF'},'flowchart':{'curve':'orthogonal','padding':30,'nodeSpacing':65,'rankSpacing':75,'useMaxWidth':true}}}%% flowchart TD START([AWS Account with Workloads]) subgraph PREVENT["Prevention Layer"] IAM_L[IAM — Least Privilege\nPermission boundaries\nSCPs on OU] VPC_L[VPC — Network Isolation\nPrivate subnets\nSecurity groups] WAF_L[AWS WAF\nOWASP Top 10 rules\nRate limiting] SSM_L[Secrets Manager\nNo hardcoded secrets\nAutomatic rotation] end subgraph DETECT["Detection Layer"] GD[GuardDuty\nML threat detection\nVPC, DNS, CloudTrail] CONFIG[AWS Config\nConfiguration compliance\nAuto-remediation rules] MACIE[Amazon Macie\nS3 PII discovery\nData classification] CT[CloudTrail\nAll API calls logged\n90 day free, S3 archive] end subgraph RESPOND["Response Layer"] SH[Security Hub\nUnified findings view\nCIS benchmark score] EV[EventBridge Rules\nRoute findings to\nSNS or Lambda] REMEDIATE[Auto-remediation\nLambda corrects drift\nConfig rule triggered] end DONE([Continuous Security Posture]) START --> PREVENT PREVENT --> DETECT DETECT --> SH SH --> EV --> REMEDIATE REMEDIATE --> DONE style START fill:#4f8ef7,color:#fff style DONE fill:#10b981,color:#fff style SH fill:#e0f2fe style REMEDIATE fill:#e0f2fe
AWS Service Topology
%%{init:{'theme':'base','themeVariables':{'fontSize':'14px','fontFamily':'Inter, system-ui, sans-serif','primaryColor':'#DBEAFE','primaryTextColor':'#1e3a5f','primaryBorderColor':'#2563EB','lineColor':'#374151','clusterBkg':'#F9FAFB','clusterBorder':'#D1D5DB','edgeLabelBackground':'#FFFFFF'},'flowchart':{'curve':'orthogonal','padding':30,'nodeSpacing':65,'rankSpacing':75,'useMaxWidth':true}}}%% flowchart TD TRAFFIC[Inbound Traffic] CALLS[AWS API Calls] RESOURCES[AWS Resources] DATA[S3 Data Buckets] TRAFFIC --> WAF_T[AWS WAF\nRate limit: 2000 RPM default\nAWSManagedRulesCommonRuleSet\nIP reputation lists] WAF_T --> ALB_T[ALB / CloudFront\nApplication entry point] CALLS --> CT_T[CloudTrail — All Regions\nManagement and data events\nS3 bucket with MFA delete\nCloudWatch Logs integration] CT_T --> GD_T[GuardDuty\nContinuous ML analysis\n200+ threat types\nMalware scanning] RESOURCES --> CONFIG_T[AWS Config\nResource inventory\nConformance packs\nCIS AWS Foundations] CONFIG_T --> DRIFT{Configuration\nDrift Detected?} DRIFT -->|Yes| REMEDIATE_T[Config Remediation\nSSM Automation document\nAuto-corrects known violations] DRIFT -->|No| COMPLIANT[Compliant State] DATA --> MACIE_T[Amazon Macie\nS3 PII classification\nCredit card, SSN, passport] GD_T & MACIE_T & CONFIG_T --> SH_T[Security Hub\nNormalised ASFF findings\nCIS score dashboard\nSuppression workflow] SH_T --> ALERT[SNS Alert\nPagerDuty or Slack\nHigh severity findings] style TRAFFIC fill:#4f8ef7,color:#fff style CALLS fill:#4f8ef7,color:#fff style COMPLIANT fill:#10b981,color:#fff style REMEDIATE_T fill:#e0f2fe style DRIFT fill:#fef3c7
Implementation Guide
CDK Stack — Security Baseline
import * as cdk from 'aws-cdk-lib';
import * as guardduty from 'aws-cdk-lib/aws-guardduty';
import * as config from 'aws-cdk-lib/aws-config';
import * as wafv2 from 'aws-cdk-lib/aws-wafv2';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as cloudtrail from 'aws-cdk-lib/aws-cloudtrail';
import * as s3 from 'aws-cdk-lib/aws-s3';
import { RemovalPolicy } from 'aws-cdk-lib';
export class SecurityBaselineStack extends cdk.Stack {
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// GuardDuty — enable with S3 and Kubernetes protection
new guardduty.CfnDetector(this, 'GuardDuty', {
enable: true,
dataSources: {
s3Logs: { enable: true },
kubernetes: { auditLogs: { enable: true } },
malwareProtection: {
scanEc2InstanceWithFindings: { ebsVolumes: true },
},
},
});
// CloudTrail — all regions, encrypted
const trailBucket = new s3.Bucket(this, 'TrailBucket', {
versioned: true,
removalPolicy: RemovalPolicy.RETAIN,
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
encryption: s3.BucketEncryption.S3_MANAGED,
});
new cloudtrail.Trail(this, 'AccountTrail', {
bucket: trailBucket,
isMultiRegionTrail: true,
includeGlobalServiceEvents: true,
enableFileValidation: true,
managementEvents: cloudtrail.ReadWriteType.ALL,
});
// AWS Config — CIS conformance pack
new config.CfnConformancePack(this, 'CisConformancePack', {
conformancePackName: 'CIS-AWS-Foundations-Benchmark-v1-4',
templateS3Uri: 's3://aws-config-rules-packages-ap-southeast-1/'
+ 'conformance-packs/CIS-AWS-Foundations-Benchmark-v1-4.yaml',
});
// WAF WebACL with managed rule groups + rate limit
new wafv2.CfnWebACL(this, 'AppWebACL', {
scope: 'REGIONAL',
defaultAction: { allow: {} },
rules: [
{
name: 'AWSManagedRulesCommonRuleSet',
priority: 1,
overrideAction: { none: {} },
statement: {
managedRuleGroupStatement: {
vendorName: 'AWS',
name: 'AWSManagedRulesCommonRuleSet',
},
},
visibilityConfig: {
sampledRequestsEnabled: true,
cloudWatchMetricsEnabled: true,
metricName: 'CommonRuleSet',
},
},
{
name: 'RateLimitRule',
priority: 2,
action: { block: {} },
statement: {
rateBasedStatement: { limit: 2000, aggregateKeyType: 'IP' },
},
visibilityConfig: {
sampledRequestsEnabled: true,
cloudWatchMetricsEnabled: true,
metricName: 'RateLimit',
},
},
],
visibilityConfig: {
sampledRequestsEnabled: true,
cloudWatchMetricsEnabled: true,
metricName: 'AppWebACL',
},
});
}
}
IAM Least-Privilege Pattern
// Service role with minimum required permissions
const serviceRole = new iam.Role(this, 'ServiceRole', {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
description: 'Order processor — read orders table, write events',
});
// Grant only what the function needs — no wildcard resources
serviceRole.addToPolicy(new iam.PolicyStatement({
sid: 'ReadOrdersTable',
effect: iam.Effect.ALLOW,
actions: ['dynamodb:GetItem', 'dynamodb:Query'],
resources: [ordersTable.tableArn],
conditions: { StringEquals: { 'aws:RequestedRegion': this.region } },
}));
// Deny dangerous actions explicitly as belt-and-suspenders
serviceRole.addToPolicy(new iam.PolicyStatement({
sid: 'DenyDangerousActions',
effect: iam.Effect.DENY,
actions: ['iam:*', 'organizations:*', 'account:*'],
resources: ['*'],
}));
Decision Criteria
| Service | What it detects | Without it you miss |
|---|---|---|
| GuardDuty | Runtime threats, compromised credentials, crypto mining | Active attacks in your account |
| Security Hub | Posture across all security services | Unified view of your security score |
| Config | Configuration drift from baseline | Resources misconfigured after deployment |
| WAF | HTTP-layer attacks, OWASP Top 10 | SQL injection, XSS, bot traffic |
| CloudTrail | Every API call | Who changed what and when — forensics |
| Macie | PII in S3 buckets | Sensitive data in wrong buckets |
Cost Model
| Service | Cost Driver | Typical monthly cost |
|---|---|---|
| GuardDuty | Events analysed + VPC flow logs | $50–300 per account |
| Security Hub | Findings ingested + compliance checks | $30–100 per account |
| Config | Configuration items recorded | $20–80 per account |
| CloudTrail | First trail free, extra copies billed | $0–20 per account |
| WAF | Web ACL + rules + requests | $10–40 per Web ACL |
Anti-Patterns to Avoid
Assigning the AWS-managed AdministratorAccess policy to Lambda functions, ECS task roles, or EC2 instance profiles. Any compromise of that workload gives full account access. Common in development accounts that drift to production.
Grant minimum required actions on specific resource ARNs. Use IAM Access Analyzer to generate least-privilege policies from CloudTrail activity. Enforce permission boundaries on all developer-created roles.
GuardDuty and Security Hub enabled but findings route to a dashboard that no one monitors. High-severity findings age to 90 days and expire. The services generate cost but provide no security value.
Connect Security Hub findings to EventBridge, route High and Critical to PagerDuty or Slack, and create a monthly review cadence for Medium findings. A security service without a response workflow is theatre.
Flowchart
References
- AWS — Security Hub User Guide. docs.aws.amazon.com/securityhub
- AWS — GuardDuty User Guide. docs.aws.amazon.com/guardduty
- CIS — AWS Foundations Benchmark v1.4. cisecurity.org/benchmark/amazon_web_services
- AWS — IAM Best Practices. docs.aws.amazon.com/IAM/latest/UserGuide/best-practices
- AWS — Well-Architected Security Pillar Whitepaper. docs.aws.amazon.com/wellarchitected