Install any skill in seconds. Free to start, no credit card required.
Get Started Free →AWS security engineering — threat detection (GuardDuty, Security Hub CSPM, Detective, Security Lake), incident response and containment, IAM policy evaluation and permission boundaries, infrastructure/network security (security groups, NACLs, WAF, Shield, PrivateLink), data protection and KMS encryption strategy, Secrets Manager, Macie, and multi-account governance (SCPs, Control Tower, Config, Firewall Manager). Use when designing or reviewing AWS security controls, detection/response automatio
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 200% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 135% | 0% |
| case-22 | ✗→✓ | ▲ Improved | 252% | 0% |
| case-06 | ✓→✓ | = Same ✓ | 264% | 0% |
| case-07 | ✓→✓ | = Same ✓ | 223% | 0% |
Operational playbook for AWS security work. Each section states the rule to apply: decision criteria, concrete limits, anti-patterns, and verification steps. Verify against the live account — effective permissions result from combining multiple policy types, and a single missing allow or extra deny changes the outcome. Benchmarked against AWS Security – Specialty (SCS-C03, December 2025).
> Load this skill when… designing or reviewing IAM policies, permission boundaries, SCPs, or RCPs; configuring threat detection (GuardDuty, Security Hub CSPM, Detective, Security Lake); implementing KMS encryption strategy or Secrets Manager rotation; auditing network defenses (WAF, Shield, PrivateLink, NACLs) or building IR/containment automation. > Not this skill: pipeline/IaC delivery → see aws-devops-engineer-professional; enterprise architecture trade-offs → see aws-solutions-architect-professional.
> Study resources, SCS-C02→SCS-C03 changes, and credential logistics: references/study-resources.md.
> Verify steps — use your project's MCP/automation, the AWS CLI (aws) or CloudShell, or the Console, in that order.
[volatile — verify live], GuardDuty finding type catalog (new finding families added quarterly) [volatile — verify live], IAM Access Analyzer supported resource types [volatile — verify live], RCP (Resource Control Policy) service coverage (partial list, expanding) [volatile — verify live], and any feature flagged in the blueprint: frontmatter as a recent addition.[volatile — verify live] (changes with AWS service updates) or [opinion — house style] (a defensible default, not the only valid choice).Every authorization decision passes through this stack in order. Explicit Deny at any layer is an immediate, unconditional halt.
[volatile — verify live].AssumeRole / GetFederationToken; caps the session below the role's full permissions.KMS special case: the key policy is the primary access control. Unless it explicitly delegates to IAM ("Principal": {"AWS": "arn:aws:iam::<account>:root"}), IAM policies for kms:Decrypt etc. have no effect. Always verify the key policy first when debugging KMS denials.
Permission boundaries cap but don't grant — effective permissions = intersection of identity policy and boundary. An AdministratorAccess policy on a role with a narrow boundary yields only the boundary's scope.
IAM Identity Center (SSO): recommended for human multi-account access — permission sets, automatic temporary credentials, no long-lived keys. SAML 2.0 uses AssumeRoleWithSAML; OIDC uses an OIDC provider principal with a Condition to scope subjects.
Red flags: identity-policy Allow to KMS with no key policy delegation; cross-account S3 with one side missing; boundary treated as grant; single-region analyzer; long-lived IAM user keys for humans.
| Dimension | Security Groups | NACLs | |---|---|---| | Scope | Per ENI | Per subnet | | State | Stateful (return traffic automatic) | Stateless (explicit inbound + outbound required) | | Default | Deny all inbound; allow all outbound | Allow all (default NACL) | | Rules | Allow only | Allow and deny; lowest-number evaluated first | | Best for | App-layer allow rules; SG-by-ID for dynamic scaling | Blocking IP/CIDR ranges; broad subnet blocks |
NACL stateless trap: allowing inbound TCP 443 without allowing outbound ephemeral ports (1024–65535) silently stalls connections. Reference security groups by ID (not CIDR) when instance membership changes.
[volatile — verify live]: paid; L7 DDoS detection, SRT engagement, cost protection.AmazonSSMManagedInstanceCore profile. All session activity logged to CloudTrail. Never maintain standing port-22/3389 ingress.Red flags: NACL missing outbound ephemeral ports; VPC endpoint with no endpoint policy; WAF only on ALB not CloudFront; SSH/RDP open to 0.0.0.0/0; no SSM Agent instance profile.
| Key type | Who manages material | Auto-rotation | Cross-region | Use case | |---|---|---|---|---| | AWS managed key (aws/<service>) | AWS | Yes (annual) | No | Default encryption for most services; least operational overhead | | Customer managed key (CMK) | Customer | Optional (configurable interval, min 90 days) | No (per-region) | Audit trails, key policy control, cross-service sharing | | Multi-region key | Customer | Optional | Yes (replicate into target regions) | Disaster recovery, global applications, cross-region replication | | Imported key material | Customer | No (must re-import) | No | Regulatory requirements to control key material source |
Only symmetric CMKs with AWS-generated material support automatic rotation (asymmetric and imported-material keys do not). On rotation, old backing material is retained for decryption; new material encrypts new data.
Envelope encryption: GenerateDataKey → encrypt locally with the plaintext data key → store only the ciphertext + encrypted data key → discard plaintext key. Decryption calls KMS to get the plaintext data key.
Key policy primacy: if the key policy lacks "Principal": {"AWS": "arn:aws:iam::<account-id>:root"}, no IAM policy can grant access. Every CMK needs the account root delegation statement; IAM policies can then add or restrict beyond it.
Deny with "aws:SecureTransport": "false" in the bucket policy.Governance mode can be bypassed by principals with s3:BypassGovernanceRetention; Compliance mode is irrevocable through the retention period even by root. Use Compliance for regulated retention.Secrets Manager: CMK-encrypted; auto-rotation via Lambda (VPC interface endpoints needed in private subnets). Managed rotation (AWS-provided Lambda rotators for supported services — RDS, Redshift, DocumentDB) available without custom code. Two strategies: single-user (rotates one credential, brief gap on switch) vs alternating-users (two credentials rotated alternately — zero-downtime). Rotation stages: AWSPENDING → AWSCURRENT → AWSPREVIOUS; cached-secret apps must handle the overlap window.
Macie: ML+pattern scanning for PII/credentials in S3. Continuous monitoring evaluates bucket-level controls; findings flow to Security Hub CSPM. Deploy org-wide. Run a discovery job to classify object content — continuous monitoring does not scan object data.
Red flags: CMK with no key policy root delegation; SSE-S3 where key-usage audit trail required (use SSE-KMS); S3 Block Public Access off at account level; secrets in env vars or Parameter Store when rotation required; SSE-KMS objects replicated cross-region without destination key policy.
GuardDuty analyzes CloudTrail, VPC Flow Logs, DNS, EKS audit logs, Lambda network activity, and RDS login activity — no log source setup required. Enable in every region and account; use the org delegated-administrator so member accounts cannot disable it.
Protection plans (enable per account or org-wide): S3 Protection, EKS Protection, Malware Protection (EBS scanning), RDS Protection (login anomalies), Lambda Protection (monitors Lambda network activity via VPC Flow Logs).
Severity: Low (do not auto-isolate), Medium (auto-notify + investigate), High (auto-contain), Critical (immediate escalation).
Extended Threat Detection: AttackSequence findings (e.g., AttackSequence:EC2/CompromisedInstanceGroup; other real types: AttackSequence:EKS/CompromisedCluster, AttackSequence:ECS/CompromisedCluster) correlate multi-stage signals into a compound Critical-severity finding (all AttackSequence findings are rated Critical 9.0–10.0). ETD also covers AWS-credential-misuse and S3-data-compromise scenarios, but emitted finding IDs are resource-keyed (not IAM-keyed). Treat with highest priority; review all constituent events, not just the most recent.
| Finding family | Example finding | Auto-remediation | |---|---|---| | Compromised EC2 | Recon:EC2/PortProbeUnprotectedPort | Quarantine SG + EBS snapshot + notify | | Credential exfiltration | UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS | Explicit-deny role policy + notify | | S3 data exposure | Policy:S3/BucketPublicAccessGranted | Re-enable Block Public Access | | Malware | Execution:EC2/MaliciousFile | Isolate instance + Malware Protection scan | | Multi-stage attack | AttackSequence:EC2/CompromisedInstanceGroup | Immediate escalation + IR playbook |
Naming (Oct/Dec 2025): Original findings-aggregation product → renamed Security Hub CSPM (Oct 2025). New Security Hub (GA Dec 2025) = separate risk-correlation/exposure product. They are distinct — verify which product a feature references.
Org-level CloudTrail: enable in the management account with "Apply to all accounts in my organization" — member accounts cannot disable it. Centralize logs in the Log Archive account S3 bucket.
CloudTrail Lake: SQL queries on CloudTrail events directly (no S3/Athena pipeline); retention ≤7 years; org-wide aggregation. Use alongside Athena (S3-backed, partition by account/region/date) or OpenSearch for dashboards.
Missing-logs — top causes: (1) single-region trail missing global-service events (IAM) — enable "Include global service events"; (2) S3 bucket policy blocking CloudTrail s3:PutObject; (3) SSE-KMS on the log bucket — key policy must allow CloudTrail kms:GenerateDataKey; (4) data events (S3 object-level, Lambda invoke) are off by default — must be explicitly enabled per trail.
Pipeline: GuardDuty → EventBridge (on severity) → Lambda / Step Functions / SSM Automation → containment + SNS + Security Hub CSPM update.
Red flags: GuardDuty not org-wide or member accounts can disable it; Security Hub CSPM without delegated admin; all severities routed to same auto-remediation Lambda; manual CloudTrail + Flow Log correlation instead of Detective; single-region trail missing global-service events; data events not enabled when object-level audit required.
EC2 compromise (in order): (1) Replace SGs with a forensic/quarantine SG (allow SSM endpoint only). (2) Create EBS snapshot before remediation. (3) Access via SSM Session Manager. (4) Tag {"IncidentStatus":"Quarantined","Ticket":"<ID>"}.
Credential compromise: (1) Attach explicit-deny inline IAM policy immediately. (2) Rotate or deactivate the credential. (3) CloudTrail: review GetCallerIdentity, AssumeRole, and all API calls in the exposure window. (4) Check for resources created or data exfiltrated.
SSM Automation runbooks: pre-build for EC2 isolation, credential revocation, and restore-from-backup. Use managed runbooks (AWS-IsolateEC2Instance) where available; add Approval steps for destructive actions.
Forensic accounts: VPC-endpoint-only (S3/CloudTrail/Athena), no internet egress, role-based access only.
Red flags: no pre-built runbooks; terminating instance before EBS snapshot; root credentials for IR; no org-level CloudTrail.
AdministratorAccess.[volatile — verify live]. Enforce encryption at rest or block non-TLS org-wide regardless of individual bucket policies.FullAWSAccess, add targeted Denies) is preferred over allow-list (allow-list requires enumerating every allowed action, becomes unmanageable).Red flags: SCPs at root without break-glass exceptions; Config rules per-account (use conformance packs); Firewall Manager WAF missing internet-facing ALBs; Log Archive with workload-account write access; security tooling in same OU as workloads.
Key services with brief decision rules (full service guides in references/study-resources.md):
aws:ResourceTag, aws:RequestTag); scales IAM without per-resource policy edits.[volatile — verify live].json "Principal": {"AWS": "arn:aws:iam::<SOURCE_ACCOUNT>:root"}, "Condition": {"StringEquals": {"sts:ExternalId": "<UNIQUE_EXTERNAL_ID>"}} → gate: aws iam get-role --role-name <role> --query 'Role.AssumeRolePolicyDocument' in the target account — confirm sts:ExternalId condition is present and the principal is scoped to the specific source account (not *).
* on actions or resources.→ gate: aws iam simulate-principal-policy --policy-source-arn <role-arn> --action-names s3:PutObject --resource-arns arn:aws:s3:::<bucket>/* — confirm allowed; test an action outside scope and confirm implicitDeny.
sts:AssumeRole on the target role ARN and attach it to the source principal (role or user).→ gate: aws iam get-role-policy or list-attached-role-policies on the source principal — confirm sts:AssumeRole is present for the exact target role ARN.
aws sts assume-role --role-arn <target-role-arn> --role-session-name test --external-id <UNIQUE_EXTERNAL_ID> from the source account.→ gate: command returns Credentials with AccessKeyId, SecretAccessKey, and SessionToken; without the external ID or with a wrong value it returns AccessDenied.
AccessDenied."Principal": {"AWS": "arn:aws:iam::<account-id>:root"}) so that IAM policies in the account can grant access. Add key administrators separately from key users.→ gate: aws kms describe-key --key-id <key-id> confirms KeyState: Enabled; aws kms get-key-policy --key-id <key-id> --policy-name default shows the root delegation statement.
kms:Decrypt, kms:GenerateDataKey) via either (a) the key policy directly or (b) an IAM identity policy (only works because of the root delegation in step 1).→ gate: aws kms list-key-policies --key-id <key-id> to inspect; then test with aws kms generate-data-key --key-id <key-id> --key-spec AES_256 as the intended principal — success confirms the grant chain works.
aws kms create-grant --key-id <key-id> --grantee-principal <arn> --operations Decrypt,GenerateDataKey.→ gate: aws kms list-grants --key-id <key-id> confirms the grant exists; note the GrantId for future revocation.
aws kms enable-key-rotation --key-id <key-id>.→ gate: aws kms get-key-rotation-status --key-id <key-id> returns {"KeyRotationEnabled": true}.
aws kms revoke-grant --key-id <key-id> --grant-id <grant-id>. Do NOT delete or disable the CMK while encrypted data exists — that data becomes permanently inaccessible.→ gate: aws kms list-grants --key-id <key-id> no longer shows the revoked grant ID.
UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS). Note instance ID, IAM role, and time window.→ gate: aws guardduty get-findings --detector-id <id> --finding-ids <finding-id> returns full JSON with service.action.awsApiCallAction details.
aws iam put-role-policy --role-name <role> --policy-name QuarantineExplicitDeny --policy-document '{"Statement":[{"Effect":"Deny","Action":"*","Resource":"*"}]}'.→ gate: test a call using the role's credentials — must return AccessDenied with ExplicitDeny.
→ gate: aws ec2 describe-instances --instance-ids <id> --query 'Reservations[].Instances[].SecurityGroups' shows only the forensic SG.
aws ec2 create-snapshot --volume-id <vol-id> --description "IR-<finding-id>-<date>" for all volumes.→ gate: aws ec2 describe-snapshots --snapshot-ids <snap-id> reaches completed before proceeding.
aws cloudtrail lookup-events --lookup-attributes AttributeKey=AccessKeyId,AttributeValue=<ASIA...> --start-time <incident-start> — flag CreateUser, AttachUserPolicy, PutBucketPolicy, GetObject, AssumeRole.→ gate: every eventName in the window reviewed; follow-up remediation items documented.
Scenario 1 — VPC endpoint policy missing: S3 data exfiltration via Gateway endpoint
> Situation: A financial-services team deploys a VPC Gateway Endpoint for S3 so EC2 instances in private subnets can reach S3 without traversing the internet. Two weeks after go-live, a GuardDuty finding fires: one instance is pushing data to an S3 bucket owned by an external account. The security team assumed the Gateway endpoint kept traffic "internal" and safe. No endpoint policy was configured.
> Competent move: A Gateway Endpoint with no endpoint policy defaults to Principal: *, Action: s3:*, Resource: * — any instance can reach any S3 bucket, including attacker-controlled ones. Add an endpoint policy restricting Resource to company bucket ARNs only; deny all other S3 through the endpoint.
> Tempting-but-wrong: Relying on the IAM role permissions alone. If the instance is compromised, the attacker can use the credentials outside the VPC over the internet, completely bypassing the endpoint policy. The endpoint policy is a network-layer control independent of credential scope.
> Verify: aws ec2 describe-vpc-endpoints --query 'VpcEndpoints[?ServiceName==\com.amazonaws.<region>.s3\].PolicyDocument' — confirm Resource is scoped to specific bucket ARNs; test copy to an external bucket — expect denied.
Scenario 2 — IAM Access Analyzer: organization-level vs per-region analyzers
> Situation: A security engineer creates a single organization-level IAM Access Analyzer in us-east-1 and declares the org's external-access detection posture complete. The org has workloads in us-east-1, eu-west-1, and ap-southeast-1. A week later a penetration test finds an unintended cross-account KMS key policy in ap-southeast-1 that Access Analyzer never flagged.
> Competent move: IAM Access Analyzer is region-scoped. An org-level analyzer in us-east-1 covers all org accounts but only resources in us-east-1. Create an org-level analyzer in every region with resources; automate with CloudFormation StackSets (SERVICE_MANAGED).
> Tempting-but-wrong: "Organization-level" means all accounts, not all regions. A single-region org analyzer does not cover other regions.
> Verify: aws accessanalyzer list-analyzers --region ap-southeast-1 — empty means no coverage; after deploying, confirm findings are generated for that region.
Scenario 3 — S3 Object Lock: Governance vs Compliance mode for audit logs
> Situation: A regulated financial services firm must retain trade-audit S3 logs for seven years and prevent deletion by any principal, including the account root user. A cloud engineer enables S3 Object Lock on the bucket, sets the default retention to 7 years, and selects Governance mode. The compliance officer signs off. Six months later an engineer with the s3:BypassGovernanceRetention IAM permission accidentally deletes a batch of locked objects.
> Competent move: Use Compliance mode. Compliance mode prevents any principal — including root — from deleting or shortening retention, with no bypass. Governance mode is defeatable by any principal with s3:BypassGovernanceRetention. Enable Compliance mode and remove any s3:BypassGovernanceRetention grants as defense-in-depth.
> Tempting-but-wrong: Using Governance mode and revoking s3:BypassGovernanceRetention. Revoking can be re-granted by any IAM admin — it is not immutable. Compliance mode is the only S3 mechanism that is truly irrevocable.
> Verify: aws s3api get-object-lock-configuration --bucket <bucket> — confirm Mode: COMPLIANCE; attempt delete with s3:BypassGovernanceRetention — must be denied.
Scenario 4 — Permission boundary gap blocks legitimate IAM role creation
> Situation: A security team deploys a permission boundary (DeveloperBoundary) to all developer IAM roles, intending to allow developers to create and manage their own IAM service roles for Lambda and EC2 but prevent privilege escalation. The boundary explicitly allows iam:CreateRole, iam:AttachRolePolicy, and iam:PassRole. A developer tries to create a new Lambda execution role with AmazonS3ReadOnlyAccess and gets AccessDenied — but the developer's identity policy allows all iam:* actions.
> Competent move: Effective permissions = intersection of identity policy AND boundary. Even with iam:* in the identity policy, iam:AttachRolePolicy must also appear in DeveloperBoundary — if it does not, attaching policies to new roles is denied. Fix: add the missing IAM actions to the boundary. Best practice: add a Condition on iam:CreateRole requiring the boundary (iam:PermissionsBoundary condition key) on created roles to prevent escalation chains.
> Tempting-but-wrong: Removing the permission boundary from the developer's role to fix the immediate error. This resolves the symptom but eliminates the guardrail entirely, allowing privilege escalation. The correct path is to refine the boundary to permit the specific IAM actions needed while still capping the maximum scope of any created role.
> Verify: IAM Policy Simulator for iam:AttachRolePolicy on the developer principal — identifies whether boundary or identity policy is the deny; aws iam get-role --role-name <developer-role> --query 'Role.PermissionsBoundary' confirms boundary ARN.
Further scenarios (EC2 credential exfiltration containment, Macie discovery job vs continuous monitoring): references/scenarios.md.
Read this section first. Each rule is concrete and imperative.
IAM / Policy evaluation
Detection and response
Encryption and data protection
Infrastructure
0.0.0.0/0.Governance
> Study resources — official exam guide PDF, service documentation links, and study sequencing by domain weight: references/study-resources.md.
Using this skill and hit a wall? If you find a claim contradicted by the live system or official docs, a missing rule that cost you a wrong attempt, or a decision this skill gave no criteria for — append an entry in the moment to .skill-feedback/aws-security-specialty.md at the project root (create it if absent):
date | skill last-reviewed | claim or gap | what you observed instead | evidence (error text / doc URL / query output) | suggested fix
These are harvested back into the skill via the learning loop. When the live system and this file disagree, trust the live system.
[volatile — verify live] marks, executable workflows, tool-agnostic verify steps, feedback protocol. Exam logistics relocated to references/study-resources.md.AttackSequence:IAM/CompromisedCredentials replaced with real resource-keyed types (AttackSequence:EC2/CompromisedInstanceGroup, etc.); (2) AttackSequence severity changed from "Critical/High" to Critical-only (all rated 9.0–10.0); (3) RCP supported-services list reworded as partial/expanding (volatile marker retained); (4) Lambda protection plan renamed from "Lambda Network Activity Monitoring" to "Lambda Protection"; (5) CloudHSM FIPS updated from 140-2 Level 3 to 140-3 Level 3 (current hsm2m.medium; legacy note retained)._Independent educational content for upskilling AI agents. Not affiliated with, authorized by, endorsed by, or sponsored by Amazon Web Services or any certification body. All product names and trademarks — including "AWS Certified Security – Specialty" — are the property of their respective owners and are used here for identification purposes only. Content is provided as guidance only; verify against official AWS documentation and live accounts. No certification outcome is implied or guaranteed._
Other measured skills in the registry, with their headline benchmark lift.