Skip to content

Cloud Security Operations Quick Reference

How to use this sheet

Tabbed sections cover AWS, Azure, and GCP — switch tabs per provider. Detection queries use SPL (Splunk) and KQL (Sentinel). All IPs are RFC 5737/1918. All org names are synthetic.


1. Cloud Security Services

Service Category Purpose Key Data Source
GuardDuty Threat Detection ML anomaly detection across CloudTrail, VPC Flow, DNS Findings → EventBridge → SIEM
Security Hub CSPM Aggregates findings; compliance scoring (CIS, PCI) ASFF-format findings
CloudTrail Audit Logging API call logging for all AWS services S3 + CloudWatch Logs
AWS Config Compliance Resource config tracking and rule evaluation Config snapshots + change history
Macie Data Security Sensitive data discovery in S3 (PII, PHI) Macie findings
Inspector Vuln Mgmt Automated scanning for EC2, Lambda, ECR CVE-based findings
IAM Access Analyzer Identity Identifies resources shared with external entities Access Analyzer findings
Service Category Purpose Key Data Source
Microsoft Sentinel SIEM/SOAR Cloud-native SIEM with KQL analytics and playbooks Log Analytics workspace
Defender for Cloud CSPM/CWPP Posture management + workload protection Secure Score, recommendations
Entra ID Protection Identity Risk-based sign-in and user risk detection Sign-in logs, risk events
Purview Data Security Data classification, DLP, information protection Purview audit, DLP alerts
Azure Monitor Observability Platform metrics, activity logs, diagnostics Activity Log, Diagnostics
Service Category Purpose Key Data Source
Chronicle SIEM SIEM Petabyte-scale analytics (YARA-L rules) UDM events
Security Command Center CSPM Asset inventory, vulnerability and threat findings SCC findings (Premium)
Cloud Audit Logs Audit Logging Admin Activity, Data Access, System Event logs Cloud Logging → Log sink
BeyondCorp Enterprise Zero Trust Context-aware access for apps and infrastructure Access logs, device signals
Cloud Armor App Security DDoS protection and WAF for load balancers Cloud Armor logs

2. AWS Detection Queries

Impossible Travel Detection

index=cloudtrail eventName=ConsoleLogin
| iplocation sourceIPAddress
| sort 0 userIdentity.arn, _time
| streamstats current=f last(lat) as prev_lat last(lon) as prev_lon
  last(_time) as prev_time last(City) as prev_city by userIdentity.arn
| eval distance_km=3959*2*asin(sqrt(pow(sin((lat-prev_lat)*3.14159/360),2)
  +cos(lat*3.14159/180)*cos(prev_lat*3.14159/180)
  *pow(sin((lon-prev_lon)*3.14159/360),2)))
| eval time_diff_hrs=(_time-prev_time)/3600
| eval speed_kmh=if(time_diff_hrs>0, distance_km/time_diff_hrs, 0)
| where speed_kmh > 900 AND distance_km > 500
| table _time, userIdentity.arn, prev_city, City, distance_km, speed_kmh
AWSCloudTrail
| where EventName == "ConsoleLogin"
| extend UserArn = tostring(UserIdentityArn)
| extend Lat = toreal(geo_info_from_ip_address(SourceIpAddress).latitude)
| extend Lon = toreal(geo_info_from_ip_address(SourceIpAddress).longitude)
| sort by UserArn asc, TimeGenerated asc
| serialize
| extend PrevLat = prev(Lat), PrevLon = prev(Lon),
         PrevTime = prev(TimeGenerated), PrevUser = prev(UserArn)
| where UserArn == PrevUser
| extend DistKm = geo_distance_2points(Lon, Lat, PrevLon, PrevLat) / 1000
| extend TimeDiffHrs = datetime_diff('second', TimeGenerated, PrevTime) / 3600.0
| extend SpeedKmh = iff(TimeDiffHrs > 0, DistKm / TimeDiffHrs, 0.0)
| where SpeedKmh > 900 and DistKm > 500

Privilege Escalation — IAM Policy Attach Sequence

index=cloudtrail (eventName=CreatePolicy OR eventName=AttachUserPolicy
  OR eventName=AttachRolePolicy OR eventName=PutUserPolicy)
| eval actor=mvindex(split('userIdentity.arn',"/"),1)
| stats earliest(_time) as first latest(_time) as last
  values(eventName) as actions dc(eventName) as action_count
  by actor, sourceIPAddress
