The Ops Atlas xOps School

Security & Compliance Emerging practice Sources verified

CloudSecOps

CloudSecOps is running security for a cloud estate at the provider-API layer: guardrails that block unsafe configuration, continuous posture checks, complete audit logs, and detection and response for control-plane activity. The label is emerging and loosely defined.

Key takeaways

  • CloudSecOps is an emerging trade-press label (Dave Shackleford called it an 'emerging buzzword' in TechTarget SearchSecurity in 2022) that no standards body defines. This page centres it on the provider control plane, which is an editorial distinction.
  • Configurations, identities and data stay with the customer in every service model, so even fully managed services leave you control-plane security work.
  • Use preventive, detective and responsive guardrails together, and learn each one's preconditions: AWS SCPs and RCPs do not apply to the management account or to service-linked roles.
  • Logs you did not collect before an incident cannot be recovered after it. AWS data events and Google Data Access logs are off by default; Entra ID keeps sign-in logs for 7 days (Free) or 30 days (P1/P2).
  • A posture score is a ratio of passed controls, and suppressing failed findings raises it. Track exposure dwell time with the age of open findings, exception debt and logging coverage instead.
  • Tool support lags benchmarks: in October 2026 CIS publishes AWS Foundations 7.1.0, while AWS Security Hub CSPM supports versions up to 5.0.0.

CloudSecOps (cloud security operations) is the continuous work of keeping a cloud estate secure through the provider’s own control plane: guardrails that stop unsafe configuration before it exists, posture checks that find drift, audit logs that record every administrative action, and detection and response for suspicious control-plane activity.

For cloud security and platform engineers, security architects, SOC leads, and leaders who decide what to enforce. Facts last checked 2026-10-17.

Item Summary
Term status Emerging. In use in trade press by 2022; the practices are documented by providers, CIS, CSA, NSA/CISA and MITRE.
Goals Unsafe configurations blocked or found quickly; every administrative action logged where attackers cannot erase it; control-plane threats detected and contained.
In scope Shared responsibility for security controls, security guardrails and drift, CSPM/CWPP/CNAPP, cloud IAM misconfigurations, keys, audit logging, public storage, CIS cloud benchmarks, cloud detection and response basics.
Out of scope See What CloudSecOps is not.
Prerequisites CloudOps (hierarchy, accounts, Regions); basic IAM; one provider’s CLI.
Key outputs A versioned security guardrail set with exceptions, an organisation-wide audit log archive, a triaged posture backlog with owners, tested control-plane detections and runbooks.

In the cloud, a bucket becomes public, a key is created or a log is switched off with one API call by anyone holding the right permission, including an attacker holding someone else’s. Three patterns recur:

  • Configuration. The Cloud Security Alliance’s 2024 Top Threats ranking, built from a poll of more than 500 industry experts, put misconfiguration and inadequate change control first and identity and access management second.[4] It is an expert ranking, not incident data.
  • Credentials. Mandiant traced every incident it handled in the 2024 Snowflake customer campaign “back to compromised customer credentials”, on accounts without multi-factor authentication.[5]
  • Missing logs. In the 2023 Exchange Online intrusion reviewed by the US Cyber Safety Review Board, one victim agency “could not view past activity as these logs only captured data from the time that Microsoft enabled the advanced logging”.[6]
Operating reality Without CloudSecOps With CloudSecOps
A risky setting (public bucket, open admin port) Found by an outsider Blocked, or found and assigned within hours
Audit logs A 90-day built-in history, plus account-level trails or exports that account admins can stop or delete An organisation trail or export into an account workload admins cannot change
A suspicious API call Nobody is looking A tested detection pages an on-call engineer with a runbook
Exceptions Permanent, undocumented Owner, reason, expiry date, review
  • Not SecOps with a cloud connector. In this Atlas, SecOps is the collaboration hub between security and IT operations and governs hardening baselines; SOC Ops runs triage. CloudSecOps supplies them with cloud-specific controls, telemetry and runbooks.
  • Not DevSecOps. DevSecOps catches misconfigurations in the pull request; CloudSecOps owns the deployed state, including changes made outside the pipeline.
  • Not CloudOps. CloudOps owns the account structure, operational guardrails (Regions, tags, budgets) and teaches the shared responsibility model; CloudSecOps decides which security guardrails to enforce and watches them drift.
  • Not identity engineering. How policies are written and evaluated → IAMOps; accounts and SSO → IdentityOps; just-in-time elevation → AccessOps.
  • Not a product, not compliance. A posture tool gives findings, not owners or fixes; audit programmes belong to ComplianceOps, and CloudSecOps produces their evidence.

Where CloudSecOps comes from and where it sits

Link to section “Where CloudSecOps comes from and where it sits”

No founding document exists. These dated milestones can be verified:

Date Milestone What it shows
2021 A Wiz-authored post on the CSA blog says Gartner coined “CNAPP”[7] Posture and workload tools start to converge
2022 TechTarget SearchSecurity and Data Center Knowledge articles use “CloudSecOps”[1][2] The label is in use, with different emphases
2024 CISA and NSA cloud information sheets (March);[8] the Snowflake customer campaign (June);[5] CSRB calls for free default audit logging;[6] CISA BOD 25-01 (December)[9] Credentials and logging become policy topics
2026 Google closes its Wiz acquisition (March);[10] MITRE ATT&CK v20 regroups cloud log tampering under a new technique ID[11] Tools consolidate; vocabulary still moves
Term Meaning on this page
Control plane / data plane Management operations that create, change and delete resources, versus operations inside a resource. Azure’s activity log records the first; its resource logs record the second.[12]
Posture The security-relevant configuration of the estate at a point in time, measured against a baseline.
Guardrail A control that runs continuously in the background;[1] this page distinguishes preventive (blocks the call), detective (reports drift) and responsive (alerts or remediates).
SCP / RCP AWS organisation policies that cap what principals (SCP) or resources (RCP) can do. Neither grants permissions; effective permissions are the intersection with identity and resource policies.[13][14]
OU, service-linked role An organisational unit groups AWS accounts so that one attached policy covers them all. A service-linked role is predefined by an AWS service and used on your behalf; SCPs and RCPs do not restrict it.[13]
IMDSv2 The session-oriented version of the EC2 instance metadata service, which AWS links to defence in depth against SSRF (see Use case 1).[15]
Data perimeter AWS: “a set of preventive controls you can use to help ensure that only your trusted identities access your trusted resources from expected networks”.[16]
CSPM, CWPP, CNAPP Posture management, workload protection, and the platform that combines them. Microsoft describes Defender for Cloud as a CNAPP with CSPM, DevSecOps and CWPP components.[17]

The mental model: four questions at the API. Every cloud action is an authenticated API call. CloudSecOps keeps four answers current: who can call (the identity perimeter), what they may configure (preventive guardrails), what the estate looks like now (posture), and what happened (logs and detections). A perfect posture score says nothing about an attacker using valid keys. This model is this Atlas’s teaching device, not an industry framework.

Page Shared ground CloudSecOps focus Their focus
CloudOps Organisation policies Security guardrails, posture, CIS benchmarks Hierarchy, Regions, tags, budgets, quotas
IAMOps SCPs, Azure Policy Which guardrails to enforce and their drift Writing and evaluating policy language
DevSecOps IaC findings Deployed state and out-of-band change The pull request and pipeline
KubernetesSecOps Workload identity Cloud accounts Admission and runtime in clusters
SecOps, SOC Ops Alerts, baselines Cloud context, telemetry and runbooks Coordination; 24×7 triage
DetectionOps, SecDataOps Cloud logs Which logs exist and where Detection logic; telemetry pipelines
ComplianceOps Benchmarks Producing evidence Audit programmes
VulnerabilityOps Findings Configuration findings Software vulnerabilities and patch priority

This charter is this Atlas’s proposal; no official CloudSecOps manifesto exists.

Mission: make unsafe cloud configuration hard to create, quick to find and hard to hide.

  1. Prevent centrally what must never happen; detect the rest. Organisation-level denies for a short list of catastrophic actions, detective checks for everything that has legitimate exceptions.
  2. Every guardrail has an owner, a test, an exception path and a measurement. A rule without an exception path creates shadow accounts.
  3. Collect logs before you need them, where workload administrators cannot change them.
  4. Identity is the perimeter. Long-lived keys are debt with interest; federated, short-lived credentials are the default.
  5. Know each control’s preconditions. Name the accounts, Regions and principals a control does not cover.
  6. Fix in code. The next deployment reverts a console fix; remediate in the infrastructure as code (InfraOps).

Non-goals: writing application code, running the SOC, designing permission models for each workload.

Fundamentals: shared responsibility applied to controls

Link to section “Fundamentals: shared responsibility applied to controls”

CloudOps teaches the shared responsibility model; this table applies Microsoft’s matrix to security controls.[18]

Control area IaaS PaaS and serverless SaaS
Identities, access, configuration settings, data Customer Customer Customer
Network controls Customer Shared Provider
Operating system and patching Customer Provider Provider

The building blocks follow the four questions: an identity perimeter of federated, short-lived credentials (designed in IAMOps and IdentityOps); preventive guardrails such as AWS SCPs, RCPs and declarative policies, Azure Policy deny and Google Organization Policy constraints;[13][14][19][20][21] detective posture, including analysis of resources shared outside a “zone of trust”;[22] and audit logs with detections. Keys and encryption cut across all four.

Defaults decide where the work starts (as of October 2026):

Log AWS Azure Google Cloud
Control-plane audit log Event history keeps 90 days of management events; a trail stores more[23] Activity log kept 90 days; export with a diagnostic setting[12] Admin Activity logs “always written”; cannot be disabled[24]
Data-plane audit log Data events off by default, charged extra[25] Resource logs need a diagnostic setting[12] Data Access logs off by default except BigQuery[24]
Identity sign-ins and directory changes Console sign-ins are CloudTrail events[26] Entra ID sign-in and audit logs kept 7 days (Free) or 30 days (P1/P2); route them out with Azure Monitor[27] Cloud Identity and Workspace login logs reach Cloud Logging only once you enable sharing[28]

If identity is the perimeter, the identity row matters most, and Entra retention is not retroactive: after an upgrade from Free, “only data still within the free retention period (up to seven days) is available”.[27]

Two other defaults matter. On AWS, instances accept both IMDSv1 and IMDSv2 unless a newer default requires IMDSv2.[15][29] On Google Cloud, organisations created on or after 3 May 2024 start with baseline constraints such as disabled service-account key creation and uniform bucket-level access; older organisations may not have them.[30]

