Cloud & Container Security · beginner · ~11 min

The cloud model and IAM

**What you will learn** - Explain the **shared-responsibility model** and split any control into "provider secures" vs "you secure." - Describe what **IAM** is (principals, policies, roles) and why *identity is the perimeter* in the cloud. - Recognise the four failures that cause most cloud breaches: over-permissioning, long-lived keys, broadly-assumable roles, and `iam:PassRole` misuse. - Read a simple IAM policy and tell an over-permissive one (`"*"`) from a **least-privilege** one. - Draw a basic cloud **threat model** and identify where the trust boundary sits. - Apply and *verify* least-privilege remediations in an authorized lab, and know which logs detect IAM abuse.

Overview

Security objective. The asset you are protecting is your cloud account and everything in it — data, compute, and the ability to spend money or create new identities. The threat is an attacker who obtains one credential (a leaked access key, a compromised laptop, a phished login) and then uses excess permissions to move from that foothold up to full control. In this lesson you learn to detect identities with too much power and prevent the privilege-escalation paths that turn a small leak into a total compromise.

In traditional hosting you owned the server, so security asked "is the box patched and behind a firewall?" In the cloud, platforms such as AWS, Azure, and GCP replace servers you rack with on-demand, API-driven services. That changes the core question from "is the box patched?" to "who can do what?"

Two ideas answer that question:

  • The shared-responsibility model splits the work. The provider secures the cloud itself (hardware, hypervisor, managed-service internals). You secure what you put in the cloud (configuration, data, and access).
  • IAM (Identity and Access Management) is how you control access. It is made of principals (users, roles, service accounts) and policies (rules about which actions a principal may take on which resources).

This lesson has no prerequisites — it is the entry point to the Cloud & Container Security track. It sets up the mindset you will reuse everywhere: the very next lesson, Storage buckets, security groups, and public exposure (cloud-storage-exposure), is really a special case of the same question — an IAM/config decision that accidentally grants access to the whole internet.

Why it matters

In real, authorized cloud work the single most valuable finding is usually not an exotic exploit — it is an identity with more power than its job requires. Industry breach reports year after year attribute the majority of cloud incidents to customer-side misconfiguration and identity mistakes, not to the provider's infrastructure failing.

Why this matters professionally:

  • Blast radius. With no network edge to hide behind, whatever a leaked credential is allowed to do is the damage it will do. Least privilege is the difference between "one dev's read-only key leaked" and "the whole account was taken over."
  • This is the core of cloud assessment. A cloud penetration test is mostly IAM analysis: enumerate identities and policies, find over-grants, and map paths from a low-privileged principal up to admin. It is the cloud equivalent of Active Directory attack-path analysis.
  • It is auditable and fixable. Unlike a zero-day, an over-permissive policy is visible in configuration and can be tightened, tested, and monitored. Defenders who understand IAM can measure their exposure and prove it shrank.
  • Compliance and trust. Frameworks (SOC 2, ISO 27001, PCI DSS) all expect least privilege, credential rotation, and access logging. Getting IAM right is table stakes for handling customer data.

Core concepts

1. Shared responsibility

Definition. A model that draws a line between what the cloud provider secures and what the customer secures.

Plain explanation. The provider runs the building, the electricity, the locks on the data-centre doors, and the software that runs virtual machines. You are the tenant: you decide who gets a key to your apartment and what you leave lying on the table.

How it works. The line moves depending on the service model:

Service model Provider secures You secure
IaaS (e.g. a virtual machine) Hardware, hypervisor, network fabric OS patches, apps, data, IAM, firewall rules
PaaS (e.g. managed database) Above plus the OS and DB engine Schema, data, access policies, credentials
SaaS (e.g. hosted email) Almost everything technical Your users, their permissions, your data-sharing settings

When it applies / when not. It always applies, but the boundary shifts by service — a frequent mistake is assuming "managed" means "secured for me." The provider secures the service; you still secure your use of it.

Pitfall. Believing a breach must be the provider's fault. Almost always the misconfiguration was on the customer side of the line.

2. IAM: principals and policies

Definition. Identity and Access Management is the system that decides which identity may perform which action on which resource.

Plain explanation. Three moving parts:

  • Principal — an identity that acts: a human user, a role (a set of permissions something can temporarily assume), or a service account / machine identity.
  • Policy — a document listing allowed (or denied) actions on resources, sometimes with conditions.
  • Permission — the concrete allow that results (e.g. "read objects in bucket X").