| where action_count >= 2 AND match(actions,"CreatePolicy")
  AND match(actions,"Attach")
| eval window_min=round((last-first)/60,1)
| where window_min <= 10
AWSCloudTrail
| where EventName in ("CreatePolicy","AttachUserPolicy",
  "AttachRolePolicy","PutUserPolicy")
| extend Actor = tostring(split(UserIdentityArn, "/")[1])
| summarize First=min(TimeGenerated), Last=max(TimeGenerated),
  Actions=make_set(EventName), ActionCount=dcount(EventName)
  by Actor, SourceIpAddress
| where ActionCount >= 2 and Actions has "CreatePolicy"
  and Actions has_any ("AttachUserPolicy","AttachRolePolicy")
| extend WindowMin = datetime_diff('minute', Last, First)
| where WindowMin <= 10

S3 Data Exfiltration — High Volume GetObject

index=cloudtrail eventName=GetObject
| eval bucket='requestParameters.bucketName'
| where 'userIdentity.accountId' != 'recipientAccountId'
| stats count as gets dc(requestParameters.key) as unique_objects
  sum(additionalEventData.bytesTransferredOut) as bytes_out
  by userIdentity.arn, bucket, sourceIPAddress
| where gets > 100 OR bytes_out > 1073741824
| eval gb_out=round(bytes_out/1073741824,2)
| sort - bytes_out
AWSCloudTrail
| where EventName == "GetObject"
| extend Bucket = tostring(parse_json(RequestParameters).bucketName)
| where UserIdentityAccountId != RecipientAccountId
| summarize Gets=count(),
  UniqueObj=dcount(tostring(parse_json(RequestParameters).key)),
  BytesOut=sum(tolong(parse_json(AdditionalEventData).bytesTransferredOut))
  by UserIdentityArn, Bucket, SourceIpAddress
| where Gets > 100 or BytesOut > 1073741824
| extend GBOut = round(BytesOut / 1073741824.0, 2)

Root Account Usage

index=cloudtrail userIdentity.type=Root eventType=AwsApiCall
| stats count by eventName, sourceIPAddress, awsRegion, eventTime
| sort - count
AWSCloudTrail
| where UserIdentityType == "Root" and EventTypeName == "AwsApiCall"
| summarize Count=count() by EventName, SourceIpAddress, AWSRegion
| sort by Count desc

Root Account Usage

Root usage should be near-zero. Any ConsoleLogin by root without a change request is Critical. Ensure root has hardware MFA and no access keys.

Unauthorized API Calls & Security Group Changes

// --- Unauthorized API calls ---
index=cloudtrail errorCode IN ("AccessDenied","UnauthorizedAccess")
| stats count as denied dc(eventName) as unique_apis
  values(eventName) as apis by userIdentity.arn, sourceIPAddress
| where denied > 10

// --- Security group opened to 0.0.0.0/0 ---
index=cloudtrail eventName IN ("AuthorizeSecurityGroupIngress",
  "AuthorizeSecurityGroupEgress")
| eval rule='requestParameters.ipPermissions.items{}.ipRanges.items{}.cidrIp'
| where match(rule,"0\\.0\\.0\\.0/0") OR match(rule,"::/0")
| table _time, userIdentity.arn, eventName, requestParameters.groupId
// Unauthorized API calls
AWSCloudTrail
| where ErrorCode in ("AccessDenied","UnauthorizedAccess")
| summarize Denied=count(), APIs=make_set(EventName,20)
  by UserIdentityArn, SourceIpAddress
| where Denied > 10

// Security group opened to the internet
AWSCloudTrail
| where EventName in ("AuthorizeSecurityGroupIngress",
  "AuthorizeSecurityGroupEgress")
| where RequestParameters has "0.0.0.0/0" or RequestParameters has "::/0"
| project TimeGenerated, UserIdentityArn, EventName, RequestParameters

3. AWS Common Misconfigurations

Misconfiguration Risk AWS Config Rule Remediation
Public S3 bucket Critical s3-bucket-public-read-prohibited Enable account-level Block Public Access
No MFA on root Critical root-account-mfa-enabled Enable hardware MFA on root
Root has access keys Critical iam-root-access-key-check Delete root access keys
IAM policy with *:* High iam-policy-no-statements-with-admin-access Apply least-privilege policies
SG allows 0.0.0.0/0 on SSH/RDP High restricted-ssh Restrict to known CIDRs
CloudTrail not in all regions High cloud-trail-enabled Enable org-level multi-region trail
Unencrypted EBS volumes Medium encrypted-volumes Enable default EBS encryption
No VPC Flow Logs Medium vpc-flow-logs-enabled Enable for all VPCs