Most services encrypt at rest by default, so the work is deciding who controls each key and who may use it. AWS owned keys cost nothing, but “you cannot change their policies, you cannot audit activities on these keys, and you cannot delete them”; customer managed keys give “full control over the lifecycle and usage” for a monthly fee.[31] Azure and Google Cloud call these customer-managed keys (CMK, CMEK). Pay for one when you must see every use in your own logs, decide who may use it, or make data unreadable by disabling it. Three controls then matter more than rotation:

  • Separate administering from using. AWS’s default key policy lets key administrators manage a key but not use it; because they can edit the policy, they “can give themselves and others” more access, so treat key administration as privileged.[32]
  • Guard deletion. Deleting a KMS key “is destructive and potentially dangerous”: the data it protects “becomes unrecoverable”, so each provider adds a delay. AWS KMS waits 7–30 days (default 30);[33] AWS’s sample SCPs reserve kms:ScheduleKeyDeletion for a privileged role or forbid waiting periods under 30 days.[34] Azure Key Vault keeps deleted keys recoverable for 7–90 days; add purge protection, which services such as Azure Storage require.[35] Cloud KMS waits 30 days by default, and an organisation policy can enforce a minimum.[36]
  • Keep key-use logs. CloudTrail logs all AWS KMS actions by default, but a trail can exclude them all to cut volume;[37] never exclude them from the trail covering accounts that hold sensitive data.

Secrets belong in the provider’s secret store (AWS Secrets Manager, Azure Key Vault, Google Secret Manager), never in code or instance user data; how pipelines fetch them belongs to DevSecOps.

Microsoft’s Cloud Adoption Framework describes posture management as “the operational security team that focuses on security enablement for technical operations teams”.[38] The RACI below is this Atlas’s proposal (R = responsible, A = accountable, C = consulted, I = informed).

Activity Cloud security Cloud platform Workload team SOC Risk owner / GRC
Choose the security guardrail set and baseline A/R C C I C
Deploy organisation policies through the pipeline A R I I I
Organisation audit log, archive account, retention A/R R I C C
Triage and route posture findings A/R C I I I
Fix a misconfiguration in a workload C C A/R I I
Approve an exception R C R (requests) I A
Cloud detection use cases and runbooks A/R C I R I
Contain a cloud incident R R C A I

Skills: IAM evaluation logic, policy as code, logging architecture, audit-log queries, incident handling. Small organisations combine these roles (see When to use).

  • Day 0, design. Pick a baseline (a CIS Foundations benchmark or the provider’s), list the few actions to deny everywhere, design the log archive and its retention, decide the exception process.
  • Day 1, roll out. Turn on organisation-wide logging and posture scanning first, then trial guardrails, then enforce OU by OU. Azure’s DoNotEnforce mode exists “when you want to evaluate the policy assignment before enforcement”,[39] and Google supports dry-run organisation policies.[21] AWS SCPs and RCPs have no documented evaluate-only mode, so on AWS the trial is a test OU and a review of its access-denied events.[13]
  • Day 2, run. The cadences below.
Cadence Activity Output
Continuous Guardrail enforcement, posture scans, control-plane detections Denied calls, findings, alerts
Daily Triage of new critical findings Owner and due date on each
Weekly Exception and overdue-finding review Renewed, closed or escalated exceptions
Monthly Guardrail and benchmark review Changes to the guardrail set, staged by OU
Quarterly Game day and metrics review (scorecard in Templates) Tested detections, trend report to leadership

Release guardrails like software, from a test OU to ever broader OUs; CloudOps teaches that staged rollout.[34] Exceptions use the exception request, capped at 90 days (this page’s suggestion).

Reference architecture: guardrail and evidence layers

Link to section “Reference architecture: guardrail and evidence layers”

CloudOps shows the landing zone; this view adds the security layers in AWS terms, and the table after it gives the Azure and Google Cloud counterparts.

Figure 1. Security layers in a multi-account cloud estate
attachesorganisation trailfindingsmisconfigurationthreatManagement account: noworkloads, outside SCPs andRCPsOrganisation policies: SCP,RCP, declarativeMember accounts: workloadsand sandboxesLog archive accountSecurity tooling accountQuery store or SIEMTriage queueWorkload owner: fix in IaCSOC: incident
Diagram source (Mermaid)
flowchart TB
  MGMT["Management account: no workloads, outside SCPs and RCPs"] -->|"attaches"| POL
  POL["Organisation policies: SCP, RCP, declarative"]
  POL --> MEM["Member accounts: workloads and sandboxes"]
  MEM -->|"organisation trail"| LOG["Log archive account"]
  MEM -->|"findings"| SEC["Security tooling account"]
  LOG --> SIEM["Query store or SIEM"]
  SEC --> TRI["Triage queue"]
  TRI -->|"misconfiguration"| OWN["Workload owner: fix in IaC"]
  TRI -->|"threat"| SOC["SOC: incident"]
  classDef core fill:#e8f3f2,stroke:#16756f,color:#122029
  classDef neutral fill:#f1f4f6,stroke:#5b7a87,color:#122029
  classDef risk fill:#fbeceb,stroke:#b4332b,color:#122029
  class POL,LOG,SEC,TRI core
  class MEM,SIEM,OWN,SOC neutral
  class MGMT risk

Text equivalent: The management account, marked as a risk, holds no workloads because SCPs and RCPs do not limit it; it attaches the organisation policies (SCP, RCP, declarative), which apply to the member accounts holding workloads. Member accounts send audit events through the organisation trail to a log archive account, which feeds a query store or SIEM, and findings to a security tooling account and its triage queue: misconfigurations go to the workload owner to fix in code, threats to the SOC.

Design choices, with their evidence:

  • Keep the management account empty. “SCPs don’t affect users or roles in the management account”, nor RCPs its resources.[13][14]
  • Log through the organisation. Member-account users “do not have sufficient permissions to delete organization trails, turn logging on or off, change what types of events are logged”.[40] Only the security team administers the archive account.
  • Cover every enabled Region. Security Hub CSPM “only receives and processes findings in the Region where you enabled” it, and AWS recommends enabling GuardDuty “in all AWS Regions”, including ones you do not use, because attackers can create resources there.[41][42]
Layer AWS Azure Google Cloud
Hierarchy for policy Organization, OUs, accounts Management groups, subscriptions Organization, folders, projects
Preventive guardrails SCP, RCP, declarative policies Azure Policy (deny, denyAction)[20] Organization Policy constraints[21]
Control-plane log CloudTrail organisation trail[40] Activity log via diagnostic settings[12] Admin Activity audit logs[24]

End-to-end workflow: from change to verified fix

Link to section “End-to-end workflow: from change to verified fix”
Figure 2. From a configuration change to a verified fix, with the exception path
yesyesnonomisconfigurationsuspicious activitySLA missedChange: pipeline, console,script or attackerPreventive guardrailmatches?Call denied and loggedLegitimate need?Exception request: owner,reason, expiryRequester changes thedesignResource created or changedPosture scan or detectionFinding type?Owner fixes in IaC within SLASOC incident and runbookRescan confirms closureEscalate, or exception withexpiry
Diagram source (Mermaid)
flowchart TB
  CHG["Change: pipeline, console, script or attacker"] --> PRE{"Preventive guardrail matches?"}
  PRE -->|"yes"| DENY["Call denied and logged"]
  DENY --> EXC{"Legitimate need?"}
  EXC -->|"yes"| REQ["Exception request: owner, reason, expiry"]
  EXC -->|"no"| STOP["Requester changes the design"]
  PRE -->|"no"| RES["Resource created or changed"]
  RES --> SCAN["Posture scan or detection"]
  SCAN --> TRI{"Finding type?"}
  TRI -->|"misconfiguration"| FIX["Owner fixes in IaC within SLA"]
  TRI -->|"suspicious activity"| INC["SOC incident and runbook"]
  FIX --> VER["Rescan confirms closure"]
  FIX -->|"SLA missed"| ESC["Escalate, or exception with expiry"]
  classDef core fill:#e8f3f2,stroke:#16756f,color:#122029
  classDef decision fill:#fdf3e3,stroke:#c9800f,color:#122029
  classDef risk fill:#fbeceb,stroke:#b4332b,color:#122029
  class CHG,RES,SCAN,FIX,VER,REQ core
  class PRE,EXC,TRI decision
  class DENY,INC,ESC,STOP risk

Text equivalent: A change arrives from a pipeline, console, script or attacker. If a preventive guardrail matches, the call is denied and logged; a legitimate need becomes an exception request with owner, reason and expiry, otherwise the design changes. If not, the change happens and a posture scan or detection evaluates it: misconfigurations go to the owner to fix in infrastructure as code, confirmed by a rescan (a missed target escalates or becomes a time-limited exception); suspicious activity becomes a SOC incident with a runbook.

Acceptance criteria (this page’s suggestion): every finding has an owner within one working day, and every closure is confirmed by a rescan, not a ticket comment.

Practice Trigger Owner Output Verification
Guardrail release New risk, incident, benchmark change Cloud security, with platform Policy as code, staged by OU No unexpected denials in the test OU
Logging baseline New account or Region Platform Organisation trail or exports A test event reaches the archive
Posture triage New critical finding Cloud security Owner and due date, or false-positive record Finding closes on rescan
Credential hygiene Long-lived key detected Workload owner Key replaced by role or federation Unused-access findings fall
Detection game day Quarterly, new detection Cloud security with SOC Alert received, runbook followed Time to alert within target

Separate what binds you from what guides you:

Framework Type Use it for Caveat
CIS Foundations Benchmarks (AWS 7.1.0, Azure 6.0.0, Google Cloud 5.0.0 as of October 2026)[43][44][45] Consensus guidance, free PDF for non-commercial use A starting baseline with assessment procedures Tools lag versions; some checks are manual
Microsoft cloud security benchmark (v1; v2 in preview)[46] Vendor benchmark, multicloud Azure-first estates; pre-mapped to CIS, NIST, PCI DSS v2 baselines not yet published
CSA Cloud Controls Matrix v4.1[47] Control framework, 197 objectives in 17 domains Assigning each control to provider or customer Control objectives, not settings
CISA/NSA cloud information sheets (2024)[8] Government guidance Identity, keys, segmentation, data, MSP risks Advisory outside US federal mandates
CISA BOD 25-01[9] Mandatory for US federal civilian agencies SaaS tenant baselines (SCuBA: Secure Cloud Business Applications) Binding only in its jurisdiction
MITRE ATT&CK Cloud matrix (v20)[48] Threat knowledge base Choosing and testing control-plane detections Coverage maps are not protection

