Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Responds to security incidents in cloud environments (AWS, Azure, GCP) by performing identity-based containment, cloud-native log analysis, resource isolation, and forensic evidence acquisition adapted for ephemeral cloud infrastructure. Activates for requests involving cloud incident response, AWS security incident, Azure compromise, GCP breach, cloud forensics, or cloud identity compromise.
.claude/skills/conducting-cloud-incident-response/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | — | — |
| case-21 | ✓→✓ | = Same ✓ | — | — |
| case-16 | ✓→✓ | = Same ✓ | — | — |
| case-13 | ✗→✗ | = Same ✗ | — | — |
| case-12 | ✗→✗ | = Same ✗ | — | — |
Do not use for on-premises-only incidents with no cloud component; use standard enterprise IR procedures.
Identify the scope and nature of the compromise:
AWS Indicators:
CloudTrail suspicious events to investigate:
- ConsoleLogin from unexpected geolocation or IP
- CreateAccessKey for existing IAM user (persistence)
- RunInstances for crypto-mining (large instance types)
- PutBucketPolicy making S3 bucket public
- AssumeRole to cross-account roles
- DeleteTrail or StopLogging (defense evasion)
- CreateUser or AttachUserPolicy (privilege escalation)Azure Indicators:
Azure Activity Log events to investigate:
- Sign-in from anonymous IP or TOR exit node
- Service principal credential added
- Role assignment changes (Owner, Contributor added)
- VM created in unusual region
- Storage account access key regenerated
- Conditional Access policy modified or deleted
- MFA disabled for user accountGCP Indicators:
GCP Audit Log events to investigate:
- SetIamPolicy changes granting broad access
- CreateServiceAccountKey for existing SA
- InsertInstance in unexpected zone
- SetBucketIamPolicy with allUsers
- DeleteLog or UpdateSink (log tampering)Cloud containment is primarily an identity operation:
AWS Containment:
bash# Disable compromised IAM access keys aws iam update-access-key --user-name compromised-user \ --access-key-id AKIA... --status Inactive # Attach deny-all policy to compromised user aws iam attach-user-policy --user-name compromised-user \ --policy-arn arn:aws:iam::aws:policy/AWSDenyAll # Revoke all active sessions for compromised IAM role aws iam put-role-policy --role-name compromised-role \ --policy-name RevokeOlderSessions --policy-document '{ "Version":"2012-10-17", "Statement":[{ "Effect":"Deny", "Action":"*", "Resource":"*", "Condition":{"DateLessThan": {"aws:TokenIssueTime":"2025-11-15T15:00:00Z"}} }] }' # Isolate compromised EC2 instance aws ec2 modify-instance-attribute --instance-id i-0abc123 \ --groups sg-isolate-forensic
Azure Containment:
powershell# Disable compromised user Set-AzureADUser -ObjectId "user@tenant.onmicrosoft.com" -AccountEnabled $false # Revoke all sessions Revoke-AzureADUserAllRefreshToken -ObjectId "user-object-id" # Remove role assignments Remove-AzRoleAssignment -ObjectId "sp-object-id" -RoleDefinitionName "Contributor" # Isolate VM with NSG deny-all rule $nsg = New-AzNetworkSecurityGroup -Name "isolate-nsg" -ResourceGroupName "rg" -Location "eastus" $nsg | Add-AzNetworkSecurityRuleConfig -Name "DenyAll" -Priority 100 -Direction Inbound ` -Access Deny -Protocol * -SourceAddressPrefix * -SourcePortRange * ` -DestinationAddressPrefix * -DestinationPortRange *
Collect evidence before ephemeral resources are terminated or logs rotate:
AWS Evidence Collection:
Azure Evidence Collection:
GCP Evidence Collection:
Analyze logs for common cloud attack techniques:
Common Cloud Attack Patterns:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. Credential Compromise → IAM Privilege Escalation → Resource Abuse
2. Public S3/Blob → Data Exfiltration
3. SSRF from Web App → IMDS Token Theft → Lateral Movement
4. Compromised CI/CD Pipeline → Malicious Deployment
5. Cross-Account Role Abuse → Multi-Account Pivot
6. Lambda/Function Abuse → Crypto-mining or Data ProcessingIMDS Token Theft Investigation (AWS):
bash# Search CloudTrail for API calls using instance role credentials from external IP aws cloudtrail lookup-events --lookup-attributes \ AttributeKey=EventSource,AttributeValue=ec2.amazonaws.com \ --start-time 2025-11-14 --end-time 2025-11-16 \ | jq '.Events[] | select(.CloudTrailEvent | fromjson | .sourceIPAddress != "internal")'
Remove adversary access and restore secure state:
Implement controls to prevent recurrence:
| Term | Definition | |------|------------| | IMDS (Instance Metadata Service) | Cloud service providing instance credentials accessible from within a VM; SSRF attacks target IMDS to steal tokens | | CloudTrail | AWS service logging all API calls across the AWS account; primary evidence source for AWS incident response | | Service Principal | Non-human identity in Azure AD used by applications and services; compromise enables persistent API access | | SCP (Service Control Policy) | AWS Organizations policy that limits the maximum permissions available to accounts; useful for guardrails | | Ephemeral Infrastructure | Cloud resources (containers, functions, auto-scaled instances) that may be terminated before evidence can be collected | | Cross-Account Role Assumption | AWS mechanism allowing one account to temporarily access resources in another; attackers pivot through assumed roles |
Context: AWS GuardDuty alerts on API calls from an unexpected IP address using an IAM user's access key. The key was accidentally committed to a public GitHub repository 4 hours ago.
Approach:
Pitfalls:
CLOUD INCIDENT RESPONSE REPORT
================================
Incident: INC-2025-1705
Cloud Provider: AWS (Account: 123456789012)
Date Detected: 2025-11-15T14:00:00Z
Detection Source: GuardDuty - UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration
COMPROMISE SUMMARY
Initial Access: IAM access key exposed in public GitHub repo
Affected Identity: iam-user: deploy-bot (AKIA...)
Attacker IP: 203.0.113.42 (VPN exit node, Netherlands)
Duration: 4 hours (10:00 UTC - 14:00 UTC)
ATTACKER ACTIVITY (from CloudTrail)
10:15 UTC - DescribeInstances (reconnaissance)
10:18 UTC - RunInstances x 12 (c5.4xlarge, all regions - crypto-mining)
10:22 UTC - CreateUser "backup-admin" (persistence)
10:23 UTC - CreateAccessKey for "backup-admin"
10:25 UTC - AttachUserPolicy - AdministratorAccess to "backup-admin"
10:30 UTC - PutBucketPolicy - s3://data-bucket made public (exfiltration)
CONTAINMENT ACTIONS
[x] Original access key disabled
[x] User policy set to AWSDenyAll
[x] Backdoor IAM user "backup-admin" deleted
[x] 12 crypto-mining instances terminated (all regions)
[x] S3 bucket policy restored to private
FINANCIAL IMPACT
Unauthorized EC2: $2,847 (4 hours x 12 x c5.4xlarge)
Data Transfer: $127 (S3 public access data egress)
Total: $2,974
POST-INCIDENT HARDENING
1. GitHub secret scanning enabled
2. Access key rotation policy implemented
3. SCP preventing CloudTrail disablement deployed
4. GuardDuty auto-remediation Lambda configured| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-13 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-23 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of 0 percentage points is the difference between those two pass rates over the 23 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.