qasim@wiki:~$

AWS Security Hardening

ScopeAccount-level, network-level, and workload-level hardening
Applies toThe WAF + ELB + Auto Scaling reference architecture in this section
SkillsIAM, VPC, KMS, GuardDuty, Security Hub, CloudTrail, WAF, Config
The principle: hardening isn't a checklist you run once — it's layered controls where each layer assumes the one in front of it will eventually fail. This page walks the layers from the account boundary inward to the running workload, using the services documented elsewhere in this section.

1 — Account & identity foundation

Root account & IAM

  • Root account: MFA enforced, access keys deleted, used for nothing operational.
  • Human access via IAM Identity Center (SSO) federated to the corporate directory — no long-lived IAM users for people.
  • Workloads use IAM roles, never embedded keys. Least privilege by default; permissions added on evidence, not anticipation.
# Find IAM users with active access keys (should be near-zero for humans)
aws iam list-users --query 'Users[].UserName' --output text \
  | tr '\t' '\n' \
  | while read u; do
      aws iam list-access-keys --user-name "$u" \
        --query 'AccessKeyMetadata[?Status==`Active`].AccessKeyId' --output text \
        | grep -q . && echo "ACTIVE KEY: $u"
    done

# Confirm root has no access keys
aws iam get-account-summary --query 'SummaryMap.AccountAccessKeysPresent'
Guardrails at the org level: Service Control Policies (SCPs) enforce boundaries no account can escape — denying region use outside approved ones, blocking the disabling of CloudTrail or GuardDuty, preventing public S3 where it's never allowed. See 01 · Landing Zone.

2 — Detective controls (always-on visibility)

CloudTrailOrg-wide trail, log file validation on, delivered to a locked S3 bucket in a separate account.
GuardDutyEnabled in every region — threat detection on VPC flow logs, DNS, and CloudTrail.
Security HubAggregates findings and scores against CIS / AWS Foundational standards.
AWS ConfigRecords resource state and flags drift from compliance rules.
# Verify the security services are actually on (a finding if any are off)
aws guardduty list-detectors --query 'DetectorIds' --output text
aws securityhub get-enabled-standards --query 'StandardsSubscriptions[].StandardsArn'
aws cloudtrail describe-trails --query 'trailList[].{Name:Name,Multi:IsMultiRegionTrail,Validation:LogFileValidationEnabled}'
aws configservice describe-configuration-recorders --query 'ConfigurationRecorders[].recordingGroup.allSupported'

3 — Network hardening

  • Public exposure limited to the ALB. The app tier and database live in private subnets with no route to an Internet Gateway.
  • Security groups reference each other by ID, not CIDR — the ALB's SG is the only source allowed into the app tier's 443; the app tier's SG is the only source allowed into the DB's 3306.
  • No 0.0.0.0/0 on SSH/RDP anywhere. Administrative access is via Systems Manager Session Manager — no bastion, no open management ports, full session logging.
# Hunt for the classic finding: management ports open to the world
aws ec2 describe-security-groups \
  --query "SecurityGroups[?IpPermissions[?ToPort==\`22\` && contains(IpRanges[].CidrIp, '0.0.0.0/0')]].GroupId"

# Connect to an instance with NO open SSH port, fully logged
aws ssm start-session --target i-0abc123def456
Why Session Manager over a bastion: it removes an entire class of exposure — no inbound port, no SSH keys to manage or leak, no bastion host to patch, and every session is logged to CloudTrail/S3. The most secure open port is the one that doesn't exist. See 20 · Systems Manager.

4 — Data protection

  • Encryption at rest everywhere: EBS volumes, RDS/MariaDB, and S3 with KMS — customer-managed keys where key-policy control or rotation auditing matters.
  • Encryption in transit: TLS terminated at the ALB with an ACM certificate; DB connections encrypted.
  • S3: Block Public Access on at the account level, bucket policies deny non-TLS requests, versioning + lifecycle for durability and cost.
  • Secrets in Secrets Manager with rotation — never in AMIs, user data, or environment files baked into images.
# Account-wide S3 public access block (the single highest-value S3 control)
aws s3control get-public-access-block --account-id 123456789012

# Find unencrypted EBS volumes
aws ec2 describe-volumes --query 'Volumes[?Encrypted==`false`].VolumeId'

# Enforce encryption-by-default for new EBS volumes
aws ec2 enable-ebs-encryption-by-default

5 — Application edge (WAF)

The WAF in front of the ALB runs AWS managed rule groups (Core Rule Set, SQLi, known-bad-inputs, bad-bot). False positives are handled by scoping an override with labels — never by disabling a whole rule group. New rules go in Count mode first, validated against real traffic, then promoted to Block. This is the same discipline covered in depth in the portfolio's WAF material and my Security Engineering work.

6 — Continuous verification

Hardening decays — new resources appear, someone opens a port "temporarily." The controls that keep it honest:

  • AWS Config rules flag drift the moment a non-compliant resource is created.
  • Security Hub gives a running compliance score against CIS benchmarks.
  • GuardDuty surfaces active threats, routed through EventBridge → SNS to the right team.
  • External scanning (Nuclei, QualysGuard) probes from the outside to confirm exposure matches intent.
War story tie-in: this mirrors the centralized multi-account security monitoring I built — org-wide CloudTrail, CloudWatch metric filters, EventBridge, SNS alerting and GuardDuty feeding a single operational view. Hardening you can't observe is hardening you can't trust.

Hardening checklist (quick reference)

LayerControlVerified by
IdentityRoot MFA, no root keys, SSO for humans, roles for workloadsIAM credential report
OrgSCP guardrails, region restrictionsOrganizations policy review
DetectionCloudTrail + GuardDuty + Security Hub + Config all onCLI checks above
NetworkPrivate subnets, SG-to-SG rules, no 0.0.0.0/0 mgmtSG audit + Config rule
AccessSession Manager, no bastion, no open SSHSG audit
DataKMS at rest, TLS in transit, S3 public access blockConfig rules
EdgeWAF managed rules, Count-then-Block, scoped overridesWAF logs
VerificationConfig drift, Security Hub score, external scansContinuous