Tools lag benchmarks. CIS lists AWS Foundations 7.1.0 as current,[43] while Security Hub CSPM “supports CIS AWS Foundations Benchmark versions 5.0.0, 3.0.0, 1.4.0, and 1.2.0” and leaves some requirements, such as metric-filter alarms, as manual checks.[49] A green dashboard means passes the automated subset of an earlier version; record the version.

This page maps the most consequential recurring mistakes to Security Hub CSPM control IDs and to a preventive option (AWS, as of October 2026).[50]

Misconfiguration Check Preventive option
A policy allowing * actions on * resources IAM.1 Validation gate and permission boundaries (IAMOps)
Root user access keys IAM.4 Centralised root access, then delete member-account root credentials[51]
User credentials unused for 45 days IAM.22 Federation for people; unused-access findings[22]
Trust or resource policies open to other accounts IAM.28 (analyzer on) External-access findings; data-perimeter RCP[16]
Publicly restorable EBS snapshots EC2.1, EC2.182 Snapshot and image block public access (EC2 declarative policy)[29]
Admin ports open to 0.0.0.0/0 or ::/0 EC2.53, EC2.54 Detective, routed to the owner; VPC Block Public Access where no ingress is needed[29]
Public buckets S3.1, S3.8 Organisation-level S3 block[52]
IMDSv1 still accepted EC2.8 Instance metadata defaults (EC2 declarative policy)[29]
KMS key scheduled for deletion KMS.3 SCP on kms:ScheduleKeyDeletion[34]
Category Job Verified examples (October 2026) Limits and selection criteria
Native preventive Block calls or settings AWS SCP, RCP, declarative policies; Azure Policy; Google Organization Policy Provider-specific; know exempt principals
Native posture Check configuration against standards Security Hub CSPM (needs AWS Config, Regional; also checks Azure);[41][53] Defender for Cloud;[17] Security Command Center[54] Attack paths only in paid tiers (Defender CSPM, SCC Premium)
Access analysis Find external, internal and unused access IAM Access Analyzer[22] External analyzers are Regional
Threat detection Flag suspicious control-plane and network activity GuardDuty;[42] Defender for Cloud plans; Security Command Center Premium Detections are vendor-defined; test them
Multicloud CNAPP One posture and risk view across providers Defender for Cloud (AWS, GCP connectors); Security Hub CSPM (Azure); commercial CNAPPs Consolidation risk: SCC Enterprise shuts down on 21 May 2027;[54] Google closed its Wiz acquisition in March 2026[10]
Open source Scan or enforce as code Prowler (Apache 2.0, many providers);[55] Cloud Custodian (CNCF incubating)[56] You run, update and tune them

Native tools now cross providers (as of October 2026). AWS runs two services. Security Hub CSPM, cited throughout this page, also scores Azure against CIS Azure Foundations v4.0 (CIS lists 6.0.0). The newer AWS Security Hub correlates CSPM, Inspector, Macie and GuardDuty findings into exposure findings with an attack path graph, in OCSF (Open Cybersecurity Schema Framework). AWS recommends enabling both.[53][57]

Selection criteria: coverage of the benchmark version you need; organisation-wide and cross-Region aggregation; export in an open format (Prowler writes CSV and JSON-OCSF by default; its SARIF output, a static-analysis format, is for IaC scans only);[58] routing to owners rather than to one security queue; cost model (per check, per resource, per role); and an exit plan if the vendor changes hands.

Automate prevention freely and remediation carefully: only what is reversible, high-confidence and narrow, such as re-enabling a public access block on a bucket tagged as private; never auto-delete data or rotate credentials in use. Azure Policy’s modify and deployIfNotExists effects remediate inside the platform;[20] elsewhere, run automation as a dedicated, logged role. Language models can summarise findings and draft runbook steps, but their suggestions are changes that need review; see AIOps for Security.

Assumptions: an AWS organisation with all features enabled, a security tooling account, a log archive account, policies kept in Git and deployed by a pipeline role. The worked artefacts are AWS-first: for Azure and Google Cloud, item 3 gives the storage equivalent and the layer table names the policy and log mechanisms, without worked examples.

1. A service control policy that protects security telemetry. Adapted from AWS’s samples: member accounts cannot leave the organisation, stop or narrow audit and posture recording, disable detectors, or suppress findings (archive rules, filters, trusted-IP lists, or setting a Security Hub CSPM finding to SUPPRESSED), and only the deployer can alter the two exempt roles.[34][59] IAMOps teaches how such policies are written; its example protects the trail and access keys, while this one covers posture, detection and the break-glass path.

Example status: JSON syntax-checked by the validator; not executed (requires an AWS organisation). Action names and the Security Hub condition key checked against AWS’s machine-readable service reference on 2026-10-17.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyLeaveOrganization",
      "Effect": "Deny",
      "Action": "organizations:LeaveOrganization",
      "Resource": "*"
    },
    {
      "Sid": "ProtectAuditAndPosture",
      "Effect": "Deny",
      "Action": [
        "cloudtrail:DeleteTrail",
        "cloudtrail:StopLogging",
        "cloudtrail:UpdateTrail",
        "cloudtrail:PutEventSelectors",
        "config:StopConfigurationRecorder",
        "config:DeleteConfigurationRecorder",
        "config:PutConfigurationRecorder",
        "config:DeleteDeliveryChannel",
        "config:PutDeliveryChannel",
        "securityhub:DisableSecurityHub",
        "securityhub:BatchDisableStandards",
        "securityhub:UpdateStandardsControl",
        "securityhub:BatchUpdateStandardsControlAssociations",
        "securityhub:DisassociateFromAdministratorAccount",
        "securityhub:DisassociateFromMasterAccount",
        "access-analyzer:DeleteAnalyzer",
        "access-analyzer:CreateArchiveRule",
        "access-analyzer:UpdateArchiveRule",
        "access-analyzer:ApplyArchiveRule",
        "access-analyzer:UpdateFindings"
      ],
      "Resource": "*",
      "Condition": {
        "ArnNotLike": {
          "aws:PrincipalARN": [
            "arn:aws:iam::*:role/security-breakglass",
            "arn:aws:iam::*:role/org-baseline-deployer"
          ]
        }
      }
    },
    {
      "Sid": "DenyFindingSuppression",
      "Effect": "Deny",
      "Action": "securityhub:BatchUpdateFindings",
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "securityhub:ASFFSyntaxPath/Workflow.Status": "SUPPRESSED"
        },
        "ArnNotLike": {
          "aws:PrincipalARN": [
            "arn:aws:iam::*:role/security-breakglass",
            "arn:aws:iam::*:role/org-baseline-deployer"
          ]
        }
      }
    },
    {
      "Sid": "ProtectThreatDetection",
      "Effect": "Deny",
      "Action": [
        "guardduty:DeleteDetector",
        "guardduty:UpdateDetector",
        "guardduty:DisassociateFromAdministratorAccount",
        "guardduty:DisassociateFromMasterAccount",
        "guardduty:ArchiveFindings",
        "guardduty:CreateFilter",
        "guardduty:UpdateFilter",
        "guardduty:CreateIPSet",
        "guardduty:UpdateIPSet",
        "guardduty:CreateTrustedEntitySet",
        "guardduty:UpdateTrustedEntitySet"
      ],
      "Resource": "*",
      "Condition": {
        "ArnNotLike": {
          "aws:PrincipalARN": [
            "arn:aws:iam::*:role/security-breakglass",
            "arn:aws:iam::*:role/org-baseline-deployer"
          ]
        }
      }
    },
    {
      "Sid": "ProtectExemptRoles",
      "Effect": "Deny",
      "Action": [
        "iam:CreateRole",
        "iam:DeleteRole",
        "iam:UpdateRole",
        "iam:UpdateAssumeRolePolicy",
        "iam:AttachRolePolicy",
        "iam:DetachRolePolicy",
        "iam:PutRolePolicy",
        "iam:DeleteRolePolicy",
        "iam:PutRolePermissionsBoundary",
        "iam:DeleteRolePermissionsBoundary",
        "iam:TagRole",
        "iam:UntagRole"
      ],
      "Resource": [
        "arn:aws:iam::*:role/security-breakglass",
        "arn:aws:iam::*:role/org-baseline-deployer"
      ],
      "Condition": {
        "ArnNotLike": {
          "aws:PrincipalARN": "arn:aws:iam::*:role/org-baseline-deployer"
        }
      }
    }
  ]
}

Preconditions and limits:

  • Scope. It binds only member accounts, and not service-linked roles.[13] It does not cover Macie, Inspector, the EventBridge rules behind your detections, or the log archive’s key and bucket.
  • Exempt roles. Each exemption matches a role name in any account, so both names are protected: create the roles while vending an account, before it joins a governed OU, and alert on every use.
  • A second layer. Member accounts cannot change an organisation trail anyway,[40] so the CloudTrail actions protect account-level trails. Manage GuardDuty and Security Hub CSPM through Organizations, where only the administrator manages GuardDuty’s lists and central configuration stops centrally managed accounts from disabling standards or controls.[60][61]
  • Finding suppression. DenyFindingSuppression closes the scoring trap under Metrics: a member account “can update findings only for their own account”. AWS documents this deny as an IAM policy, so validate it as an SCP (Lab 2, step 1) before attaching.[59]

2. A resource control policy that requires TLS. A shortened version of AWS’s sample “Restrict access to only HTTPS connections to your resources” (the sample covers more services).[16] RCPs apply to a listed subset of services and not to resources in the management account.[14]

Example status: JSON syntax-checked; not executed.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "EnforceSecureTransport",
      "Effect": "Deny",
      "Principal": "*",
      "Action": ["s3:*", "sts:*", "kms:*", "sqs:*", "secretsmanager:*"],
      "Resource": "*",
      "Condition": {
        "BoolIfExists": {
          "aws:SecureTransport": "false"
        }
      }
    }
  ]
}

3. The same intent on Google Cloud: prevent public Cloud Storage access across the organisation. When enforced, “no one can make data in applicable buckets public through IAM policies or ACLs”; existing public grants stay in place but are overridden.[62]

Example status: YAML syntax-checked; not executed. Replace the organisation ID.

name: organizations/123456789012/policies/storage.publicAccessPrevention
spec:
  rules:
    - enforce: true

Apply it with gcloud org-policies set-policy policy.yaml; the same command accepts a dry-run specification for testing first.[21] On Azure, assign a deny policy for the same intent with enforcementMode set to DoNotEnforce, review compliance, then switch to Default.[39]

