skip to content

Search

Syspirit
EN

AWS IAM

Users, roles, policies and Organizations: AWS permissions explained!

AWS
Published on
Karl Certa

AWS IAM (Identity and Access Management) is the service that controls who can authenticate to an AWS account and which actions each identity can perform on which resources.

🧱 IAM building blocks

📌 Element🎯 Role📊 Example
👑 Root userIdentity created with the account, full access to everything, billing includedAccount email address
👤 IAM userIdentity with long-term credentials (password, access keys)Third-party tool that cannot assume a role
👥 GroupSet of IAM users that receive the same policiesAdmins, Ops
🎭 RoleIdentity with no permanent credentials, assumed on demand with temporary credentialsApplication on AWS, partner account
📄 PolicyJSON (JavaScript Object Notation) document that allows or denies actionsReadOnlyAccess
🧩 PrincipalAuthenticated entity making the request: root, user, role, AWS serviceAudit role from another account
  • IAM is a global service: an identity or a policy applies in every Region of the account.
  • A group only contains users: groups cannot be nested, and a group cannot be used as a Principal in a policy, because it carries permissions without ever authenticating.
  • An assumed role replaces your permissions: during the session, the caller gives up its own permissions and only has those of the role.

🤔 Which identity for which need

📌 Need🔐 Mechanism to use💡 Why
👨‍💻 Humans across several accountsIAM Identity Center + permission setsTemporary credentials, central management
🖥️ Application running on AWSRole attached to the resourceAWS provides temporary credentials, no key to store
🔁 Access from one AWS account to anotherRole assumed through STS (Security Token Service)Short-lived, revocable, logged access
🤝 Third-party providerCross-account role + External IDNo key shared with the third party
🗄️ Open a single resource to another accountResource-based policy on the resourceNo role to assume
🧰 Third-party tool that cannot use rolesIAM user + access keysA case where AWS accepts long-term credentials
🚨 Emergency access if the identity provider is downBreak-glass IAM user with MFA (Multi-Factor Authentication)Recovery plan, tightly controlled credentials
🧑‍🔧 Let a team create its own rolesPermissions boundaryCaps the permissions those roles can get

👑 Root user and best practices

📌 Rule🧭 Mechanism and consequence
🔒 MFA on the root userSecond factor on top of the password; AWS requires it for every account type, with a 35-day grace period after the first sign-in
🚫 No root access keysRoot has access to everything, billing included: a leaked key hands over the whole account
🧑‍💼 No root for daily workKept for the few tasks that require it; an administrative user handles the rest
📧 Group email addressIf AWS contacts the owner, the response does not depend on a single person
🏢 Member accounts of an organizationRoot credentials (password, keys, MFA) can be removed centrally
🎯 Least privilegeGrant only the needed actions on the needed resources; start from AWS policies, then tighten with IAM Access Analyzer
🧹 Regular reviewLast accessed data shows unused users, roles and keys to remove

📄 JSON policy structure