4. Azure Detection Queries (KQL)

Entra Sign-In Risk & Conditional Access Bypass

// High-risk sign-ins (requires Entra ID P2)
SigninLogs
| where RiskLevelDuringSignIn in ("high","medium")
| where RiskState != "remediated"
| project TimeGenerated, UserPrincipalName, RiskLevelDuringSignIn,
    IPAddress, AppDisplayName, ResultType,
    City=tostring(parse_json(LocationDetails).city),
    Country=tostring(parse_json(LocationDetails).countryOrRegion)

// Conditional Access bypass attempts
SigninLogs
| where ConditionalAccessStatus == "failure"
| mv-expand Policy = parse_json(ConditionalAccessPolicies)
| where tostring(Policy.result) == "failure"
| summarize Attempts=count(),
    Policies=make_set(tostring(Policy.displayName),10)
  by UserPrincipalName, AppDisplayName, bin(TimeGenerated,1h)
| where Attempts > 3

Privileged Role Assignments & Mass Deletions

// Privileged role assignments
AuditLogs
| where OperationName has "Add member to role"
| extend Target = tostring(TargetResources[0].userPrincipalName)
| extend Role = tostring(parse_json(
    tostring(TargetResources[0].modifiedProperties))[1].newValue)
| where Role has_any ("Global Administrator","Privileged Role Administrator",
    "Security Administrator","User Access Administrator")
| extend Actor = tostring(InitiatedBy.user.userPrincipalName)
| project TimeGenerated, Actor, Target, Role

// Anomalous mass resource deletion
AzureActivity
| where OperationNameValue has "DELETE" and ActivityStatusValue == "Success"
| summarize Deletes=count(), Resources=make_set(Resource,25)
  by Caller, CallerIpAddress, bin(TimeGenerated,1h)
| where Deletes > 5

5. Azure Common Misconfigurations

Misconfiguration Risk Remediation
No Conditional Access policies Critical Implement baseline CA (require MFA, block legacy auth)
Overprivileged managed identities High Scope to specific resources with minimal roles
Storage allows public blob access High Disable public access at account level
NSG allows RDP/SSH from Any High Restrict to bastion or specific CIDRs
No diagnostic logging on Key Vault High Enable audit logs to Log Analytics
Activity Log not exported to SIEM Medium Configure diagnostic settings to workspace / Event Hub

6. GCP Detection & Security

Detection Pipeline

Cloud Audit Logs → Log Sink → BigQuery / Chronicle
                     Scheduled Query / YARA-L Rule → Pub/Sub → SOAR

Suspicious IAM Binding (BigQuery)

SELECT timestamp,
  protopayload_auditlog.authenticationInfo.principalEmail AS actor,
  protopayload_auditlog.methodName AS method,
  JSON_EXTRACT_SCALAR(binding, '$.role') AS role_granted
FROM `acme-secops-prod.audit_logs.cloudaudit_googleapis_com_activity_*`,
  UNNEST(JSON_EXTRACT_ARRAY(
    protopayload_auditlog.servicedata_v1_iam_admin.permissionDelta)) AS binding
WHERE protopayload_auditlog.methodName LIKE '%SetIamPolicy%'
  AND (JSON_EXTRACT_SCALAR(binding,'$.role') LIKE '%roles/owner%'
    OR JSON_EXTRACT_SCALAR(binding,'$.members') LIKE '%allUsers%')
  AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 24 HOUR)

Service Account Key Creation (Chronicle YARA-L)

rule service_account_key_created {
  meta:
    author = "acme-secops"
    severity = "HIGH"
    mitre_attack = "T1098.001"
  events:
    $e.metadata.event_type = "USER_RESOURCE_CREATION"
    $e.metadata.product_name = "Google Cloud IAM"
    $e.target.resource.type = "SERVICE_ACCOUNT_KEY"
  condition:
    $e
}

GCP Common Misconfigurations