How it works. When a principal calls the cloud API, the platform evaluates every attached policy. An explicit Deny always wins; otherwise the request must be explicitly Allowed, or it is refused by default (deny-by-default).

When it applies / when not. IAM governs control-plane access (creating, reading, changing cloud resources). It does not, by itself, secure what happens inside an app you deploy — that is still your application's job.

Pitfall. Reading a role's name and assuming it is safe. ReadOnlyLogsRole may still carry a policy allowing iam:CreateAccessKey. Read the policy, not the name.

3. The four common failures

Definition. The recurring IAM mistakes that create most cloud attack paths.

  1. Over-permissioning — granting "Action": "*" / "Resource": "*" or AdministratorAccess broadly. One leaked key becomes total compromise.
  2. Long-lived access keys — static keys that never expire, used instead of short-lived role credentials. They leak into git history, laptops, and CI logs and stay valid forever.
  3. Broadly-assumable roles — a powerful role whose trust policy lets too many principals assume it, so a weak identity borrows a strong one.
  4. iam:PassRole misuse — permission to hand an existing powerful role to a new service (e.g. launch a VM as an admin role). Combined with a compute-launch permission, a limited user escalates to admin without ever "being" admin.

How it works together. Attackers chain these: enumerate identities → find one they control → find a role it can assume or a PassRole it can abuse → repeat until they reach admin. This is a privilege-escalation path.

When it applies / when not. These are configuration issues, present regardless of how well-patched your servers are. They are not provider bugs.

Pitfall. Fixing one over-grant and declaring victory. Escalation needs only one path; you must map all of them.

4. Least privilege (the fix)

Definition. Grant only the permissions a principal actually needs, for only as long as needed.

Plain explanation. Start from nothing and add the specific actions and resources the task requires, prefer short-lived role credentials over static keys, and remove permissions that go unused.

How it works. Scope by action (s3:GetObject, not s3:*), by resource (one bucket ARN, not *), and by condition (only from your VPC, only with MFA). Rotate and expire credentials automatically.

Pitfall. "We'll tighten it later." Broad grants added "temporarily" are the ones found in breaches years later. Tighten first, loosen only with evidence.

CLOUD IAM THREAT MODEL (single account)

  Entry points (untrusted)                Trust boundary: the cloud IAM control plane
  ------------------------                --------------------------------------------
  [ Leaked access key ]  ---.
  [ Phished console login ] -+--> ( AWS/Azure/GCP API )  ==BOUNDARY==>  ASSETS
  [ Compromised CI token ] --'         |  evaluates policies              - Data (buckets, DBs)
  [ SSRF on an EC2 app ] -----> (instance metadata) --> temp role creds   - Compute (VMs, functions)
                                                                           - Billing / spend
  Principals inside boundary:                                             - IAM itself (create users!)
    user  -> policy(read-only?)                                            
      \__ can it assume a role? ----> role(admin)   <-- escalation path
      \__ can it iam:PassRole + launch compute? ---> runs AS admin role

  Defender's job: shrink each principal's allowed actions so no entry
  point reaches the assets, and LOG every assume-role / policy change.

Knowledge check.

  1. In the diagram above, what asset is ultimately protected, and where is the trust boundary?
  2. A read-only user can call sts:AssumeRole on an admin role. What insecure assumption made this dangerous, and which single log event would reveal the escalation?
  3. Why must you only test these assume-role paths in an authorized lab, never against an account you do not own?

Syntax notes

The heart of IAM is a policy document (JSON in AWS; similar shapes in Azure/GCP). Read it as: this principal may (or may not) perform these Actions on these Resources, under these Conditions.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ReadOneBucketOnly",      // human label for the statement
      "Effect": "Allow",               // Allow or Deny (Deny always wins)
      "Action": ["s3:GetObject"],       // scoped verb, NOT "s3:*"
      "Resource": "arn:aws:s3:::lab-reports-bucket/*", // one resource, NOT "*"
      "Condition": {                     // optional extra guardrails
        "Bool": { "aws:MultiFactorAuthPresent": "true" }
      }
    }
  ]
}

The read-only inspection commands you would use in an authorized account (all safe, non-mutating):

# WHO am I acting as right now? (confirms which principal a credential maps to)
aws sts get-caller-identity

# List policies attached to a role, then read one
aws iam list-attached-role-policies --role-name lab-app-role
aws iam get-policy-version --policy-arn <arn> --version-id v1

