- 1Foundation — accounts, identity & guardrailsYou're reading this
- Network & Perimeter — segmentation & private connectivityComing Aug 2026
- Data & Secrets — encryption, KMS & storageComing Sep 2026
- Detection & Response — logging, CSPM & threat detectionComing Oct 2026
- Govern & Comply — policy-as-code & continuous complianceComing Nov 2026
Cloud Security Program · Part 1 — Foundation: Accounts, Identity & Guardrails
The first deep-dive: the multi-cloud foundation every later phase depends on — account/organization structure, identity, and preventative guardrails across AWS, GCP and Azure.
This is Part 1 of the Cloud Security Program — the foundation the entire program stands on. Before you configure a single firewall rule or turn on a threat detector, three things have to be true across every cloud you run: your workloads live in an account structure that isolates blast radius, the right people (and only the right people) can reach the control plane through one governed identity, and there are org-wide guardrails a well-meaning engineer cannot click past. Get these wrong and every later phase is built on sand — a private-network design is meaningless if any team can attach a public IP, and a KMS strategy is worthless if a role can disable encryption on a whim. This part is deliberately unglamorous and deliberately thorough: it is the highest-leverage cloud-security work you will ever do, and almost none of it costs money. It costs configuration discipline and a few focused days.
The structure throughout is a three-column comparison — AWS, GCP, Azure side by side — because these are the same controls wearing three different badges. Learn the concept once; apply it three times.
Scope of this phase
Every part of this program is scope-bounded so you know exactly when you are done and are not tempted to boil the ocean.
- In scope: the account/organization hierarchy and landing-zone structure that isolates prod from non-prod and limits blast radius; centralised human identity with SSO and MFA and least-privilege access; the elimination of long-lived static keys in favour of federated/workload identity; org-wide preventative guardrails (deny public storage, restrict regions, require encryption); and a baseline logging + configuration-recording posture, turned on now and consumed in Part 4.
- Explicitly out of scope (later parts): network segmentation, private connectivity and WAF/DDoS (Part 2); encryption design, KMS key hierarchies and secrets management (Part 3); the detection, CSPM and incident-response use of the logs you enable here (Part 4); and continuous compliance, drift and framework mapping (Part 5). You prepare the ground for these here; you do not implement them yet.
- Definition of done: the exit checklist at the end of this part. When every box is ticked across all three clouds, you are ready for Part 2 — and not before.
The foundation, across three clouds
| Building block | AWS | GCP | Azure |
|---|---|---|---|
| Organization structure | Organizations + OUs · Control Tower | Organization + Folders + Projects | Management Groups + Subscriptions |
| Identity | IAM Identity Center · IAM | Cloud Identity + IAM | Microsoft Entra ID |
| Preventative guardrails | Service Control Policies (SCPs) | Organization Policies | Azure Policy |
| Logging & config baseline | CloudTrail + AWS Config | Cloud Audit Logs + Asset Inventory | Activity Log + Resource Graph |
The concepts are identical across AWS, GCP and Azure — only the service names differ.
The three building blocks — structure, identity, guardrails — are independent enough to parallelise across a small team, but all three must be complete before the program advances. Let's take them one at a time.
Building block 1 — Account & organization structure
You cannot apply a control to an environment you have not drawn a boundary around. The first job is to organise workloads into an isolating hierarchy so that a compromise, a mistake or a runaway cost in one place cannot spill into another. Every cloud gives you the same primitive — a top-level organization with nested containers holding the actual workload accounts — under three different names.
| Concept | AWS | GCP | Azure |
|---|---|---|---|
| Top of hierarchy | Organization (AWS Organizations) | Organization resource | Tenant (root management group) |
| Grouping container | Organizational Units (OUs) | Folders | Management Groups |
| Workload boundary | Accounts | Projects | Subscriptions (+ resource groups) |
| Guided landing zone | Control Tower | (landing-zone blueprints / Terraform) | (Landing Zone accelerator) |
The universal rule: separate prod from non-prod at the account boundary, not just with tags. A production workload lives in its own AWS account / GCP project / Azure subscription, distinct from dev and staging. The isolation is what makes the boundary real — an over-permissive role or a misconfigured resource in dev cannot reach prod because they are different accounts with different identities and different guardrails. Group these workload boundaries under OUs / folders / management groups that mirror how you actually run — for example a Prod OU, a Non-Prod OU, a Sandbox OU, and a Security OU for the audit and logging accounts — so you can attach a guardrail once, high in the tree, and have it inherit down to everything beneath it.
Keep the management/root account clean. In AWS, the Organizations management account should own almost no workloads; in GCP, no resources hang directly off the organization node; in Azure, the tenant root management group is for policy assignment, not for running things. This is where the whole hierarchy's trust originates, so it must be the least-exposed, most-tightly-held part of the estate.
Building block 2 — Identity
Identity is the perimeter. In the cloud there is no network moat around the control plane; the thing standing between an attacker and your ability to create, read or destroy every resource is whether they can authenticate as a principal that has access. That makes identity the single highest-value control in the program — and it splits into two halves: human identity and workload (machine) identity.
Centralise human identity behind one directory
Each cloud has a native way to centralise workforce identity, ideally federated to the IdP you already pay for (Okta, Google Workspace, Entra ID):
| Concern | AWS | GCP | Azure |
|---|---|---|---|
| Workforce identity | IAM Identity Center (federated to your IdP) | Cloud Identity / Workspace + IAM | Microsoft Entra ID |
| Per-request authorization | IAM policies / roles | Cloud IAM roles & bindings | Azure RBAC role assignments |
| Console access model | Permission sets → accounts | IAM bindings per project/folder/org | Role assignments per scope |
The non-negotiables, identical across all three:
- SSO everywhere, so access is granted and revoked in one place. Humans should not have per-cloud local users. In AWS that means IAM Identity Center federated to your IdP rather than long-lived IAM users; in GCP, human access through your Workspace/Cloud Identity accounts; in Azure, Entra ID as the one directory.
- MFA enforced by policy, not opt-in — on every path that reaches the control plane. Phishing-resistant factors (passkeys / WebAuthn / FIDO2 hardware keys) are strongly preferred for anyone with admin or production access.
- No shared logins. Every human has their own identity; every API call is attributable.
Least privilege, from groups not people
Model access as roles mapped to IdP groups, not permissions granted to individuals — so joining or leaving a team changes access automatically. Default to read-only and grant write/admin only where a role genuinely needs it. Prefer just-in-time elevation over standing production admin: AWS IAM Identity Center permission sets with short sessions, GCP IAM Conditions with time bounds (and Privileged Access Manager for temporary grants), and Azure Entra Privileged Identity Management (PIM) for time-boxed, approved activation of privileged roles.
Kill long-lived static keys
This is the cloud-specific heart of identity, and the most common real-world breach path: a static access key committed to a repo, baked into a container image, or living forever in a CI variable. The fix is the same idea in all three clouds — machines get short-lived, automatically-rotated credentials via federation, never a permanent key:
| Mechanism | AWS | GCP | Azure |
|---|---|---|---|
| Identity for resources in-cloud | IAM roles (instance/task/pod roles; IRSA / EKS Pod Identity) | Attached service accounts / Workload Identity for GKE | Managed identities (system- or user-assigned) |
| Identity for external/CI workloads | IAM Roles Anywhere / OIDC federation (e.g. GitHub Actions → role) | Workload Identity Federation | Workload identity federation (OIDC) to Entra |
| The thing to eliminate | Long-lived IAM user access keys | Downloaded service-account JSON keys | Client secrets / stored credentials |
Concretely: your CI pipeline assumes a role via OIDC instead of holding an access key; your compute reads its identity from the platform metadata endpoint instead of an embedded credential; your Kubernetes pods use IRSA / GKE Workload Identity / Entra workload identity instead of a mounted key file. Where a static key is genuinely unavoidable, it is inventoried, scoped to the minimum, and rotated on a schedule — but the goal of this phase is to drive that list toward zero.
Root and break-glass accounts
Every cloud has an all-powerful identity that must be locked away. The AWS account root user, the GCP Organization Administrator / super-admin, and the Azure Global Administrator are for emergencies and initial setup, not daily use. For each: enable the strongest MFA, remove or vault any programmatic keys, alert on every sign-in, and define exactly one documented, heavily-logged break-glass procedure for when normal federated access fails — tested periodically, and reviewed after every use.
Building block 3 — Preventative guardrails
This is the key foundation idea and the reason cloud security can scale at all. A detective control tells you after the fact that someone made a bucket public. A preventative guardrail makes it impossible in the first place — an org-wide rule, set high in the hierarchy, that individual teams inherit and cannot override. You are moving the security decision from "did everyone remember the rule?" to "the platform refuses the action." Each cloud has one policy engine for this:
| Concept | AWS | GCP | Azure |
|---|---|---|---|
| Guardrail engine | Service Control Policies (SCPs) | Organization Policy Service | Azure Policy (+ initiatives) |
| Applied at | OU / account | Org / folder / project | Management group / subscription |
| Enforcement style | Deny/allow boundary on IAM | Constraints (boolean + list) | Deny / Audit / DeployIfNotExists effects |
| Typical guardrails | Deny public S3, restrict regions, deny disabling CloudTrail | Restrict public IPs, restrict regions, uniform bucket access | Deny public blob, allowed locations, require encryption |
The three guardrails worth having on day one, in every cloud: deny public object storage, restrict which regions can be used (data residency and a smaller attack surface), and require encryption / block the disabling of your audit log. Here is roughly what each looks like.
An AWS SCP that denies making objects public and blocks turning off the org trail, attached to a workload OU:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyPublicS3",
"Effect": "Deny",
"Action": ["s3:PutBucketPublicAccessBlock", "s3:PutAccountPublicAccessBlock"],
"Resource": "*",
"Condition": {
"BoolIfExists": { "s3:PublicAccessBlockConfiguration.BlockPublicAcls": "false" }
}
},
{
"Sid": "ProtectOrgTrail",
"Effect": "Deny",
"Action": ["cloudtrail:StopLogging", "cloudtrail:DeleteTrail"],
"Resource": "arn:aws:cloudtrail:*:*:trail/org-trail"
}
]
}A GCP Organization Policy that pins workloads to approved regions (applied at the org or a folder, inherited by every project beneath):
# gcloud resource-manager org-policies set-policy org-policy-restrict-regions.yaml \
# --organization 123456789012
constraint: constraints/gcp.resourceLocations
listPolicy:
allowedValues:
- in:europe-west1-locations
- in:europe-southwest1-locations
# everything outside these regions is denied for every project below this nodeAn Azure Policy that denies storage accounts that are not configured for encryption in transit, assignable at a management group:
{
"properties": {
"displayName": "Require secure transfer on Storage accounts",
"policyRule": {
"if": {
"allOf": [
{ "field": "type", "equals": "Microsoft.Storage/storageAccounts" },
{ "field": "Microsoft.Storage/storageAccounts/supportsHttpsTrafficOnly", "notEquals": "true" }
]
},
"then": { "effect": "deny" }
}
}
}Define these as code (Terraform, CloudFormation/Config, Bicep) and apply them high in the hierarchy so a new account/project/subscription inherits them the moment it is created. That inheritance is the whole point: security that is on by default for everything you have not built yet.
The baseline logging & config posture (set up now, used in Part 4)
The last job of the foundation is to switch on the two data feeds every later phase depends on, so that from this moment forward everything that happens in your estate is recorded. You are not building detection or dashboards here — that is Part 4 — you are simply making sure the tape is running and the recordings are being kept somewhere tamper-resistant.
| Feed | AWS | GCP | Azure |
|---|---|---|---|
| Control-plane audit log | CloudTrail (org trail, all regions) | Cloud Audit Logs (Admin Activity always on; enable Data Access) | Azure Activity Log (+ Entra sign-in/audit logs) |
| Resource configuration/inventory | AWS Config | Cloud Asset Inventory | Azure Resource Graph |
Two rules for the audit log: make it organization-wide so no account/project/subscription is a blind spot, and ship it to a dedicated, locked-down logging account (the Security OU / a separate GCP project / a separate subscription) whose storage is write-once and out of reach of the accounts it is recording — so an attacker who compromises a workload cannot erase the evidence. This is also your first hard piece of ISO 27001 / SOC 2 / ENS logging evidence; keep it. Turn on the configuration/inventory feed at the same time — you will point CSPM and drift detection at it in Parts 4 and 5, but it only captures history from the moment it is enabled, so enabling it now is what makes that history exist.
Definition of done — Foundation exit checklist
You are ready for Part 2 when every one of these is true, in each cloud you run:
- Structure: a real organization hierarchy (AWS Organizations / GCP Organization / Azure tenant) with OUs / folders / management groups that separate prod from non-prod at the account boundary; workloads isolated in their own accounts / projects / subscriptions; the management/root container kept clean of workloads.
- Human identity: SSO consolidated through one IdP (IAM Identity Center / Cloud Identity / Entra ID); MFA enforced by policy on every control-plane path; phishing-resistant factors for admin/production access; no shared logins.
- Access model: roles mapped to groups, least-privilege defaults, just-in-time elevation for privileged/production access (permission sets / IAM Conditions / PIM), and a completed first access review with records kept.
- Machine identity: workloads authenticate via roles / attached service accounts / managed identities and CI via OIDC federation; long-lived static keys inventoried and driven toward zero; any residual key scoped and on a rotation schedule.
- Root/break-glass: root / super-admin / Global Administrator secured with strong MFA, programmatic keys removed, sign-in alerting on, and one documented, tested break-glass procedure per cloud.
- Guardrails: preventative policies (SCPs / Organization Policies / Azure Policy) applied high in the hierarchy and inherited down — at minimum deny public storage, restrict regions, and require encryption / protect the audit log — defined as code.
- Baseline logging & config: org-wide audit logging (CloudTrail / Cloud Audit Logs / Activity Log) shipping to a dedicated locked-down logging account, plus the configuration/inventory feed (AWS Config / Cloud Asset Inventory / Resource Graph) enabled.
Tick every box and the foundation is solid. Skip one — the forgotten Azure subscription, the one GCP project without the region guardrail — and a later phase will quietly assume it is closed, which is exactly how gaps become incidents.
What's next
Part 2 — Network & Perimeter builds directly on this foundation: with an account structure, governed identity and inherited guardrails in place, we design the network across all three clouds — segmentation with VPCs / VPC networks / VNets, private connectivity to managed services (PrivateLink / Private Service Connect / Private Link), controlled and inspected egress, and edge protection with WAF and DDoS mitigation. The OUs and guardrail engine you stood up here are exactly where the network-layer controls attach. It ships next month.
Standing up this foundation is also the point where a platform starts to earn its keep: ISMShed captures your account structure, identity posture, guardrail coverage and logging baseline as continuous, framework-mapped audit evidence across ISO 27001, ENS, NIS2, DORA, SOC 2 and GDPR — so the configuration this phase produces becomes your compliance story rather than a spreadsheet you rebuild before every audit. If you would like experienced hands to stand the foundation up across your own AWS, GCP and Azure estate, Axelia's cloud-security and GRC consultants run the program alongside you. Get the foundation right, and the rest of the program compounds from there.