Misconfiguration Risk Remediation
Public GCS bucket Critical Remove allUsers / allAuthenticatedUsers bindings
Default service account in production High Create dedicated SAs with minimal permissions
Overly permissive IAM (roles/owner) High Use predefined roles; apply least privilege
Data Access audit logs not enabled High Enable for sensitive services
VPC firewall allows 0.0.0.0/0 ingress High Restrict source ranges and ports
Unrestricted API keys Medium Restrict by API and referrer/IP

7. Multi-Cloud Comparison

CSPM Coverage

Capability AWS Security Hub Defender for Cloud GCP SCC 3rd Party (Wiz/Prisma)
Asset Inventory Partial (Config) Yes (Resource Graph) Yes Unified cross-cloud
Misconfig Detection CIS/PCI rules Secure Score Health Analytics Custom policies
Vuln Scanning Inspector Defender for Servers Web Security Scanner Agentless + agent
Identity Risk IAM Access Analyzer Entra Permissions Mgmt IAM Recommender CIEM
Container Security Inspector for ECR Defender for Containers GKE Security Posture Full lifecycle
Cross-Cloud AWS only Azure + limited AWS/GCP GCP only Full multi-cloud

Shared Responsibility Model

Layer IaaS (Customer) PaaS (Shared) SaaS (Provider)
Data classification & protection Customer Customer Customer
Identity & access management Customer Customer Customer (user-level)
Application security Customer Shared Provider
Network controls Customer Shared Provider
OS patching Customer Provider Provider
Physical infrastructure Provider Provider Provider

The Customer Always Owns

Regardless of IaaS/PaaS/SaaS, the customer is always responsible for: data classification, user access management, regulatory compliance, and business continuity planning.


8. Crown Jewel Identification

# Question Examples Risk If Compromised
1 Data stores with PII/PHI/financial? S3, RDS, BigQuery Regulatory fines, breach notification
2 Principals with cross-account/admin access? Root, break-glass roles, CI/CD SAs Full environment takeover
3 Where are secrets and encryption keys? KMS, Key Vault, Secrets Manager Data exposure, lateral movement
4 Internet-facing entry points? ALBs, API Gateways, CDNs Initial access vector
5 CI/CD pipelines deploying to prod? CodePipeline, GitHub Actions, Cloud Build Supply chain compromise
6 Logging systems that would blind you if disabled? CloudTrail, Sentinel, Chronicle Detection evasion

9. Cloud Incident Response

 PRESERVE ──▶ CONTAIN ──▶ ERADICATE ──▶ RECOVER

Preserve

Action AWS Azure GCP
Snapshot instances aws ec2 create-snapshot az snapshot create gcloud compute disks snapshot
Preserve audit logs Copy trail bucket; enable Object Lock Export Activity Log to immutable storage Export to locked GCS bucket
Capture IAM state get-account-authorization-details az role assignment list gcloud projects get-iam-policy

Contain

Action AWS Azure GCP
Network isolation Apply deny-all SG Apply deny-all NSG Deny-all firewall rule (priority 0)
Revoke credentials delete-access-key + inline deny policy revoke-refresh-tokens service-accounts keys delete
Block malicious IPs WAF IP set / NACL NSG deny / Azure Firewall Cloud Armor deny rule

Eradicate & Recover

Phase Actions
Eradicate Remove rogue IAM entities; delete persistence (Lambda backdoors, event rules); rotate all affected credentials; patch exploited vulns
Recover Restore from known-good backups; rebuild compromised instances from hardened images; re-enable services incrementally with monitoring; validate detection coverage; conduct post-incident review

10. Cross-Cloud Identity Federation Risks

Risk Detection Mitigation
Overly broad trust policy Review sts:AssumeRole trust policies; IAM Access Analyzer Restrict to specific ARNs with sts:ExternalId
Stale federation configs Audit OIDC/SAML providers quarterly Remove unused identity providers
Token replay across clouds Correlate cross-cloud identity events Short-lived tokens; enforce audience restrictions
Workload identity escalation Review IAM bindings for workload identities Least privilege; Workload Identity Federation conditions
IdP compromise propagation Monitor IdP audit logs for admin changes Phishing-resistant MFA on IdP admins; out-of-band recovery

11. Cloud ATT&CK Techniques