Key structural points: Action and Resource are where over-permissioning hides ("*" is the red flag); sts:AssumeRole in an Action list means the principal can become another role; iam:PassRole means it can hand a role to a service.

Lesson

Cloud platforms such as AWS, Azure, and GCP replace servers you own with on-demand services.

This changes the core security question. It is no longer "is the box patched?" but "who can do what?"

Shared responsibility

Responsibility is split between you and the provider:

  • The provider secures the cloud: hardware, the hypervisor (the software that runs virtual machines), and the internals of managed services.
  • You secure what is in the cloud: your configuration, data, access, and code.

Most cloud breaches come from customer-side misconfigurations, not provider failures.

IAM is the perimeter

Identity and Access Management (IAM) controls access in the cloud. It has two parts:

  • Principals: the identities that act, such as users, roles, and service accounts.
  • Policies: the rules that say which actions a principal may perform on which resources.

In the cloud there is no network edge to hide behind. Identity is the perimeter.

The failures that show up again and again:

  • Over-permissioned identities — for example, granting *:* or AdministratorAccess everywhere. One leaked key then becomes total compromise.
  • Long-lived access keys — used instead of short-lived role credentials.
  • Roles assumable by too-broad principals — opening the door to privilege escalation through iam:PassRole or role chaining (linking one role to another to gain more access).

Why testers focus here

Cloud penetration testing is mostly IAM analysis. The work is to:

  1. Enumerate identities and policies.
  2. Find over-grants (excess permissions).
  3. Map paths from a low-privileged principal up to admin.

This is the cloud version of Active Directory attack paths.

The fix is least privilege: scoped policies, short-lived credentials, and removing unused permissions.

Code examples

The example below shows the required INSECURE → SECURE → VERIFY shape using AWS IAM policy JSON and safe, read-only CLI checks. Run only in a lab account you own.

1. WARNING: intentionally vulnerable — use only in a local, isolated, authorized lab. Do not deploy.

An app role that was given far more than it needs:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "WayTooMuch",
      "Effect": "Allow",
      "Action": "*",
      "Resource": "*"
    }
  ]
}

Why it is dangerous: this role can do anything, including iam:CreateAccessKey, iam:AttachUserPolicy, and launching compute with iam:PassRole. If the app is hit by SSRF and its temporary credentials leak, the attacker owns the whole account. The insecure assumption is "the app is internal, so a broad grant is convenient." Convenience here equals total blast radius.

2. SECURE — least-privilege replacement

Grant only the two actions this app actually performs (read its reports bucket, write to one log group), scoped to named resources, and require the request originate from the app's VPC:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ReadReports",
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:ListBucket"],
      "Resource": [
        "arn:aws:s3:::lab-reports-bucket",
        "arn:aws:s3:::lab-reports-bucket/*"
      ]
    },
    {
      "Sid": "WriteOwnLogs",
      "Effect": "Allow",
      "Action": ["logs:CreateLogStream", "logs:PutLogEvents"],
      "Resource": "arn:aws:logs:us-east-1:111122223333:log-group:/lab/app:*"
    },
    {
      "Sid": "DenyIamEscalation",
      "Effect": "Deny",
      "Action": ["iam:*", "sts:AssumeRole"],
      "Resource": "*"
    }
  ]
}

The explicit Deny on iam:* and sts:AssumeRole is a belt-and-braces guard: even if a future edit accidentally adds an IAM allow, the Deny still wins.

3. VERIFY — prove the fix rejects bad input and accepts good input

AWS provides a dry-run simulator so you can test policies without performing the actions:

# GOOD path must be Allowed:
aws iam simulate-principal-policy \
  --policy-source-arn arn:aws:iam::111122223333:role/lab-app-role \
  --action-names s3:GetObject \
  --resource-arns arn:aws:s3:::lab-reports-bucket/report-1.pdf
# expected evalDecision: allowed

# BAD path must be Denied:
aws iam simulate-principal-policy \
  --policy-source-arn arn:aws:iam::111122223333:role/lab-app-role \
  --action-names iam:CreateAccessKey \
  --resource-arns arn:aws:iam::111122223333:user/admin
# expected evalDecision: explicitDeny