4. Validate before you attach. IAM Access Analyzer validates SCPs and RCPs against grammar and best practice and returns ERROR, SECURITY_WARNING, WARNING and SUGGESTION findings.[63] Make an empty ERROR and SECURITY_WARNING list a pipeline gate.

Lab 1 runs anywhere with Python and was executed. Labs 2 and 3 need an AWS organisation and were not executed; their expected outputs come from the cited documentation.

Lab 1 (beginner): find public storage exposure and expired exceptions

Link to section “Lab 1 (beginner): find public storage exposure and expired exceptions”

Objective: learn how layered public-access settings combine, why a “fixed value” condition matters, and why exceptions need expiry dates. Prerequisites: Python 3.8 or later; no cloud account, cost or risk; 40 minutes.

The script is a teaching approximation of the Amazon S3 rules for what counts as “public”:[64] a statement that allows Principal: "*" is public unless a listed condition key has a fixed value, and an aws:SourceIp range broader than /8 still counts as public. It treats negated operators (StringNotEquals, NotIpAddress) as not narrowing, and ignores aws:userid, access points and the ForAnyValue/ForAllValues set operators. Use IAM Access Analyzer or S3’s own policy status for real decisions.

  1. Save the three files below as exposure_check.py, inventory.json and exceptions.json.
  2. Run python3 exposure_check.py inventory.json exceptions.json 2026-10-16, then echo $?.
  3. In inventory.json, set the account’s IgnorePublicAcls to false and run again.
  4. Restore it, set "org_bpa": {"enforced": true} and run again. Ask what happens to marketing-site, which serves a website.

Example status: verified by execution (Python 3.8.10, 2026-10-16; re-run after the r1 change, 2026-10-17); outputs below are verbatim.

"""Teaching approximation of S3 public-exposure evaluation (not a replacement
for IAM Access Analyzer or S3's own policy-status check)."""
import ipaddress
import json
import sys
from datetime import date

FIXED_KEYS = {  # condition keys that can make a policy non-public (AWS S3 docs)
    "aws:principalorgid", "aws:sourceip", "aws:sourcearn", "aws:sourcevpc",
    "aws:sourcevpce", "aws:sourceowner", "aws:sourceaccount",
    "s3:dataaccesspointarn", "s3:dataaccesspointaccount",
}
BPA = ["BlockPublicAcls", "IgnorePublicAcls", "BlockPublicPolicy",
       "RestrictPublicBuckets"]
PUBLIC_GROUPS = ("AllUsers", "AuthenticatedUsers")


def effective_bpa(org, account, bucket):
    """Most restrictive combination: a setting is on if any level turns it on."""
    org_all = org.get("enforced", False)  # org level is all-or-nothing
    return {k: org_all or account.get(k, False) or bucket.get(k, False) for k in BPA}


def is_fixed(value):
    values = value if isinstance(value, list) else [value]
    return all(isinstance(v, str) and not any(c in v for c in "*?$") for v in values)


RFC1918 = [ipaddress.ip_network(n) for n in
           ("10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16")]


def too_broad(cidrs):
    """Broader than /8 (IPv4) or /32 (IPv6), RFC 1918 ranges excepted."""
    cidrs = cidrs if isinstance(cidrs, list) else [cidrs]
    for c in cidrs:
        net = ipaddress.ip_network(c, strict=False)
        if net.version == 4 and any(net.subnet_of(p) for p in RFC1918):
            continue
        if net.prefixlen < (8 if net.version == 4 else 32):
            return True
    return False


def statement_is_public(stmt):
    if stmt.get("Effect") != "Allow":
        return False
    principal = stmt.get("Principal")
    if isinstance(principal, dict):
        principal = principal.get("AWS")
    principals = principal if isinstance(principal, list) else [principal]
    if "*" not in principals:
        return False
    for op_name, operator in stmt.get("Condition", {}).items():
        if "Not" in op_name:  # negated operators never narrow a grant
            continue
        for key, value in operator.items():
            if key.lower() not in FIXED_KEYS or not is_fixed(value):
                continue
            if key.lower() == "aws:sourceip" and too_broad(value):
                continue
            return False  # one fixed-value key narrows the grant
    return True


def assess(bucket, org, account):
    bpa = effective_bpa(org, account, bucket.get("bpa", {}))
    stmts = bucket.get("policy", {}).get("Statement", [])
    policy_public = any(statement_is_public(s) for s in stmts)
    acl_public = any(g in PUBLIC_GROUPS for g in bucket.get("acl_grantees", []))
    exposed = []
    if policy_public and not bpa["RestrictPublicBuckets"]:
        exposed.append("bucket policy")
    if acl_public and not bpa["IgnorePublicAcls"]:
        exposed.append("ACL")
    return exposed, bpa


def main(inventory_path, exceptions_path, today):
    inv = json.load(open(inventory_path))
    exceptions = {e["bucket"]: e for e in json.load(open(exceptions_path))}
    failures = 0
    for b in inv["buckets"]:
        exposed, _ = assess(b, inv.get("org_bpa", {}), inv.get("account_bpa", {}))
        exc = exceptions.get(b["name"])
        if not exposed:
            status = "OK"
        elif exc and date.fromisoformat(exc["expires"]) >= today:
            status = f"PUBLIC, excepted to {exc['expires']} ({exc['owner']})"
        elif exc:
            status = f"PUBLIC, exception EXPIRED {exc['expires']}"
            failures += 1
        else:
            status = "PUBLIC, no exception"
            failures += 1
        via = f" via {', '.join(exposed)}" if exposed else ""
        print(f"{b['name']:<18} {status}{via}")
    print(f"summary: {len(inv['buckets'])} buckets, {failures} need action")
    return 1 if failures else 0


if __name__ == "__main__":
    as_of = date.fromisoformat(sys.argv[3]) if len(sys.argv) > 3 else date.today()
    sys.exit(main(sys.argv[1], sys.argv[2], as_of))
{
  "org_bpa": {"enforced": false},
  "account_bpa": {"BlockPublicAcls": true, "IgnorePublicAcls": true},
  "buckets": [
    {"name": "app-logs-prod",
     "policy": {"Statement": [{"Effect": "Allow",
       "Principal": {"Service": "logging.s3.amazonaws.com"},
       "Action": "s3:PutObject", "Resource": "*"}]}},
    {"name": "partner-drop",
     "policy": {"Statement": [{"Effect": "Allow", "Principal": "*",
       "Action": "s3:GetObject", "Resource": "*",
       "Condition": {"StringEquals": {"aws:PrincipalOrgID": "o-exampleorg1"}}}]}},
    {"name": "marketing-site",
     "policy": {"Statement": [{"Effect": "Allow", "Principal": "*",
       "Action": "s3:GetObject", "Resource": "*"}]}},
    {"name": "legacy-exports",
     "acl_grantees": ["AllUsers"],
     "policy": {"Statement": [{"Effect": "Allow", "Principal": {"AWS": "*"},
       "Action": "s3:GetObject", "Resource": "*",
       "Condition": {"IpAddress": {"aws:SourceIp": "0.0.0.0/1"}}}]}},
    {"name": "data-science-tmp",
     "bpa": {"RestrictPublicBuckets": true},
     "policy": {"Statement": [{"Effect": "Allow", "Principal": "*",
       "Action": "s3:GetObject", "Resource": "*"}]}}
  ]
}
[
  {"bucket": "marketing-site", "owner": "web-team", "reason": "static site",
   "expires": "2026-12-31"},
  {"bucket": "legacy-exports", "owner": "finance-it", "reason": "vendor migration",
   "expires": "2026-09-30"}
]

Expected output (step 2), exit code 1:

app-logs-prod      OK
partner-drop       OK
marketing-site     PUBLIC, excepted to 2026-12-31 (web-team) via bucket policy
legacy-exports     PUBLIC, exception EXPIRED 2026-09-30 via bucket policy
data-science-tmp   OK
summary: 5 buckets, 1 need action

Validation. Step 3 changes one line to legacy-exports PUBLIC, exception EXPIRED 2026-09-30 via bucket policy, ACL (exit code 1): with IgnorePublicAcls off, the public ACL counts again. Step 4 prints OK for all five buckets and summary: 5 buckets, 0 need action (exit code 0), because the organisation level applies all four settings together.[64] What to notice: partner-drop is not public because its condition uses a fixed aws:PrincipalOrgID; legacy-exports is public because 0.0.0.0/1 is broader than /8; data-science-tmp relies on a bucket setting that its editors could remove. In step 4 the website stops serving the public, the trade-off examined in A judgement call. Troubleshooting: JSONDecodeError usually means a trailing comma; AttributeError: … subnet_of means Python older than 3.7. Teardown: delete the three files.

Lab 2 (intermediate): stage two guardrails in a test OU (AWS)

Link to section “Lab 2 (intermediate): stage two guardrails in a test OU (AWS)”

Objective: release the reference SCP and RCP to one test OU and prove they work.[65] Prerequisites:

  • an AWS organisation with all features;
  • a pipeline role limited to Organizations policy actions, or a member account made a delegated administrator for policies, not management-account administrator credentials;[66]
  • a test OU with one sandbox account holding a test role, an account-level trail named sandbox-trail and a bucket with one throw-away object.

Cost and risk: negligible cost; a wrong attachment can lock users out, so attach only to the test OU.[13] Time: 60 minutes.

Example status: syntax-checked; not executed (no AWS organisation available). IDs such as r-exam and ou-exam-test1234 are placeholders.

# 1. Validate both policies (expect no ERROR or SECURITY_WARNING findings).
aws accessanalyzer validate-policy --policy-type SERVICE_CONTROL_POLICY \
  --policy-document file://scp-protect.json
aws accessanalyzer validate-policy --policy-type RESOURCE_CONTROL_POLICY \
  --policy-document file://rcp-tls.json

# 2. Enable RCPs once for the organisation root.
aws organizations enable-policy-type --root-id r-exam \
  --policy-type RESOURCE_CONTROL_POLICY