Technique ID Name Tactic Example Attack Detection Signal
T1078.004 Cloud Accounts Initial Access Compromised creds from anomalous location Impossible travel on ConsoleLogin
T1190 Exploit Public-Facing App Initial Access Exploiting vuln web app on EC2/VM WAF alerts, unexpected child process
T1098.001 Additional Cloud Credentials Persistence Creating new access keys for IAM user CreateAccessKey events
T1098.003 Additional Cloud Roles Persistence Attaching admin policy to compromised user AttachUserPolicy audit events
T1136.003 Cloud Account Persistence Creating rogue IAM user or service account CreateUser, iam.serviceAccounts.create
T1578.002 Create Cloud Instance Defense Evasion Launching instance in unused region (cryptomining) RunInstances in atypical region
T1562.008 Disable Cloud Logs Defense Evasion Stopping CloudTrail or deleting log sinks StopLogging, DeleteTrail
T1530 Data from Cloud Storage Collection Downloading sensitive S3/Blob/GCS data High-volume GetObject, unusual principal
T1537 Transfer to Cloud Account Exfiltration Copying bucket to attacker-controlled account Cross-account CopyObject
T1496 Resource Hijacking Impact Cryptomining on compromised compute Unusual instance types, high CPU spike
T1580 Cloud Infrastructure Discovery Discovery Enumerating resources after initial access Spike in Describe* / List* API calls
T1525 Implant Internal Image Persistence Backdooring AMI/VM image in auto-scaling Image creation by unusual principal
T1610 Deploy Container Execution Deploying malicious container in EKS/AKS/GKE Unexpected image, public registry pull

Cloud ATT&CK Matrix

MITRE maintains a dedicated Cloud Matrix covering IaaS, SaaS, and identity provider techniques. Map detection rules to these IDs for coverage tracking.


12. Key Metrics & Benchmarks

Metric Target Source
CloudTrail coverage 100% of accounts and regions Org-level trail status
GuardDuty finding SLA Critical < 15 min, High < 1 hr Finding timestamp → analyst ack
CSPM compliance score > 85% across all accounts Security Hub / Secure Score / SCC
IAM access review cadence Quarterly (privileged), semi-annual (standard) Access Analyzer / Entra Reviews
Secrets rotation 90 days (access keys), 365 days (KMS) Secrets Manager / Key Vault config
Time to revoke compromised cred < 30 minutes IR playbook timestamps
Cloud ATT&CK rule coverage > 60% of Cloud Matrix techniques Navigator layer vs. SIEM rules

13. Quick CLI Reference

# List IAM users with console access but no MFA
aws iam generate-credential-report && sleep 5
aws iam get-credential-report --query 'Content' --output text | \
  base64 -d | awk -F',' '$4=="true" && $8=="false" {print $1}'

# Check CloudTrail status across all regions
for region in $(aws ec2 describe-regions --query 'Regions[].RegionName' \
  --output text); do
  aws cloudtrail describe-trails --region "$region" \
    --query 'trailList[].{Name:Name,Multi:IsMultiRegionTrail}'
done

# Revoke all sessions for IAM user (emergency)
aws iam put-user-policy --user-name compromised-user \
  --policy-name DenyAll --policy-document \
  '{"Version":"2012-10-17","Statement":[{"Effect":"Deny","Action":"*","Resource":"*"}]}'
# Storage accounts with public blob access
az storage account list --query \
  "[?allowBlobPublicAccess==true].{Name:name,RG:resourceGroup}" -o table

# Defender for Cloud secure score
az security secure-scores list --query \
  "[].{Name:displayName,Score:currentScore,Max:maxScore}" -o table

# Revoke user sessions (emergency)
az ad user show --id compromised@acme-corp.example.com --query id -o tsv | \
  xargs -I {} az rest --method POST \
  --url "https://graph.microsoft.com/v1.0/users/{}/revokeSignInSessions"
# List public GCS buckets
for bucket in $(gsutil ls); do
  gsutil iam get "$bucket" 2>/dev/null | \
    grep -q "allUsers\|allAuthenticatedUsers" && echo "PUBLIC: $bucket"
done

# Firewall rules allowing 0.0.0.0/0
gcloud compute firewall-rules list \
  --filter="sourceRanges=('0.0.0.0/0') AND direction=INGRESS" \
  --format='table(name,network,allowed,sourceRanges)'

# Disable compromised service account (emergency)
gcloud iam service-accounts disable \
  compromised-sa@acme-secops-prod.iam.gserviceaccount.com

Related References

See the MITRE ATT&CK Cheat Sheet for endpoint-focused technique coverage and the SOC Metrics Cheat Sheet for operational KPIs.