Expected output. The first call returns "EvalDecision": "allowed" for s3:GetObject; the second returns "EvalDecision": "explicitDeny" for iam:CreateAccessKey. Together they demonstrate the policy accepts the legitimate task and rejects the escalation attempt — the essence of a verified least-privilege fix. (111122223333 is AWS's documentation placeholder account id; the ARNs are illustrative.)

Line by line

Walking the secure policy and the verify step:

Step Line / element What happens Why it matters
1 "Version": "2012-10-17" Selects the current IAM policy language version Fixed date string; not "today" — using the wrong value silently changes how the doc is parsed
2 Sid: ReadReports, Effect: Allow Opens a statement that grants something Each statement is evaluated independently and combined
3 Action: [s3:GetObject, s3:ListBucket] Allows exactly two verbs Scoped — not s3:*, so delete/put are still denied by default
4 Resource: [bucket, bucket/*] Both the bucket and its objects ListBucket needs the bucket ARN; GetObject needs the /* object ARN — a classic off-by-one that breaks apps if you list only one
5 Sid: WriteOwnLogs Second Allow, one log group only The app can write telemetry but cannot read or delete other groups
6 Sid: DenyIamEscalation, Effect: Deny Explicitly forbids all iam:* and sts:AssumeRole Deny beats Allow in evaluation, so this blocks escalation even if a later Allow is added by mistake
7 simulate-principal-policy ... s3:GetObject Asks the engine to evaluate (not perform) the good action Returns allowed → legitimate work still functions
8 simulate-principal-policy ... iam:CreateAccessKey Evaluates the escalation action Returns explicitDeny → the attack path is closed

How the decision is reached (evaluation order): start deny-by-default → is there an explicit Deny? If yes → deny (step 8 hits the DenyIamEscalation statement). If no → is there an explicit Allow? If yes → allow (step 7 hits ReadReports). If no → implicit deny. That ordering is why adding the belt-and-braces Deny is safe and strong.

Common mistakes

Mistake 1 — "Decoding the role/token tells me it's safe."

  • WRONG: Base64-decoding a JWT or reading a role name and concluding it is low-privilege.
  • WHY WRONG: Decoding is not verifying, and a name is not a policy. ReadOnlyRole can carry iam:CreateAccessKey. Signature/authority checks and the actual attached policy are what matter.
  • CORRECTED: Read every attached and inline policy (list-attached-role-policies, get-policy-version) and simulate the sensitive actions.
  • RECOGNISE/PREVENT: If your judgement rests on a label or a decode, stop — pull the real policy.

Mistake 2 — Using "Action": "*" to "get it working."

  • WRONG: Granting admin to unblock a failing deploy, meaning to tighten later.
  • WHY WRONG: "Later" rarely comes; the broad grant becomes the account's biggest attack path and one leak = full compromise.
  • CORRECTED: Start from zero, add the specific failing action from the error message, re-test. Use the policy simulator to find the minimum set.
  • RECOGNISE/PREVENT: Grep policies for "*" in Action/Resource; alert on AdministratorAccess attachments.

Mistake 3 — Long-lived access keys in code or CI.

  • WRONG: A static AKIA... key committed to git or pasted in a pipeline variable.
  • WHY WRONG: It never expires, leaks widely, and is valid until manually revoked.
  • CORRECTED: Use short-lived role credentials (instance/OIDC roles); rotate and expire. Store any unavoidable secret in a secrets manager, never in source.
  • RECOGNISE/PREVENT: Secret-scanning on commits; alert on long-lived key creation; set key age limits.

Mistake 4 — "The scanner passed, so we're secure."

  • WRONG: Treating a clean automated IAM scan as proof of safety.
  • WHY WRONG: Scanners miss context-specific escalation chains (e.g. a benign-looking PassRole + RunInstances combo). A pass is not a proof; nothing is "completely secure."
  • CORRECTED: Combine tooling with manual attack-path mapping; document residual risk.
  • RECOGNISE/PREVENT: Never report "secure"; report "no paths found under these assumptions."

Mistake 5 — Forgetting ListBucket needs the bucket ARN.

  • WRONG: Granting s3:GetObject on bucket/* only, then wondering why listing fails.
  • WHY WRONG: GetObject acts on objects (/*); ListBucket acts on the bucket itself.
  • CORRECTED: Include both ARNs as in the secure example.
  • RECOGNISE/PREVENT: Match each action to the resource type it operates on.

Debugging tips

Common symptoms and what to check:

  • AccessDenied on a legitimate call. Read the full message — modern clouds name the missing action and the resource. Add exactly that action, scoped to that resource, then re-simulate. Do not jump to *.
  • explicitDeny even after adding an Allow. A Deny statement (in this policy, a permission boundary, an SCP/org policy, or a resource policy) is overriding you. Deny always wins — find and adjust the correct layer, don't pile on Allows.
  • Simulator says allowed but the real call fails. Check for conditions (MFA, source VPC/IP), a resource-based policy on the target (e.g. the bucket policy), or that your credential maps to the principal you think — run aws sts get-caller-identity first.
  • "It works for me but not the app." You and the app are different principals. Simulate against the app's role ARN, not your user.

Questions to ask when an IAM change misbehaves:

  1. Which principal is actually making the call? (get-caller-identity)
  2. Which action and resource ARN does the error name — exactly?
  3. Is there an explicit Deny, permission boundary, or org/SCP policy above me?
  4. Is a Condition (MFA, IP, VPC) unmet?
  5. Does the target resource have its own policy that must also allow me?

Safe debugging workflow: prefer non-mutating tools — simulate-principal-policy and get-caller-identity change nothing, so you can iterate on a policy in a lab without risk before applying it.

Memory safety

Security & safety — detection and logging for IAM.

IAM is invisible unless you log it. Capture the control-plane audit trail (AWS CloudTrail, Azure Activity/Entra sign-in logs, GCP Cloud Audit Logs) and, for each security-relevant event, record:

  • Timestamp (UTC) and a correlation / request id to tie related calls together.
  • Source: principal ARN/identity, source IP, user agent, and whether MFA was present.
  • Resource acted on (the ARN) and the action attempted.
  • Result / security decision: allowed vs denied, and why (which policy).

Events that signal abuse (watch and alert on these):

  • CreateAccessKey, CreateUser, AttachUserPolicy, PutUserPolicy — especially outside change windows.
  • AssumeRole chains, and any use of PassRole paired with compute launch (RunInstances, function create/update).
  • Spikes in AccessDenied from one principal (enumeration/brute-forcing permissions).
  • Console logins without MFA, logins from new geographies, or root-account use.
  • Disabling of logging itself (StopLogging, deleting a trail) — a top-priority alert.

Never log: passwords, access keys/secret keys, session tokens or cookies, private keys, MFA seeds, full payment card numbers (PANs), or unnecessary PII. Log that a credential was used and its identifier, never the secret material.

False positives arise from legitimate automation (CI creating short-lived sessions), a new admin onboarding, or a VPN changing a user's source IP. Baseline normal behaviour, tune alerts to context (who/when/how often), and route to a human before locking accounts — over-alerting trains responders to ignore the console, which is its own risk.

Real-world uses

Authorized real-world use case. A company hires you to assess its AWS account before a product launch. With written scope and read-only credentials, you enumerate roles and policies, find that a build role holds iam:PassRole plus ec2:RunInstances (a launch-as-admin escalation path) and that three developers still have long-lived keys over a year old. You report each with severity tied to exploitability and impact, propose scoped policies, and — crucially — hand over verification steps so the fix can be proven.

Professional best-practice habits:

  • Validation: confirm every request's action/resource is truly needed; simulate before granting.
  • Least privilege: default deny; scope by action, resource, and condition; expire credentials.
  • Secure defaults: MFA on humans, no root use, short-lived role credentials over static keys, deny public access unless explicitly justified.
  • Logging: enable and protect the audit trail; alert on the abuse signals above.
  • Error handling: deny safely (fail closed), and never leak why to untrusted callers while logging the full reason internally.
Beginner focus Advanced focus
IAM reading Spot "*" and admin grants; read one policy Map multi-step escalation chains across roles and accounts
Credentials Find and rotate long-lived keys Design OIDC/short-lived federation, permission boundaries, SCPs
Verification Run the policy simulator on one action Automated least-privilege tests in CI; detect drift
Detection Know which log records IAM changes Build alerts, baselines, and response runbooks

Authorization checklist (any lab or engagement): (1) written permission naming exact accounts/scope; (2) a lab you own or a sanctioned target (localhost, personal dev account, intentionally-vulnerable range, CTF) — never a third party; (3) agreed time window and rules of engagement; (4) read-only where possible; (5) a rollback/cleanup plan agreed in advance.

Practice tasks

All tasks are lab-only: use a personal, isolated cloud account (or a free-tier sandbox / intentionally-vulnerable practice range you control). Never test an account you do not own. Each ends by remediating and verifying.

Beginner 1 — Split the responsibility.

  • Objective: internalise the shared-responsibility line.
  • Requirements: for five items — hypervisor patching, S3 bucket ACLs, OS updates on a VM, the data centre's physical locks, your IAM policies — label each Provider or You, and give one sentence of reasoning.
  • Output: a 5-row table.
  • Concepts: shared responsibility, service models.
  • Hint: ask "could I change this in the console?" If yes, it is usually yours.

Beginner 2 — Spot the over-grant.

  • Objective: read a policy critically.
  • Requirements: given the insecure policy from the Code section, list every dangerous capability "Action": "*" implies (name at least three, e.g. iam:CreateAccessKey), and state the one-line insecure assumption behind the grant.
  • Output: a bullet list + the assumption.
  • Concepts: over-permissioning, blast radius.
  • Hint: think about what an attacker with this role's credentials could create.

Intermediate 1 — Write and simulate a least-privilege policy.

  • Objective: replace a broad grant with a scoped one and prove it.
  • Requirements: for an app that only reads objects from lab-reports-bucket, write an Allow-only policy; then use aws iam simulate-principal-policy (or your cloud's equivalent) to show s3:GetObject is allowed and s3:DeleteObject is denied.
  • Input/Output: policy JSON + two simulator decisions.
  • Constraints: no "*" in Action or Resource; read-only actions only.
  • Concepts: least privilege, verification, deny-by-default.
  • Hint: remember ListBucket needs the bucket ARN too.
  • Defensive conclusion: state which log event would confirm the app never attempts a denied action in production.

Intermediate 2 — Map one escalation path (analysis only).

  • Objective: recognise a privilege-escalation chain without exploiting it.
  • Requirements: given a low-priv user that can iam:PassRole an admin role and call ec2:RunInstances, describe in words how those two permissions combine into admin, then write the remediation (which permission to remove or scope) and the verification (simulator result proving the path is closed).
  • Output: a short chain description + fix + verify step.
  • Constraints: describe only; do not launch anything.
  • Concepts: PassRole, role chaining, remediation + verification.
  • Hint: the fix is usually scoping PassRole's Resource, not deleting RunInstances.
  • Defensive conclusion: name the log events (PassRole, RunInstances) an analyst would alert on.

Challenge — Least-privilege review with detection design.

  • Objective: perform a mini authorized review end-to-end.
  • Requirements: in your lab account, (1) enumerate roles and flag any with "*" or long-lived keys; (2) rewrite one over-permissive policy to least privilege; (3) verify with the simulator (good action allowed, dangerous action denied); (4) design a detection: list the exact audit-log events and the alert conditions that would catch abuse of the original permissions, and note two likely false positives.
  • Output: findings table (with severity tied to exploitability/impact), before/after policy, simulator evidence, and a short detection plan.
  • Constraints: lab-only; read-only enumeration; include a cleanup step.
  • Concepts: enumeration, least privilege, verification, detection/logging, reporting.
  • Defensive conclusion: finish with cleanup — delete any test role/policy you created and confirm the account is back to its starting state.

Lab cleanup / reset (all tasks): delete any test users, roles, policies, keys, or instances you created; confirm no long-lived keys remain (aws iam list-access-keys); and check the audit log shows your session ended. Leave the account as you found it.

Summary

Main concepts.

  • The shared-responsibility model splits security: the provider secures the cloud itself; you secure your configuration, data, and access. The line shifts by service model (IaaS → PaaS → SaaS), but you always own IAM and data.
  • IAM is the cloud's core control, built from principals (users, roles, service accounts) and policies (actions on resources, with conditions). With no network edge, identity is the perimeter — the exact idea the quiz points at.
  • The four failures behind most breaches: over-permissioning ("*"), long-lived keys, broadly-assumable roles, and iam:PassRole misuse. Attackers chain them into privilege-escalation paths.
  • The fix is least privilege: default deny; scope by action, resource, and condition; short-lived credentials.

Key syntax / commands. Policy JSON (Effect/Action/Resource/Condition, explicit Deny wins); aws sts get-caller-identity (who am I?); aws iam simulate-principal-policy (test allow/deny without acting).

Common mistakes. Trusting a role's name instead of its policy; decoding a token and calling it verified; "*" "to get it working"; committing long-lived keys; treating a passed scanner as proof of security (nothing is "completely secure").

What to remember. Ask "who can do what?", start from zero and add only what is needed, always verify the fix (good action allowed, dangerous action denied), log every IAM change (never the secrets themselves), and test only in accounts you own or are authorized to assess.