DevOps.Academy
CoursesCurriculumPricing

    Loading…

    ↑ ↓ move · ↵ open · Ctrl K anywhere

    ◔My learningSign in
    DevOps.Academy

    Free, hands-on DevOps lessons. Made with care in India.

    Learn

    All coursesLinux roadmapCurriculumMy learning

    Academy

    PricingCertificates

    Legal

    PrivacyTermsContact

    devops.rajeev.pro

    AWS for DevOpsLesson 2 of 17
    Your progress · 0%
    On this page
    1. Every request asks one question
    2. Reading a policy
    3. Users and groups
    4. MFA
    5. Access keys
    6. Roles and temporary credentials
    7. Prove it: the policy simulator
    8. Guard rails for bigger teams
    9. IAM Identity Center is the human access portal
    10. ABAC uses tags as a permission condition
    ↖ Course roadmap
    Lesson 2 · IAM

    IAM: who can do what

    Users, groups, policies and roles, clicked through in the real console: write a least-privilege policy, give it to a group, add a user, set up MFA and prove what the user can and cannot do.

    35 min read · intermediate · hands-on

    By the end of this lesson you'll be able to

    0 of 6 complete

    Every request asks one question

    Every click in the console and every aws command is an API request, and IAM answers one question for each one: is this identity allowed to do this action on this resource? The default answer is no.

    PieceWhat it isExample
    Usera person or app with long-term credentialsdemo-dev
    Groupa set of users that share permissionsdevelopers
    Rolean identity anyone trusted can assume for a while, with temporary credentialsan EC2 server, a CI job, an admin from another account
    Policya JSON document listing what's allowed or deniedacademy-s3-read

    Find out who you are right now:

    $ aws sts get-caller-identity
    {
        "UserId": "AIDA…",
        "Account": "111122223333",
        "Arn": "arn:aws:iam::111122223333:user/anythinkX"
    }
    
    aws sts get-caller-identity
    • awsthe AWS command line

    The screenshots and outputs in this lesson come from a real practice account. The account ID is replaced with 111122223333, the example ID AWS uses in its own documentation, and other users' names are blurred.

    Reading a policy

    This policy lets someone list buckets and read objects, and nothing else:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "ReadOnlyS3",
          "Effect": "Allow",
          "Action": ["s3:ListAllMyBuckets", "s3:ListBucket", "s3:GetObject"],
          "Resource": "*"
        }
      ]
    }
    
    FieldMeaning
    EffectAllow or Deny
    ActionAPI calls, as service:Action; wildcards like s3:Get* work
    Resourcewhich things, by ARN: arn:aws:s3:::my-bucket/*; * means all
    Conditionoptional extra rules: source IP, MFA present, tags, time

    Three rules decide every request: everything is denied by default, an Allow opens it, and an explicit Deny beats any Allow.

    Policies come in three kinds: AWS managed (written by AWS, like AmazonS3ReadOnlyAccess), customer managed (yours, reusable, versioned) and inline (stuck to one identity; avoid them). The ones above are identity-based: attached to a user, group or role. Resource-based policies, such as an S3 bucket policy, sit on the resource and say who may use it.

    Create it in the console

    IAM → Policies → Create policy opens the policy editor. Switch from Visual to JSON and paste the policy:

    (1) Switch the editor to JSON and paste the policy. (2) Next, to name and review it.© Screenshot: DevOps Academy

    (1) Switch the editor to JSON and paste the policy. (2) Next, to name and review it.© Screenshot: DevOps Academy

    Click Next, name it academy-s3-read, add a description and Create policy. Its page shows what it allows, in plain words:

    The summary reads the JSON for you: S3 only, List and Read only.© Screenshot: DevOps Academy

    The summary reads the JSON for you: S3 only, List and Read only.© Screenshot: DevOps Academy

    The same from the CLI:

    $ aws iam create-policy --policy-name academy-s3-read --policy-document file://pol.json
    
    aws iam create-policy --policy-name academy-s3-read --policy-document file://pol.json
    • awsthe AWS command line

    Users and groups

    Give permissions to groups, then put users in them. When someone changes team, you move them between groups instead of editing policies person by person.

    IAM → User groups → Create group: name it developers, search for academy-s3-read and tick it.

    (1) Name the group. (2) Search for and tick academy-s3-read. (3) Create user group. Adding users here is optional.© Screenshot: DevOps Academy

    (1) Name the group. (2) Search for and tick academy-s3-read. (3) Create user group. Adding users here is optional.© Screenshot: DevOps Academy

    Created. 0 users so far, permissions Defined.© Screenshot: DevOps Academy

    Created. 0 users so far, permissions Defined.© Screenshot: DevOps Academy

    Now the user. IAM → Users → Create user, three steps:

    (1) The user name. (2) Console access stays off for this demo. (3) Next.© Screenshot: DevOps Academy

    (1) The user name. (2) Console access stays off for this demo. (3) Next.© Screenshot: DevOps Academy

    (1) Add user to group. (2) Tick developers, which already carries the policy. (3) Next.© Screenshot: DevOps Academy

    (1) Add user to group. (2) Tick developers, which already carries the policy. (3) Next.© Screenshot: DevOps Academy

    (1) Check the user gets its permissions from the developers group. (2) Create user.© Screenshot: DevOps Academy

    (1) Check the user gets its permissions from the developers group. (2) Create user.© Screenshot: DevOps Academy

    From the CLI it's two commands:

    $ aws iam create-user --user-name demo-dev
    $ aws iam add-user-to-group --user-name demo-dev --group-name developers
    
    aws iam create-user --user-name demo-dev
    • awsthe AWS command line

    MFA

    A password alone is one phishing email away from gone. Multi-factor authentication adds a code from a device you hold. Open the user, Security credentials tab:

    (1) Assign MFA device starts the MFA setup. (2) Access keys: 0, the safest number.© Screenshot: DevOps Academy

    (1) Assign MFA device starts the MFA setup. (2) Access keys: 0, the safest number.© Screenshot: DevOps Academy

    Assign MFA device asks for a name and the type:

    (1) Name the device. (2) Authenticator app is the common choice; a passkey or security key resists phishing better.© Screenshot: DevOps Academy

    (1) Name the device. (2) Authenticator app is the common choice; a passkey or security key resists phishing better.© Screenshot: DevOps Academy

    Step 2 shows a QR code: scan it with an authenticator app and type two codes in a row. Do it first for the root user (the email you signed up with), then for every human user. The account summary tells you whether root has it:

    $ aws iam get-account-summary --query 'SummaryMap.{Users:Users,MFADevices:MFADevices,AccountMFAEnabled:AccountMFAEnabled}'
    {
        "Users": 2,
        "MFADevices": 2,
        "AccountMFAEnabled": 1
    }
    
    aws iam get-account-summary --query 'SummaryMap.{Users:Users,MFADevices:MFADevices,AccountMFAEnabled:AccountMFAEnabled}'
    • awsthe AWS command line
    • --querypick fields from the JSON response

    AccountMFAEnabled: 1 means the root user has MFA.

    Access keys

    An access key (an ID starting AKIA plus a secret) lets the CLI and SDKs act as a user. It never expires on its own, so it's the credential that leaks most: committed to git, baked into an image, pasted in a chat.

    • Prefer no keys: humans use IAM Identity Center (aws sso login), servers and CI use roles.
    • If you must have one, one per person, never for root, stored by aws configure (not in code), and rotated: create a new key, switch to it, deactivate the old one, delete it.
    • A key that leaked is a key to delete now, not later: bots scan public GitHub for AKIA within minutes.

    Roles and temporary credentials

    A role has no password or keys. Something it trusts assumes it and gets credentials that expire, usually after an hour. Assume a role from the CLI:

    $ aws sts assume-role --role-arn arn:aws:iam::111122223333:role/academy-console --role-session-name lesson-demo \
        --query '{Arn:AssumedRoleUser.Arn,Expires:Credentials.Expiration}'
    {
        "Arn": "arn:aws:sts::111122223333:assumed-role/academy-console/lesson-demo",
        "Expires": "2026-10-17T09:09:02+00:00"
    }
    
    aws sts assume-role --role-arn arn:aws:iam::111122223333:role/academy-console --role-session-name lesson-demo \
    • awsthe AWS command line

    Every role has two policies: the trust policy (who may assume it) and permissions policies (what it can do once assumed). The console's Create role starts with the trust side:

    (1) Who may use the role: here an AWS service. (2) Which one, such as EC2. This is the role's trust policy.© Screenshot: DevOps Academy

    (1) Who may use the role: here an AWS service. (2) Which one, such as EC2. This is the role's trust policy.© Screenshot: DevOps Academy
    Trusted entityReal use
    AWS service → EC2an instance profile: the app on the server gets credentials from the instance, no keys on disk (lesson 3)
    AWS accountcross-account access: admins in a security account assume a role in production
    Web identityOIDC for CI/CD: GitHub Actions assumes a role for one job, no stored AWS keys (the CI/CD course)
    SAML 2.0a company login (Okta, Entra ID) mapped to AWS roles

    Prove it: the policy simulator

    Don't guess what a policy allows: test it. The policy simulator evaluates real policies without making the calls:

    $ aws iam simulate-principal-policy --policy-source-arn arn:aws:iam::111122223333:user/demo-dev \
        --action-names s3:GetObject s3:PutObject s3:DeleteBucket ec2:RunInstances \
        --query 'EvaluationResults[].[EvalActionName,EvalDecision]' --output table
    --------------------------------------
    |       SimulatePrincipalPolicy      |
    +-------------------+----------------+
    |  s3:GetObject     |  allowed       |
    |  s3:PutObject     |  implicitDeny  |
    |  s3:DeleteBucket  |  implicitDeny  |
    |  ec2:RunInstances |  implicitDeny  |
    +-------------------+----------------+
    
    aws iam simulate-principal-policy --policy-source-arn arn:aws:iam::111122223333:user/demo-dev \
    • awsthe AWS command line

    demo-dev can read objects and nothing else. Least privilege is exactly this: start with nothing and allow only what the job needs. IAM Access Analyzer helps keep it that way: it finds resources shared outside the account and permissions nobody has used for months.

    Guard rails for bigger teams

    IAM Identity Center is the human access portal

    IAM users are a poor fit for a team: each account grows another password and another long-lived key. IAM Identity Center gives a person one sign-in portal, then assigns a permission set to a role in each account. The role supplies temporary credentials, so removing access means removing the assignment rather than hunting for keys. Use it for workforce access; keep IAM roles for workloads.

    In the console, open IAM Identity Center → Settings and read the enable page and settings page. Do not press Enable. A read-only CLI check, when an organization already has an instance, is:

    $ aws sso-admin list-instances --region ap-south-1 \
        --query 'Instances[].{Status:Status,IdentityStore:IdentityStoreId}' --output table
    
    aws sso-admin list-instances --region ap-south-1 \
    • awsthe AWS command line
    • --regionwhich Region

    Permission sets are reusable policy bundles. Assign one to a group and account, then let the person use the access portal for temporary credentials.

    ABAC uses tags as a permission condition

    Attribute-based access control compares a principal tag with a resource tag. It scales better than one policy per team, but only if tag changes are restricted and audited:

    {"Effect":"Allow","Action":"ec2:StopInstances","Resource":"*","Condition":{"StringEquals":{"ec2:ResourceTag/Project":"${aws:PrincipalTag/Project}"}}}
    

    Use fixed resource ARNs for a small, high-risk set where the boundary must be obvious.

    • IAM Identity Center (SSO): one login for people across all your accounts, with temporary credentials instead of IAM users. AWS recommends it for human access.
    • AWS Organizations: many accounts (dev, staging, prod, security) under one bill, so a mistake in dev can't touch prod.
    • Service control policies (SCPs): an organisation-wide ceiling: even an admin in a member account can't do what an SCP denies, such as leaving approved Regions or turning off CloudTrail.
    • Permission boundaries: a ceiling on one user or role, so you can let a team create roles without letting them create something more powerful than themselves.
    Lock the root user away

    The root user can do everything, including closing the account, and no policy can limit it. Give it MFA and a strong unique password, delete any root access keys, and use it only for the few tasks that need it, such as changing the account's support plan.

    In production

    People sign in through IAM Identity Center with MFA, workloads use roles, CI uses OIDC, and long-lived access keys are the rare exception, rotated and monitored. Review unused permissions with Access Analyzer every few months, and keep separate accounts for production.

    ⌘
    Mini mission

    A least-privilege developer

    In your own account, create the academy-s3-read policy, a developers group with it attached and a demo-dev user in the group, following the screenshots. Prove with the policy simulator that demo-dev can read S3 objects but not write them or start servers, then delete everything you created.

    Input: An AWS account where you can use IAM, with the AWS CLI configuredOutput: A simulator table with allowed for s3:GetObject and implicitDeny for the rest, then no demo-dev, developers or academy-s3-read left
    Reveal one safe solution
    $ printf '%s\n' '{"Version":"2012-10-17","Statement":[{"Sid":"ReadOnlyS3","Effect":"Allow","Action":["s3:ListAllMyBuckets","s3:ListBucket","s3:GetObject"],"Resource":"*"}]}' > pol.json
    $ ACC=$(aws sts get-caller-identity --query Account --output text)
    $ aws iam create-policy --policy-name academy-s3-read --policy-document file://pol.json
    $ aws iam create-group --group-name developers
    $ aws iam attach-group-policy --group-name developers --policy-arn arn:aws:iam::$ACC:policy/academy-s3-read
    $ aws iam create-user --user-name demo-dev
    $ aws iam add-user-to-group --user-name demo-dev --group-name developers
    $ aws iam simulate-principal-policy --policy-source-arn arn:aws:iam::$ACC:user/demo-dev \
        --action-names s3:GetObject s3:PutObject ec2:RunInstances \
        --query 'EvaluationResults[].[EvalActionName,EvalDecision]' --output text
    s3:GetObject	allowed
    s3:PutObject	implicitDeny
    ec2:RunInstances	implicitDeny
    $ aws iam remove-user-from-group --user-name demo-dev --group-name developers
    $ aws iam delete-user --user-name demo-dev
    $ aws iam detach-group-policy --group-name developers --policy-arn arn:aws:iam::$ACC:policy/academy-s3-read
    $ aws iam delete-group --group-name developers
    $ aws iam delete-policy --policy-arn arn:aws:iam::$ACC:policy/academy-s3-read
    
    printf '%s\n' '{"Version":"2012-10-17","Statement":[{"Sid":"ReadOnlyS3","Effect":"Allow","Action":["s3:ListAllMyBuckets","s3:ListBucket","s3:GetObject"],"Resource":"*"}]}' > pol.json
    • >write output to a file, replacing it
    aws iam create-policy --policy-name academy-s3-read --policy-document file://pol.json
    • awsthe AWS command line

    IAM is free, so this costs nothing. The order of the clean-up matters: a group with members, or a policy still attached, can't be deleted.

    Try it yourself

    0 of 6 steps done

    Run each task in your own account or terminal, then tick it off.

    Knowledge check

    Quick check

    Question 1 of 5

    A new developer needs read access to S3. What is the best way to give it?

    Go deeper

    Official reading for this lesson

    • DocsIAM user guideAWS Docs ↗
    • DocsSecurity best practices in IAMAWS Docs ↗
    • DocsPolicy evaluation logicAWS Docs ↗
    • DocsIAM rolesAWS Docs ↗
    • DocsAWS IAM Identity CenterAWS Docs ↗

    Or get every quiz answer right and it completes itself.

    ← PreviousCloud basics: what you're actually rentingNext lesson →EC2: your first server in the cloud