Users, roles, policies and Organizations: AWS permissions explained!
AWS
Published on
Karl Certa Systems & network administrator5 years in IT, from support to sysadmin, now Ops. Learning cloud, and writing everything down here. Focused on IaC & cloud AWS SAA, Kubernetes next LinkedIn karlcerta.fr GitHub 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 user
Identity created with the account, full access to everything, billing included
Account email address
👤 IAM user
Identity with long-term credentials (password, access keys)
Third-party tool that cannot assume a role
👥 Group
Set of IAM users that receive the same policies
Admins, Ops
🎭 Role
Identity with no permanent credentials, assumed on demand with temporary credentials
Application on AWS, partner account
📄 Policy
JSON (JavaScript Object Notation) document that allows or denies actions
ReadOnlyAccess
🧩 Principal
Authenticated entity making the request: root, user, role, AWS service
Audit 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 accounts
IAM Identity Center + permission sets
Temporary credentials, central management
🖥️ Application running on AWS
Role attached to the resource
AWS provides temporary credentials, no key to store
🔁 Access from one AWS account to another
Role assumed through STS (Security Token Service)
Short-lived, revocable, logged access
🤝 Third-party provider
Cross-account role + External ID
No key shared with the third party
🗄️ Open a single resource to another account
Resource-based policy on the resource
No role to assume
🧰 Third-party tool that cannot use roles
IAM user + access keys
A case where AWS accepts long-term credentials
🚨 Emergency access if the identity provider is down
Break-glass IAM user with MFA (Multi-Factor Authentication)
Recovery plan, tightly controlled credentials
🧑🔧 Let a team create its own roles
Permissions boundary
Caps the permissions those roles can get
👑 Root user and best practices
📌 Rule
🧭 Mechanism and consequence
🔒 MFA on the root user
Second 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 keys
Root has access to everything, billing included: a leaked key hands over the whole account
🧑💼 No root for daily work
Kept for the few tasks that require it; an administrative user handles the rest
📧 Group email address
If AWS contacts the owner, the response does not depend on a single person
🏢 Member accounts of an organization
Root credentials (password, keys, MFA) can be removed centrally
🎯 Least privilege
Grant only the needed actions on the needed resources; start from AWS policies, then tighten with IAM Access Analyzer
🧹 Regular review
Last accessed data shows unused users, roles and keys to remove
📄 JSON policy structure
📌 Element
🎯 Role
📊 Values
Version
Policy language version
"2012-10-17"
Statement
One or more rules
Object or array
Sid
Optional rule label
"ReadBucketOffice"
Effect
Allow or deny
Allow, Deny
Action
Targeted API (Application Programming Interface) calls, prefixed by the service
s3:GetObject, ec2:Describe*
Resource
ARN (Amazon Resource Name) of the targeted resources
arn:aws:s3:::amzn-s3-demo-bucket/*
Condition
Context required for the rule to apply
Source IP (Internet Protocol), Region, tag, MFA
Principal
Who is targeted; only in a resource-based policy or a trust policy
Account, role, AWS service
Identity-based policy that allows reading objects from an S3 (Simple Storage Service) bucket, only from a public IP address range:
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.
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 default
Without an applicable Allow, the request is denied (only the root user has full access by default)
⛔ Explicit deny wins
A single applicable Deny, in any policy type, overrides every Allow
🏢 SCP and RCP
An Allow is needed at every level of the organization, otherwise denied even with AdministratorAccess
➕ Identity-based and resource-based
Union: an Allow in either one is enough (except role trust policies and KMS key policies, which must allow explicitly)
✂️ Permissions boundary
Intersection with identity-based policies: the action must be allowed on both sides
🎫 Session policy
Filter 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 from
Principal’s identity-based policy and what limits it (boundary, SCP)
Must return Allow
Account B, owner of the resource
Resource-based policy naming A’s principal and what limits it (RCP)
Must return Allow
Final decision
Both evaluations
Allow only if both sides allow
🎭 Roles and STS
📌 Element
🎯 Role
Trust policy
Resource-based policy of the role: who is allowed to assume it
Permissions policy
Identity-based policy of the role: what the session can do
sts:AssumeRole
Returns a temporary access key, secret key and session token
Service role
Role an AWS service assumes to act on your behalf, editable by the admin
Service-linked role
Role linked to and owned by a service: permissions visible but not editable
Role chaining
Assuming a second role with the session of the first one
📌 AssumeRole session duration
📊 Value
Default
1 hour (3600 s)
Minimum
15 minutes (900 s)
Maximum set on the role
From 1 to 12 hours
With role chaining
1 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 account
Creates the organization, pays the bill, attaches policies; cannot be changed later
Member account
Belongs to only one organization at a time
Root
Container 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 administrator
Member account that manages a service or policies instead of the management account
📌 Criterion
👤 SCP
🗄️ RCP
What is capped
Permissions of users and roles in member accounts, member root included
Permissions on resources in member accounts, whoever the caller, even external
Typical use
Deny Regions that are not approved
Block access to resources from outside the organization
Services covered
All, apart from a few documented exceptions
A defined list: S3, STS, KMS, SQS, Secrets Manager, etc.
Default policy
FullAWSAccess, replaceable
RCPFullAWSAccess, cannot be detached
Maximum attached per root, OU or account
10
5
Key date
Full IAM language since September 2025
Launched 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.