# 3. Create the policies and attach them to the test OU only.
SCP_ID=$(aws organizations create-policy --type SERVICE_CONTROL_POLICY \
  --name protect-security-telemetry --description "Lab 2 SCP" \
  --content file://scp-protect.json --query Policy.PolicySummary.Id --output text)
RCP_ID=$(aws organizations create-policy --type RESOURCE_CONTROL_POLICY \
  --name require-tls --description "Lab 2 RCP" \
  --content file://rcp-tls.json --query Policy.PolicySummary.Id --output text)
aws organizations attach-policy --policy-id "$SCP_ID" --target-id ou-exam-test1234
aws organizations attach-policy --policy-id "$RCP_ID" --target-id ou-exam-test1234

# 4. From the sandbox account's test role: both calls should be denied.
#    The second sends a signed request over plain HTTP on purpose; use the
#    bucket's own Region in the endpoint URL.
aws cloudtrail stop-logging --name sandbox-trail
aws s3api get-object --bucket example-lab-bucket --key test.txt out.txt \
  --endpoint-url http://s3.eu-west-1.amazonaws.com

# 5. Confirm the trail is still logging and HTTPS access still works.
aws cloudtrail get-trail-status --name sandbox-trail --query IsLogging
aws s3api get-object --bucket example-lab-bucket --key test.txt out.txt

Expected output: step 1 returns an empty or suggestion-only findings list; step 4 returns two access-denied errors (the first should name an explicit deny in a service control policy); step 5 prints true and downloads the object. Validation: the denied calls appear in the sandbox account’s event history with an access-denied error code. Troubleshooting: if step 4 succeeds, check that the account really sits in the test OU and that the role has neither exempt name; if step 3 fails with a policy-type error, step 2 has not completed. Teardown: aws organizations detach-policy for both IDs, then aws organizations delete-policy; disable the RCP type if nothing else uses it.

Lab 3 (advanced): detect logging tampering and test the alert

Link to section “Lab 3 (advanced): detect logging tampering and test the alert”

Objective: alert within minutes when anyone stops or changes a trail, and measure the time to alert. Prerequisites: a sandbox account with an active trail, permission to manage EventBridge and SNS, and a way to run cloudtrail stop-logging there (the break-glass role, or detach the Lab 2 SCP first). Cost: negligible. Time: 45 minutes.

To receive these events in EventBridge “you must enable a CloudTrail trail with logging”; they reach the account’s default event bus, and rules in the default ENABLED state match write management events.[67] ATT&CK v20 files this behaviour as T1685.002, Disable or Modify Cloud Log.[11]

Example status: JSON syntax-checked; not executed.

{
  "source": ["aws.cloudtrail"],
  "detail-type": ["AWS API Call via CloudTrail"],
  "detail": {
    "eventSource": ["cloudtrail.amazonaws.com"],
    "eventName": ["StopLogging", "DeleteTrail", "UpdateTrail", "PutEventSelectors"]
  }
}

Save the pattern above as pattern.json and the topic policy below as topic-policy.json, with your Region and account ID. AWS documents this EventBridge statement without a condition, so keep the topic for this rule alone.[68]

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublishEventsToMyTopic",
      "Effect": "Allow",
      "Principal": {"Service": "events.amazonaws.com"},
      "Action": "sns:Publish",
      "Resource": "arn:aws:sns:eu-west-1:111122223333:cloud-log-tamper"
    }
  ]
}
TOPIC_ARN=$(aws sns create-topic --name cloud-log-tamper --query TopicArn --output text)
aws sns set-topic-attributes --topic-arn "$TOPIC_ARN" --attribute-name Policy \
  --attribute-value file://topic-policy.json
aws sns subscribe --topic-arn "$TOPIC_ARN" --protocol email \
  --notification-endpoint secops-oncall@example.com
aws events put-rule --name cloud-log-tamper --event-pattern file://pattern.json
aws events put-targets --rule cloud-log-tamper --targets "Id=sns,Arn=$TOPIC_ARN"

# Game day: note the time, stop logging, wait for the e-mail, restart logging.
date -u +%H:%M:%S
aws cloudtrail stop-logging --name sandbox-trail
aws cloudtrail start-logging --name sandbox-trail

Expected output: an SNS e-mail containing "eventName": "StopLogging" and the caller’s ARN. Validation: record the minutes between the date output and the e-mail; get-trail-status shows IsLogging true after the restart. Troubleshooting: no e-mail usually means an unconfirmed subscription, a missing topic policy, or a rule created in a different Region from the call. The lesson: if the stopped trail were the account’s only trail, later calls might never reach EventBridge; the organisation trail and GuardDuty, whose consumption your CloudTrail settings do not affect, cover that gap.[42] Teardown: aws events remove-targets --rule cloud-log-tamper --ids sns, aws events delete-rule --name cloud-log-tamper, aws sns delete-topic --topic-arn "$TOPIC_ARN".

For the sourced cases, the lessons drawn are this page’s mapping, not the investigators’ findings.

Scenario Context CloudSecOps response Success measure
1. Over-permissioned role (sourced) Capital One, 2019: “The intrusion occurred through a misconfigured web application firewall that enabled access to the data” (DOJ).[69] Krebs reported request forgery against the metadata service and a role “assigned too many permissions”.[70] IMDSv2 by default through an EC2 declarative policy;[29] roles scoped to named buckets; data events on sensitive buckets[25] Instances requiring IMDSv2; sensitive buckets logged
2. Valid stolen credentials (sourced) Snowflake customers, 2024: no MFA, credentials “had not been rotated or updated”, no network allow lists.[5] A SaaS platform, but the failure, identity at the tenant API, transfers to any provider (IdentityOps teaches the case as its Case 3) MFA and federation for people; long-lived keys replaced; access from trusted networks only; alerts on abnormal access Long-lived credentials trending to zero
3. Missing logs (sourced) Exchange Online, 2023: the detecting agency relied on a premium-licence log (SOC Ops teaches the detection); the CSRB asked for default logs “without additional charges, with a minimum default retention of six months”.[6] Inventory default logs per provider and licence; enable what investigations need before an incident Logging coverage matches the written standard
4. A 40-account scale-up turns on CSPM (illustrative) Thousands of findings on day one; teams ignore the dashboard Exposure findings first; organisation-level blocks where no legitimate use exists; owners and SLAs for the rest Critical dwell time on target within a quarter
KPI Definition and formula Data source Pitfall Cadence
Guardrail coverage Accounts under the current guardrail set ÷ active accounts Organisation policy attachments Management account always excluded; report it separately Monthly
Logging coverage (Account, enabled Region) pairs whose control-plane events reach the organisation archive ÷ all pairs Trail and export status Opt-in Regions enabled later are missed Weekly
Detection coverage Pairs with threat detection on ÷ all pairs Detector status Detectors off in newly enabled Regions Weekly
Critical exposure dwell time Median of (closed − first seen) for public-exposure and admin-credential findings Posture tool timestamps Counts closed findings only, so leaving the hardest open improves it; closure by suppression Weekly
Open critical finding age p50 and p90 of (now − first seen) for open critical findings Posture tool Report it beside dwell time, never instead Weekly
Exception debt Open exceptions past expiry ÷ open exceptions Exception register Silent renewals; count renewals too Weekly
Long-lived credentials Active user access keys + service-account keys IAM reports, Access Analyzer Counting keys, not their privilege Monthly
Detection test pass rate Control-plane tests that alerted within target ÷ tests run Game-day log Testing only easy detections Quarterly
Tool control pass rate Passed ÷ (passed + failed + unknown) controls Posture tool Suppressing failed findings raises it Monthly, as context only

The last row is a trap. AWS defines its security score as “the proportion of Passed controls to enabled controls” and warns that “if you suppress all failed findings for a control, its status becomes Passed”.[71] A score is a lagging, gameable view of an automated subset; dwell time, open-finding age and exception debt show whether the operating model works.

The main quality risk is self-inflicted: a deny at the wrong level locks out a team or a pipeline, which is why AWS “strongly recommends” testing SCPs before attaching them to the root.[13] Regulation is jurisdictional: BOD 25-01 binds only US federal civilian agencies.[9] Audit logs contain personal data such as user names and IP addresses, so set their retention with PrivacyOps and their evidence use with ComplianceOps. Accepting a residual risk is its owner’s decision (RiskOps), not the finder’s. This page is not legal advice.

Logging and posture costs shape design (as of October 2026):

  • CloudTrail delivers one copy of management events without a CloudTrail charge (storage is billed); scope the extra-cost data events to sensitive data stores.[23][25]
  • Azure charges no ingestion for activity logs in Log Analytics, only retention beyond 90 days.[12] Google leaves Data Access logs off “because they can generate large volumes of data”.[24]
  • Security Hub CSPM charges per check and finding after a 30-day trial; Access Analyzer charges for unused and internal access analysis; Defender’s foundational CSPM and SCC Standard cost nothing extra.[41][22][17][54]

Price logging by the investigations it enables: a missing log cannot be bought during an incident. Cost allocation belongs to FinOps.

Assure the guardrails themselves: run the Lab 3 game day quarterly for each critical detection; diff attached organisation policies against Git weekly; enable a new benchmark version before disabling the old one, as AWS advises.[49] Risk indicators: denials that teams work around by moving accounts between OUs, exceptions renewed rather than closed, findings closed without a rescan, detectors off in newly enabled Regions, and growing counts of long-lived keys.

Symptom Likely cause Diagnosis Remediation Prevention
A team is locked out after a policy change Deny attached too high, missing exception Access-denied events naming a service control policy Detach or narrow; add exception Staged rollout by OU
Dashboard green, auditor finds gaps Tool covers an older benchmark or only automated checks Compare tool version with CIS list[49] Add manual checks Record benchmark version
Findings never close No owner, or fix made in console and reverted by IaC Finding reopens after deploy Fix in code Route by owner tag
Alert expected, none arrived Trail stopped, rule in wrong Region, detector off in that Region Trail status, rule Region, detector list Restore; extend coverage Logging-coverage KPI
A public bucket reappears Bucket-level block removed by someone with bucket rights[64] Event history for the setting change Account or organisation block Organisation-level block
Investigation lacks data Data events or Data Access logs never enabled Logging standard vs reality Enable now; accept the historical gap Logging standard reviewed with responders

Worked runbook: logging stopped and an unknown access key is active

Link to section “Worked runbook: logging stopped and an unknown access key is active”

Trigger: the Lab 3 rule reports StopLogging on a production account trail, and threat detection reports API calls from an access key in a country where the team does not work. Severity: high until scoped. Incident command follows IncidentOps; evidence and eradication depth follow ResponseOps.

Figure 3. Containment sequence for a control-plane alert
Cloud APIs and log archiveOn-call engineerSOC leadAlert: StopLogging and odd key useQuery activity since key creationCalls and resources touchedDeclare incident with scopeDisable key, deny user, revoke sessionsConfirmedRemove persistence, restart loggingHand over evidence and timeline
Diagram source (Mermaid)
sequenceDiagram
  participant S as SOC lead
  participant E as On-call engineer
  participant P as Cloud APIs and log archive
  Note over E: Alert: StopLogging and odd key use
  E->>P: Query activity since key creation
  P-->>E: Calls and resources touched
  E->>S: Declare incident with scope
  E->>P: Disable key, deny user, revoke sessions
  P-->>E: Confirmed
  E->>P: Remove persistence, restart logging
  E->>S: Hand over evidence and timeline