📌 Element🎯 Role📊 Values
VersionPolicy language version"2012-10-17"
StatementOne or more rulesObject or array
SidOptional rule label"ReadBucketOffice"
EffectAllow or denyAllow, Deny
ActionTargeted API (Application Programming Interface) calls, prefixed by the services3:GetObject, ec2:Describe*
ResourceARN (Amazon Resource Name) of the targeted resourcesarn:aws:s3:::amzn-s3-demo-bucket/*
ConditionContext required for the rule to applySource IP (Internet Protocol), Region, tag, MFA
PrincipalWho is targeted; only in a resource-based policy or a trust policyAccount, role, AWS service

Identity-based policy that allows reading objects from an S3 (Simple Storage Service) bucket, only from a public IP address range:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ReadBucketOffice",
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*",
      "Condition": {
        "IpAddress": { "aws:SourceIp": "203.0.113.0/24" }
      }
    }
  ]
}

No Principal here: in an identity-based policy, the principal is implicitly the identity the policy is attached to. The aws:SourceIp key only works with public IP addresses.

🆚 Identity-based vs resource-based

📌 Criterion👤 Identity-based policy🗄️ Resource-based policy
Attached toUser, group or roleResource: S3 bucket, KMS (Key Management Service) key, SQS (Simple Queue Service) queue, role
Question answeredWhat can this identity do?Who can act on this resource?
Principal fieldNot allowedRequired
ExamplesAdministratorAccess, custom policyBucket policy, key policy, role trust policy
📌 Identity-based policy type🛠️ Managed by🔁 Reusable💡 Usage
AWS managedAWS, which updates itYes, cannot be editedStarting point, often too broad
Customer managedYouYes, across several identitiesStandard case, tailored to the need
InlineYouNo, tied to one identity and deleted with itStrict one-to-one relationship

⚖️ Evaluation logic

Rules applied to every request within a single account. Documented order: explicit deny, RCP (Resource Control Policy), SCP (Service Control Policy), resource-based, identity-based, permissions boundary, session policy.

📌 Rule🧭 Mechanism
🚫 Implicit deny by defaultWithout an applicable Allow, the request is denied (only the root user has full access by default)
⛔ Explicit deny winsA single applicable Deny, in any policy type, overrides every Allow
🏢 SCP and RCPAn Allow is needed at every level of the organization, otherwise denied even with AdministratorAccess
➕ Identity-based and resource-basedUnion: an Allow in either one is enough (except role trust policies and KMS key policies, which must allow explicitly)
✂️ Permissions boundaryIntersection with identity-based policies: the action must be allowed on both sides
🎫 Session policyFilter passed during AssumeRole; the session never exceeds the role’s permissions

Cross-account request: a principal in account A (trusted) accesses a resource in account B (trusting).

📌 Side evaluated🔍 Policies checked📊 Requirement
Account A, where the request comes fromPrincipal’s identity-based policy and what limits it (boundary, SCP)Must return Allow
Account B, owner of the resourceResource-based policy naming A’s principal and what limits it (RCP)Must return Allow
Final decisionBoth evaluationsAllow only if both sides allow

🎭 Roles and STS

📌 Element🎯 Role
Trust policyResource-based policy of the role: who is allowed to assume it
Permissions policyIdentity-based policy of the role: what the session can do
sts:AssumeRoleReturns a temporary access key, secret key and session token
Service roleRole an AWS service assumes to act on your behalf, editable by the admin
Service-linked roleRole linked to and owned by a service: permissions visible but not editable
Role chainingAssuming a second role with the session of the first one
📌 AssumeRole session duration📊 Value
Default1 hour (3600 s)
Minimum15 minutes (900 s)
Maximum set on the roleFrom 1 to 12 hours
With role chaining1 hour maximum, whatever the role setting
  • Cross-account with a role: the trust policy in account B names account A, and the identity in A needs a policy that allows sts:AssumeRole on the role ARN.
  • External ID: identifier provided by the third party and required by the sts:ExternalId condition of the trust policy, so that another of its customers cannot make it assume your role (the “confused deputy” problem).

🏢 AWS Organizations

📌 Element🎯 Role
Management accountCreates the organization, pays the bill, attaches policies; cannot be changed later
Member accountBelongs to only one organization at a time
RootContainer at the top of the hierarchy, created automatically (unrelated to the root user)
OU (Organizational Unit)Group of accounts or OUs, up to 5 levels under the root; policies are inherited
Delegated administratorMember account that manages a service or policies instead of the management account
📌 Criterion👤 SCP🗄️ RCP
What is cappedPermissions of users and roles in member accounts, member root includedPermissions on resources in member accounts, whoever the caller, even external
Typical useDeny Regions that are not approvedBlock access to resources from outside the organization
Services coveredAll, apart from a few documented exceptionsA defined list: S3, STS, KMS, SQS, Secrets Manager, etc.
Default policyFullAWSAccess, replaceableRCPFullAWSAccess, cannot be detached
Maximum attached per root, OU or account105
Key dateFull IAM language since September 2025Launched in November 2024

🔑 IAM Identity Center

Successor of AWS SSO (Single Sign-On), renamed in July 2022: a single portal gives people access to their accounts and applications, from one identity source per organization (built-in directory, Active Directory or an external provider such as Okta or Microsoft Entra ID).

A permission set is a policy template: when assigned, Identity Center creates the matching IAM role in each target account. The session lasts 1 hour by default, 12 hours at most.

Related posts