Text equivalent: On the alert, the on-call engineer queries the log archive for the key’s activity since it was created, gets back the calls and resources touched, and declares a scoped incident to the SOC lead. Through the cloud APIs the engineer disables the key, denies all actions to the user and revokes role sessions (confirmed), removes persistence, restarts logging, and hands evidence and a timeline to the SOC lead.

  1. Confirm and preserve. Check that the organisation trail is still logging (member accounts cannot stop it).[40] Do not delete anything; snapshot evidence before changing resources.
  2. Scope. In the log archive, list every call made with the access key ID, every role it assumed, and every GetSessionToken or GetFederationToken call: those return temporary keys (IDs starting ASIA) that keep working after the long-term key is disabled, so follow their key IDs too.[72] Note created users, keys, roles, trust-policy changes and data reads.
  3. Contain. Deactivate the key (aws iam update-access-key --user-name <user> --access-key-id <key-id> --status Inactive), then attach the AWS managed policy AWSDenyAll to the user. Temporary credentials “are valid until they expire” (up to 36 hours), and AWS says “you must also change permissions for the IAM user or role” to stop them; sessions the user created are evaluated against the user’s own policies, so the deny ends them. Root-user sessions cannot be stopped this way, one more reason for IAM.4.[73] For roles the key assumed, revoke sessions: AWS attaches a deny on aws:TokenIssueTime, which does not stop sessions assumed afterwards, so first remove the attacker’s ability to re-assume the role.[74]
  4. Eradicate. Delete persistence found in step 2; check for new resources in Regions you do not use.
  5. Recover and verify. Restart the trail, confirm IsLogging is true, rerun the posture scan, watch for the key ID for 30 days.
  6. Learn. Why did a long-lived key exist, and why could its holder stop logging? Usually both lead to a guardrail (the reference SCP) and a credential-hygiene backlog item.
  • “The provider secures the cloud for us.” The provider secures its infrastructure; configurations, identities and data stay with you in every model.[18]
  • Dashboard-driven security. Chasing a score invites suppression, which raises it.[71] Manage dwell time and exceptions.
  • Deny everything at the root on day one. It locks out teams and produces exception sprawl; stage by OU.[34]
  • Exempting a role name without protecting it. Anyone who can create a role with that name inherits the bypass.
  • “Key rotation protects our data.” AWS states that rotation “has no effect on the data that the KMS key protects” and “will not mitigate the effect of a compromised data key”; KMS keys are mostly wrapping keys “almost never reused enough to risk key exhaustion”.[75] Rotate where rules require it, but spend effort on who can use the key.
  • “GuardDuty keeps our logs.” It extracts fields “and then discards these logs”; investigations need your own archive.[42]

Use a deliberate CloudSecOps practice when several hold: more than a handful of accounts or subscriptions; production or regulated data in the cloud; many teams with API access; a security team that cannot review every change; auditors who expect continuous control evidence.

Do not build a separate function when the estate is one or two accounts run by one small team. For small organisations Microsoft’s guidance is to “Combine cloud platform engineering and security responsibilities into a single function”;[38] free native posture tiers and an organisation-wide log are enough to start. Do not buy a CNAPP first if nobody owns findings: it will produce a backlog without a workflow. Hidden responsibilities: maintaining exceptions, benchmark upgrades, detector coverage in new Regions, and the on-call rota for control-plane alerts.

Most decisions in CloudSecOps are about where a control should live. The tree below is this Atlas’s proposal.

Figure 4. Choosing preventive or detective placement for a proposed control
noyesyesnoyesnonoyesCould this action causesevere harm in any account?Detective check, routed toownerAny legitimate use in someaccounts?Can those accounts sit intheir own OU?Preventive at organisationroot, stagedPreventive on other OUs;detective thereCan a condition express theexception?Detective with fast SLA andauto-alertPreventive with testedconditionReview quarterly: promote orretire
Diagram source (Mermaid)
flowchart TB
  Q1{"Could this action cause severe harm in any account?"}
  Q1 -->|"no"| D1["Detective check, routed to owner"]
  Q1 -->|"yes"| Q2{"Any legitimate use in some accounts?"}
  Q2 -->|"yes"| Q3{"Can those accounts sit in their own OU?"}
  Q2 -->|"no"| P1["Preventive at organisation root, staged"]
  Q3 -->|"yes"| P2["Preventive on other OUs; detective there"]
  Q3 -->|"no"| Q4{"Can a condition express the exception?"}
  Q4 -->|"no"| D2["Detective with fast SLA and auto-alert"]
  Q4 -->|"yes"| P3["Preventive with tested condition"]
  D1 --> R["Review quarterly: promote or retire"]
  D2 --> R
  classDef decision fill:#fdf3e3,stroke:#c9800f,color:#122029
  classDef core fill:#e8f3f2,stroke:#16756f,color:#122029
  classDef neutral fill:#f1f4f6,stroke:#5b7a87,color:#122029
  class Q1,Q2,Q3,Q4 decision
  class P1,P2,P3 core
  class D1,D2,R neutral

Text equivalent: If the action cannot cause severe harm in any account, use a detective check routed to the owner. If it can and has no legitimate use, make it preventive at the organisation root, staged. If some accounts need it and can sit in their own OU, prevent it elsewhere and detect it there. Otherwise prevent with a tested policy condition if one can express the exception, or detect with a fast service-level target and automatic alerts. Detective controls are reviewed quarterly and promoted or retired.

Assumptions: preventive controls can be tested in a non-production OU, and the people a condition constrains cannot set it themselves; if a tag drives the exception, protect the tag or it becomes a bypass.

This maturity model is this Atlas’s proposal, not an industry standard.

Level Observable behaviour Exit criteria
0 Ad hoc Per-account defaults; findings seen only after incidents Organisation-wide audit log and posture scan enabled
1 Visible Findings exist but few have owners Every critical finding has an owner within a day
2 Baselined Written baseline, guardrails in audit mode or a test OU, exception register Benchmark version recorded; exceptions all have expiry dates
3 Enforced Preventive guardrails by OU, logging and detection coverage complete Coverage 100%; median critical dwell under target for a quarter
4 Engineered Guardrails as tested code; detections game-dayed; metrics change the baseline Each critical detection passes its quarterly test
Figure 5. Maturity progression and the usual regressions
turn on org logging and scansowners and SLAsenforce by OUtest guardrails and detectionsexceptions renewed, notclosedtriage stops, backlog grows0 Ad hoc1 Visible2 Baselined3 Enforced4 Engineered
Diagram source (Mermaid)
flowchart TB
  L0["0 Ad hoc"] -->|"turn on org logging and scans"| L1["1 Visible"]
  L1 -->|"owners and SLAs"| L2["2 Baselined"]
  L2 -->|"enforce by OU"| L3["3 Enforced"]
  L3 -->|"test guardrails and detections"| L4["4 Engineered"]
  L3 -.->|"exceptions renewed, not closed"| L2
  L2 -.->|"triage stops, backlog grows"| L1
  classDef core fill:#e8f3f2,stroke:#16756f,color:#122029
  classDef risk fill:#fbeceb,stroke:#b4332b,color:#122029
  class L0,L1,L2,L3,L4 core

Text equivalent: The five levels of the table in order, each step labelled with its main action (organisation logging and scans, owners and SLAs, enforcement by OU, tested guardrails and detections). Two dotted arrows show regressions: level 3 falls back to 2 when exceptions are renewed rather than closed, and level 2 to 1 when triage stops and the backlog grows.

Window Actions Milestone Metric
Days 1–30 Organisation-wide logs into a locked archive; posture scans and threat detection in all enabled Regions; one benchmark version; long-lived key inventory Level 1 Logging and detection coverage measured
Days 31–60 Owners and SLAs for critical findings; exception register with expiry; reference SCP and storage block in a test OU; Lab 3 detection live Level 2 Median critical dwell time measured
Days 61–90 Enforce the first preventive guardrails OU by OU; quarterly scorecard to leadership; first game day Start of level 3 Guardrail coverage; exception debt

Quick wins: storage blocks on OUs with no public buckets; no root access keys; threat detection in unused Regions. Dependency: an IaC pipeline for organisation policies (InfraOps).

Quick start

  • Organisation-wide control-plane logging into an account workload admins cannot change
  • Posture scanning and threat detection in every enabled Region
  • One benchmark version chosen and recorded
  • Critical-finding routing to owners, with a service-level target

Guardrail preflight

  • Policy validated (no ERROR or SECURITY_WARNING findings)
  • Exempt principals listed and protected; management account and service-linked roles noted as not covered
  • Attached to a test OU for at least one week with access-denied events reviewed
  • Rollback is a one-line detach in the pipeline

Logging readiness

  • Data-plane logs enabled for sensitive data stores
  • Identity-provider sign-in and directory logs exported beyond their default retention
  • Retention set with privacy and compliance owners
  • A test event found in the archive in under one hour

Quarterly review

  • Each critical detection passed its game day
  • Exceptions past expiry: zero
  • Benchmark and tool versions re-checked

Guardrail record (one per guardrail, kept next to the policy code):

id: GR-007
intent: Member accounts cannot disable, narrow or suppress audit, posture or detection
type: preventive (second layer)
mechanism: AWS SCP protect-security-telemetry (incl. DenyFindingSuppression)
preconditions: [GuardDuty and Security Hub CSPM managed via Organizations]
scope: all OUs except Sandbox (detective there)
not_covered: [management account, service-linked roles, Macie, Inspector, detection rules]
exempt_principals: [role/security-breakglass, role/org-baseline-deployer]
owner: cloud-security
test: Lab 3 game day, quarterly
exceptions: none
last_reviewed: 2026-10-16

Exception request:

Exception ID:        EX-2026-031
Guardrail:           GR-012 (no public object storage)
Resource / account:  marketing-site / web-prod
Reason:              Static website; CDN migration planned
Compensating control: Bucket holds public assets only; data events logged
Risk owner:          Head of Web (accepts the residual risk)
Expires:             2026-12-31 (max 90 days; renewal needs a new review)

Quarterly scorecard: guardrail, logging and detection coverage, median and mean critical dwell time, open critical finding age, exception debt, long-lived credential count, detection test pass rate, benchmark version assessed, top three risks and decisions needed.

Approach Strength Weakness Choose when
Native tools per provider Free or cheap tiers; deep integration Partial cross-provider coverage; attack paths in paid tiers One or two main providers
Multicloud CNAPP One workflow and risk model across providers Licence cost; vendor consolidation risk Three or more providers, small team
Open source (Prowler, Cloud Custodian) Transparent checks; runs in your pipeline You maintain and tune it Strong engineering team; need for custom checks

Is CloudSecOps a job title or a team? Both appear; the label is not standardised. What matters is that someone owns guardrails, posture, logging and cloud detections.

Do we need a CNAPP? Not to start: the free tiers and trial under Cost are enough to begin. Attack-path analysis no longer needs one: AWS Security Hub, the paid Defender CSPM plan and SCC Premium offer it.[57][17][54] A CNAPP earns its cost through one workflow across several providers.

Should every CIS check be enforced? No. Your baseline chooses among the recommendations and records exceptions.

Does SaaS belong here? It is a close neighbour: CISA’s BOD 25-01 sets baselines for Microsoft 365 tenants.[9] This page covers infrastructure and platform providers, but the guardrail-and-evidence pattern carries over.

What if the provider itself is compromised? You cannot prevent it, but your logs, keys you control and detections on your own tenancy are what let you see it. The CSRB report describes a customer whose own logs first revealed an intrusion that turned out to stem from a provider key compromise.[6]

  • Data perimeters: combining SCPs, RCPs and network conditions so only trusted identities reach trusted resources.[16]
  • Configuration that survives new APIs: AWS declarative policies are enforced “in the service’s control plane”, so the baseline holds “even when the service introduces new features or APIs”.[19]
  • AI workloads: AI posture management in Defender for Cloud and an AI domain in the Microsoft benchmark v2 preview are early signs.[17][46]
  • Provider logging norms: the CSRB asked cloud providers for default audit logs without extra charge, kept at least six months.[6] Microsoft raised Purview Audit (Standard) retention from 90 to 180 days for records from 17 October 2023;[76] this page found no cross-provider standard for the wider ask (as of October 2026).
  • Shifting vocabulary: ATT&CK v20 moved cloud log tampering to T1685.002 under a “Defense Impairment” tactic;[11] update detection mappings that use the old ID.
  • Prerequisites: CloudOps for hierarchy and accounts; one provider’s IAM evaluation logic (IAMOps).
  • One day: Lab 1; read your provider’s SCP or Azure Policy documentation and its audit-log defaults.
  • One week: Labs 2 and 3 in a sandbox organisation; run Prowler with --compliance against a test account and triage the output.[55][77]
  • 30 days: write a baseline mapped to one CIS benchmark, an exception process and the scorecard; run one game day.
  • Specialise: cluster security (KubernetesSecOps), detections (DetectionOps), telemetry (SecDataOps) or response (ResponseOps).
  • Portfolio: a public repository with tested guardrail policies, a logging standard and a game-day report.
Topic Remember
What it is Security enforced, measured and investigated at the provider API
Decide Which few actions to deny everywhere; which logs to keep and for how long; who owns findings
Practices Staged guardrails, organisation-wide logging, owner-routed triage, expiring exceptions, game days
Metrics Guardrail, logging and detection coverage; critical dwell time with open-finding age; exception debt; long-lived credentials
Watch-outs Management account and service-linked roles sit outside SCPs and RCPs; tools lag benchmarks; scores can be gamed
Next action Run Lab 1 on a real inventory export and count your expired exceptions

A judgement call: block public storage across the organisation now, or fix first?

Link to section “A judgement call: block public storage across the organisation now, or fix first?”

Situation (illustrative): an AWS estate of 60 accounts has 14 publicly readable buckets. Nine hold website assets; five are unexplained. The CISO asks for an organisation-level S3 block “today”.

Option A, enforce at the root now. Organisation-level S3 policies apply all four block settings together and override account settings.[52] Every unexplained exposure closes at once, but the nine website buckets stop serving too, and the pressure to restore them can produce exemptions by moving accounts out of the OU, weakening every guardrail for those accounts.

Option B, detect and fix first. Triage all 14 within days, move websites behind a CDN with private origins, then enforce. The estate stays exposed during the work, and “temporary” can become permanent.

Assumptions that decide it: whether the five unexplained buckets hold sensitive data (unknown until triaged), and whether OUs can be split so website accounts sit apart. A reasoned choice: close the five unexplained exposures now with account- or bucket-level blocks, enforce the organisation-level block today on every OU without a public bucket (Lab 1’s step 4 shows the effect), and give the website OU a dated plan to move behind a CDN, with a detective rule meanwhile. Option A looks safest, but breaking production on day one is how guardrails lose their sponsors. Uncertainty: if an unexplained bucket holds personal data, that account moves to Option A and to incident handling.

You can now explain what CloudSecOps covers and where its label is unsettled; design a guardrail set with exceptions; operate logging, posture triage and control-plane detections; and evaluate posture metrics and tools critically.

  1. An SCP denies cloudtrail:StopLogging, yet a trail was stopped. Name two ways this can happen.
Show answer for question 1

The call came from the management account, which SCPs do not affect, or from a principal matching the exemption (for example, a role created with the break-glass name in an account that does not protect it).[13] A service-linked role is also outside SCPs.

  1. Your posture score rose from 71% to 90% in a week with no deployments. What do you check first?
Show answer for question 2

Suppressions and archived findings. AWS notes that suppressing all failed findings for a control makes it “Passed”.[71] Also check whether a standard was disabled or a Region removed from aggregation.

  1. Why does BlockPublicPolicy alone not close an existing public bucket?
Show answer for question 3

It rejects new public bucket policies but “doesn’t affect existing” ones. RestrictPublicBuckets limits access granted by an existing public policy.[64] Lab 1’s data-science-tmp shows the effect.

  1. During an investigation you need object reads from six months ago on AWS and Google Cloud. What do you probably lack, and why?
Show answer for question 4

Data-plane logs. CloudTrail data events are off by default and Google’s Data Access logs are off by default except for BigQuery.[25][24] Logs not collected cannot be recovered; the CSRB case shows the cost.[6]

  1. A team revoked active sessions on a compromised role, yet the attacker is back an hour later. Why? And what else must you do when the stolen credential is an IAM user’s access key?
Show answer for question 5

Revocation denies sessions issued before the revocation time; a session assumed afterwards is not affected.[74] The attacker still held whatever let them assume the role. Remove that source (a key, a trust-policy entry) first. For a user key, deactivation leaves sessions from GetSessionToken or GetFederationToken valid until they expire, up to 36 hours; attach a deny-all policy to the user as well.[73]

  1. Your tool reports full CIS compliance on AWS. What two caveats belong in the report?
Show answer for question 6

The benchmark version (Security Hub CSPM supports up to 5.0.0, while CIS lists 7.1.0) and the requirements the tool marks as manual checks.[49][43]

CloudSecOps is a young name for an old problem in a new place. The name will keep shifting; trade press and a certification body already use it differently. The place will not: every cloud resource, permission and log setting passes through a provider API, and the cases that teach most (an over-permissioned role, valid stolen passwords, logs nobody switched on) were failures of configuration, identity and evidence at that layer. This page’s proposal is simple to state: enforce centrally a short list of things that must never happen, let owners fix everything else in code against a clock, and test guardrails and detections like applications. Start with logs you can trust; then make dangerous things impossible, one OU at a time.

Claim-by-claim evidence: research/cloudsecops-ledger.md. Re-verify dated facts (versions, retention defaults, prices) quarterly or when CIS, AWS, Microsoft or Google announce changes, and re-check neighbour anchors on each rebuild.

Changelog. 2026-10-16, r0: first version; Lab 1 executed, Labs 2–3 not executed. 2026-10-17, r1: revised after independent review reviews/cloudsecops-r1.md (item-by-item response in reviews/cloudsecops-r1-response.md): TechTarget definition, stolen-key containment, telemetry SCP, identity-log defaults, keys and misconfiguration sections, Security Hub split; Lab 1 re-run. 2026-10-17, r1.1: score follow-ups S1, S2, S5, S6 (reviews/cloudsecops-score-superseded-20261017T0519.md): the DenyFindingSuppression statement, IdentityOps link, decision-tree title, re-check cadence. 2026-10-17, post-score polish (reviews/cloudsecops-polish.md): worked artefacts labelled AWS-first; SCP action names and condition key re-checked against AWS’s service reference; dense passages split into lists; decision tree narrowed; restatements trimmed.


  1. SecOps vs. CloudSecOps: What does a CloudSecOps team do? — Dave Shackleford, TechTarget, 2022-07-14. Checked 2026-10-16. ↩︎ ↩︎ ↩︎

  2. CloudSecOps: When SecOps Meets Cloud Security — Gilad David Maayan, Data Center Knowledge, 2022-02-16. Checked 2026-10-16. ↩︎ ↩︎

  3. CCSP Certification Exam Outline — ISC2, page dated 2026-08-01. Checked 2026-10-16. ↩︎

  4. Cloud Security Alliance Releases Top Threats to Cloud Computing 2024 Report — CSA, 2024-08-06. Checked 2026-10-16. ↩︎

  5. UNC5537 Targets Snowflake Customer Instances for Data Theft and Extortion — Mandiant, Google Cloud blog, 2024-06-10. Checked 2026-10-16. ↩︎ ↩︎ ↩︎

  6. Review of the Summer 2023 Microsoft Exchange Online Intrusion — Cyber Safety Review Board, report dated 2024-03-20. Checked 2026-10-16. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  7. What is a Cloud Native Application Protection Platform (CNAPP)? — Josh Dreyfuss (Wiz), Cloud Security Alliance blog, 2021-10-25. Checked 2026-10-16. ↩︎

  8. CISA and NSA Release Cybersecurity Information Sheets on Cloud Security Best Practices — CISA, 2024-03-07. Checked 2026-10-16. ↩︎ ↩︎

  9. BOD 25-01: Implementing Secure Practices for Cloud Services — CISA, 2024-12-17. Checked 2026-10-16. ↩︎ ↩︎ ↩︎ ↩︎

  10. Google Completes $32 Billion Acquisition of Wiz — Cleary Gottlieb, 2026-03-11. Checked 2026-10-16. ↩︎ ↩︎

  11. Disable or Modify Tools: Disable or Modify Cloud Log, T1685.002 — MITRE ATT&CK, modified 2026-05-12. Checked 2026-10-16. ↩︎ ↩︎ ↩︎

  12. Activity Log in Azure Monitor — Microsoft Learn, updated 2026-10-15. Checked 2026-10-16. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  13. Service control policies (SCPs) — AWS Organizations. Checked 2026-10-16. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  14. Resource control policies (RCPs) — AWS Organizations. Checked 2026-10-16. ↩︎ ↩︎ ↩︎ ↩︎

  15. Use the Instance Metadata Service to access instance metadata — AWS. Checked 2026-10-16. ↩︎ ↩︎

  16. Resource control policy examples and Data perimeter policy examples — AWS samples on GitHub. Checked 2026-10-16. ↩︎ ↩︎ ↩︎ ↩︎

  17. Microsoft Defender for Cloud Overview — Microsoft Learn, updated 2026-08-10. Checked 2026-10-16. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  18. Shared responsibility in the cloud — Microsoft Learn, updated 2026-08-24. Checked 2026-10-16. ↩︎ ↩︎

  19. Declarative policies in AWS Organizations — AWS. Checked 2026-10-16. ↩︎ ↩︎

  20. Azure Policy definitions effect basics — Microsoft Learn, updated 2025-12-01. Checked 2026-10-16. ↩︎ ↩︎ ↩︎

  21. Creating and managing organization policies — Google Cloud; see also gcloud org-policies set-policy. Checked 2026-10-16. ↩︎ ↩︎ ↩︎ ↩︎

  22. Using AWS IAM Access Analyzer — AWS. Checked 2026-10-16. ↩︎ ↩︎ ↩︎ ↩︎

  23. What Is AWS CloudTrail? — AWS. Checked 2026-10-16. ↩︎ ↩︎

  24. Cloud Audit Logs overview — Google Cloud, updated 2026-10-16. Checked 2026-10-16. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  25. Logging data events — AWS CloudTrail. Checked 2026-10-16. ↩︎ ↩︎ ↩︎ ↩︎

  26. AWS Management Console sign-in events — AWS CloudTrail. Checked 2026-10-17. ↩︎

  27. Microsoft Entra data retention — Microsoft Learn, updated 2026-03-25. Checked 2026-10-17. ↩︎ ↩︎

  28. Audit logs for Google Workspace — Google Cloud, updated 2026-10-16. Checked 2026-10-17. ↩︎

  29. EC2 policies — AWS Organizations. Checked 2026-10-16. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  30. Managing secure-by-default organization resources — Google Cloud, updated 2026-10-13. Checked 2026-10-16. ↩︎

  31. AWS KMS keys — AWS KMS Developer Guide. Checked 2026-10-17. ↩︎

  32. Default key policy — AWS KMS Developer Guide. Checked 2026-10-17. ↩︎

  33. Delete an AWS KMS key — AWS KMS Developer Guide. Checked 2026-10-17. ↩︎

  34. Service control policy examples — AWS Organizations, with the linked sample repository. Checked 2026-10-16. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  35. Azure Key Vault soft-delete overview — Microsoft Learn, updated 2026-06-12. Checked 2026-10-17. ↩︎

  36. Destroy and restore key versions — Google Cloud, updated 2026-10-13. Checked 2026-10-17. ↩︎

  37. Logging AWS KMS API calls with AWS CloudTrail — AWS KMS Developer Guide. Checked 2026-10-17. ↩︎

  38. Security Teams, Roles, and Functions — Microsoft Cloud Adoption Framework, updated 2026-10-01. Checked 2026-10-16. ↩︎ ↩︎

  39. Details of the policy assignment structure — Microsoft Learn, updated 2026-09-18. Checked 2026-10-16. ↩︎ ↩︎

  40. Creating a trail for an organization — AWS CloudTrail. Checked 2026-10-16. ↩︎ ↩︎ ↩︎ ↩︎

  41. Introduction to AWS Security Hub CSPM — AWS. Checked 2026-10-16. ↩︎ ↩︎ ↩︎

  42. GuardDuty foundational data sources — AWS. Checked 2026-10-16. ↩︎ ↩︎ ↩︎ ↩︎

  43. CIS Amazon Web Services Benchmarks — Center for Internet Security. Checked 2026-10-16. ↩︎ ↩︎ ↩︎

  44. CIS Microsoft Azure Benchmarks — Center for Internet Security. Checked 2026-10-16. ↩︎

  45. CIS Google Cloud Computing Platform Benchmarks — Center for Internet Security. Checked 2026-10-16. ↩︎

  46. Microsoft cloud security benchmark introduction — Microsoft Learn, updated 2026-02-03. Checked 2026-10-16. ↩︎ ↩︎

  47. Cloud Controls Matrix — Cloud Security Alliance (version 4.1). Checked 2026-10-16. ↩︎

  48. Cloud Matrix — MITRE ATT&CK, content v20. Checked 2026-10-16. ↩︎

  49. CIS AWS Foundations Benchmark in Security Hub CSPM — AWS. Checked 2026-10-16. ↩︎ ↩︎ ↩︎ ↩︎

  50. Security Hub CSPM controls reference — AWS. Checked 2026-10-17. ↩︎

  51. Centralize root access for member accounts — AWS IAM User Guide. Checked 2026-10-17. ↩︎

  52. Amazon S3 policies — AWS Organizations. Checked 2026-10-16. ↩︎ ↩︎

  53. Integrating Security Hub CSPM with Microsoft Azure — AWS. Checked 2026-10-17. ↩︎ ↩︎

  54. Security Command Center service tiers — Google Cloud, updated 2026-10-15. Checked 2026-10-16. ↩︎ ↩︎ ↩︎ ↩︎

  55. prowler-cloud/prowler — Prowler, GitHub. Checked 2026-10-16. ↩︎ ↩︎

  56. Cloud Custodian — CNCF. Checked 2026-10-16. ↩︎

  57. What are Security Hub and Security Hub CSPM? and Introduction to AWS Security Hub — AWS. Checked 2026-10-17. ↩︎ ↩︎

  58. Reporting in Prowler — Prowler documentation. Checked 2026-10-17. ↩︎

  59. Using BatchUpdateFindings to update a finding and BatchUpdateFindings API — AWS Security Hub CSPM. Checked 2026-10-17. ↩︎ ↩︎

  60. Working with trusted lists and threat lists — Amazon GuardDuty User Guide. Checked 2026-10-17. ↩︎

  61. Understanding central configuration in Security Hub CSPM — AWS. Checked 2026-10-17. ↩︎

  62. Public access prevention — Google Cloud. Checked 2026-10-16. ↩︎

  63. aws accessanalyzer validate-policy — AWS CLI Command Reference. Checked 2026-10-16. ↩︎

  64. Blocking public access to your Amazon S3 storage — AWS. Checked 2026-10-16. ↩︎ ↩︎ ↩︎ ↩︎

  65. aws organizations create-policy — AWS CLI Command Reference. Checked 2026-10-16. ↩︎

  66. Delegated administrator for AWS Organizations — AWS Organizations. Checked 2026-10-17. ↩︎

  67. AWS service events delivered via AWS CloudTrail — Amazon EventBridge. Checked 2026-10-16. ↩︎

  68. Using resource-based policies for Amazon EventBridge — Amazon EventBridge. Checked 2026-10-17. ↩︎

  69. United States v. Paige Thompson — US Attorney’s Office, Western District of Washington, updated 2022-01-13. Checked 2026-10-16. ↩︎

  70. What We Can Learn from the Capital One Hack — Brian Krebs, Krebs on Security, 2019-08-02. Checked 2026-10-16. ↩︎

  71. Calculating security scores — AWS Security Hub CSPM. Checked 2026-10-16. ↩︎ ↩︎ ↩︎

  72. IAM identifiers — AWS IAM User Guide. Checked 2026-10-17. ↩︎

  73. Disabling permissions for temporary security credentials and Permissions for GetFederationToken — AWS IAM User Guide. Checked 2026-10-17. ↩︎ ↩︎

  74. Revoke IAM role temporary security credentials — AWS. Checked 2026-10-16. ↩︎ ↩︎

  75. Rotate AWS KMS keys — AWS. Checked 2026-10-16. ↩︎

  76. Learn about auditing solutions in Microsoft Purview — Microsoft Learn, updated 2026-07-08. Checked 2026-10-17. ↩︎

  77. Compliance — Prowler documentation. Checked 2026-10-16. ↩︎

Related Ops

CloudOps

CloudOps (cloud operations) is running workloads on public cloud through the provider's control plane: account hierarchy, guardrails, quotas, Regions, provider signals and managed-service change. The label is common, but no neutral body defines it.

IAMOps

IAMOps is an informal label for IAM operations. This Atlas uses it for authorisation as code: designing, testing and evaluating the policies that decide what people, workloads and agents may do, so permissions stay minimal, explainable and testable.

KubernetesSecOps

KubernetesSecOps is a rare name for Kubernetes security operations: running the controls that decide who may change a cluster, what may run in it, what may talk to what, and how an attack in progress is noticed and contained.

DevSecOps

DevSecOps is the practice of building security into the software delivery pipeline and into the teams that run it, so that every change is checked, traceable and safe to ship without a separate security phase that stalls delivery.

ComplianceOps

ComplianceOps runs regulatory and contractual compliance as a continuous operation: one library of controls mapped to every framework in scope, evidence collected and tested on a schedule, exceptions with expiry dates, and audits served from records that already exist.

SOC Ops

SOC Ops is running a security operations centre as a dependable service: turning alerts into timely, recorded decisions through tiers, playbooks, SIEM and SOAR, shift handover, metrics and sourcing choices that people can sustain around the clock.

SecDataOps

SecDataOps is the engineering and governance of security telemetry: onboarding log sources, parsing and normalising them to a schema, enriching, routing and tiering them, and retaining them so that detections, investigations and audits have complete, trustworthy and affordable evidence.

SecOps

SecOps is an ambiguous label. Here it means the working contract between security and IT operations: agreed hardening baselines, one owned remediation queue with deadlines, governed exceptions and joint metrics. Others use it for SOC work or a Google product.

Practise and get certified

From xOps School

Practise CloudSecOps and get certified

The free CloudSecOps track on xOps School has study notes, a 25-question practice quiz with explanations, and a verifiable certificate when you score 70% or more. Sign in with Google to start.

For teams

Instructor-led training

Live batches for your team, with completion certificates and reports for L&D/HR.

Source: master.md (the editorial source of this page) · built 2026-10-17 · diagrams rendered with @mermaid-js/mermaid-cli 11.17.0 (mermaid 11.17.2)