AWS IAM for Enterprises: Architecture, Implementation, and Hardening Guide
Prerequisites
- Basic AWS account and IAM knowledge
- AWS CLI configured with administrative access
Steps
AWS Identity and Access Management (IAM) is the control plane for authentication and authorization across AWS accounts, workloads, and human users. This guide explains enterprise IAM architecture, implementation steps, hardening patterns, troubleshooting, and how IAM compares with Microsoft Entra ID and Okta.
Overview
AWS Identity and Access Management (IAM) is the native AWS service for controlling who can authenticate and what actions they can perform on AWS resources. Enterprises use IAM to enforce least privilege, separate duties, integrate workforce identities, and standardize access across multi-account environments.
IAM evaluates requests using policies attached to users, groups, roles, and resources. In enterprise deployments, IAM is rarely used as a standalone identity store for employees; instead, organizations commonly federate from an external IdP such as Microsoft Entra ID or Okta into AWS IAM Identity Center and IAM roles.
Architecture
Core components
- IAM users: Long-term identities, typically avoided for workforce access.
- IAM groups: Collections of users with shared permissions.
- IAM roles: Assumable identities for humans, workloads, and cross-account access.
- Policies: JSON documents defining allowed or denied actions.
- IAM Identity Center: Centralized workforce access across AWS Organizations accounts.
- AWS Organizations + SCPs: Guardrails that limit the maximum available permissions.
Deployment models
- Single account: Suitable for small teams, but weak for enterprise separation.
- Multi-account landing zone: Recommended; use Organizations, dedicated security/shared services accounts, and role-based access.
- Federated workforce model: External IdP authenticates users, AWS authorizes via permission sets and roles.
Data flow
- User authenticates with external IdP.
- IdP sends SAML/OIDC assertion to IAM Identity Center or STS.
- AWS issues temporary credentials.
- Request is evaluated against SCPs, session policies, identity policies, resource policies, and explicit denies.
Implementation Guide
1. Create a customer-managed policy
cat > s3-readonly-prod.json <<'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListBucket",
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": "arn:aws:s3:::prod-finance-reports"
},
{
"Sid": "ReadObjects",
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::prod-finance-reports/*"
}
]
}
EOF
aws iam create-policy --policy-name S3ReadOnlyProdFinance --policy-document file://s3-readonly-prod.json
2. Create a role with a trust policy for EC2
cat > ec2-trust-policy.json <<'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"Service": "ec2.amazonaws.com"},
"Action": "sts:AssumeRole"
}
]
}
EOF
aws iam create-role --role-name AppServerS3ReadRole --assume-role-policy-document file://ec2-trust-policy.json
aws iam attach-role-policy --role-name AppServerS3ReadRole --policy-arn arn:aws:iam::123456789012:policy/S3ReadOnlyProdFinance
aws iam create-instance-profile --instance-profile-name AppServerProfile
aws iam add-role-to-instance-profile --instance-profile-name AppServerProfile --role-name AppServerS3ReadRole
3. Enable account password policy and auditing
aws iam update-account-password-policy --minimum-password-length 14 --require-symbols --require-numbers --require-uppercase-characters --require-lowercase-characters --max-password-age 90 --password-reuse-prevention 24
aws iam generate-credential-report
aws iam get-credential-report --query 'Content' --output text | base64 --decode > credential-report.csv
4. Example IAM policy validation in CI
aws accessanalyzer validate-policy --policy-document file://s3-readonly-prod.json --policy-type IDENTITY_POLICY
Code Examples
Example 1: Cross-account trust policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::210987654321:role/SecurityAuditRole"},
"Action": "sts:AssumeRole",
"Condition": {"StringEquals": {"sts:ExternalId": "audit-2026-enterprise"}}
}
]
}
Example 2: Terraform role creation
resource "aws_iam_role" "lambda_exec" {
name = "lambda-exec-prod"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Service = "lambda.amazonaws.com" }
Action = "sts:AssumeRole"
}]
})
}
resource "aws_iam_role_policy_attachment" "basic" {
role = aws_iam_role.lambda_exec.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}
Example 3: Boto3 role assumption
import boto3
sts = boto3.client("sts")
resp = sts.assume_role(RoleArn="arn:aws:iam::123456789012:role/SecurityAuditRole", RoleSessionName="audit-session")
print(resp["Credentials"]["AccessKeyId"])
Security Hardening
- Prefer federation and temporary credentials over IAM users and static keys.
- Enforce MFA for privileged roles and console access.
- Use SCPs to block risky services or regions, for example denying
iam:CreateAccessKeyoutside break-glass workflows. - Restrict trust policies with
aws:PrincipalOrgID,sts:ExternalId, source IP, or tags where appropriate. - Rotate and eliminate legacy access keys; monitor with credential reports.
- Encrypt downstream data with KMS, and tightly control
kms:Decryptpermissions because IAM alone does not protect data usage. - Enable CloudTrail, AWS Config, Access Analyzer, and GuardDuty for visibility and continuous assurance.
Comparison
| Feature | AWS IAM | Microsoft Entra ID | Okta |
|---|---|---|---|
| Pricing | Included for core IAM; related services billed separately | Per-user licensing tiers | Per-user licensing tiers |
| Deployment | Native AWS service | Cloud IdP with deep Microsoft integration | Cloud IdP with broad SaaS integration |
| Scalability | Excellent across AWS multi-account estates | Excellent for workforce identity | Excellent for workforce identity |
| Security | Fine-grained AWS authorization, SCPs, STS, resource policies | Strong conditional access and identity governance | Strong SSO, lifecycle, adaptive MFA |
| Best fit | AWS-native authorization and workload access | Enterprise workforce identity | Cross-platform workforce identity |
Troubleshooting
1. Access denied on AssumeRole
Log sample:
An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:sts::123456789012:assumed-role/Admin/user@example.com is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::210987654321:role/SecurityAuditRole
Fix: Verify both sides: caller identity policy must allow sts:AssumeRole, and target role trust policy must trust the caller.
2. Explicit deny from SCP
Log sample:
User: arn:aws:sts::123456789012:assumed-role/DevOps/admin is not authorized to perform: iam:CreateUser because no service control policy allows the iam:CreateUser action
Fix: Review effective SCPs in AWS Organizations; identity policy alone cannot override an SCP deny.
3. Invalid principal in policy
Log sample:
An error occurred (MalformedPolicyDocument) when calling the UpdateAssumeRolePolicy operation: Invalid principal in policy: "AWS":"arn:aws:iam::999999999999:role/OldRole"
Fix: Confirm the referenced account and role exist and have not been deleted; update stale trust relationships.
Best Practices
Do
- Use roles per workload instead of shared credentials.
- Tag roles and enforce ABAC where business units map cleanly to tags.
- Separate admin, audit, and break-glass access.
- Validate policies before deployment with Access Analyzer.
Don't
- Do not attach
AdministratorAccessbroadly to developer roles. - Do not embed access keys in EC2 user data, Lambda environment variables, or CI secrets when roles are available.
- Do not rely on inline policies as your primary governance model; prefer versioned customer-managed policies.
- Do not ignore resource policies on S3, KMS, SQS, and SNS, because effective access is the combination of identity and resource controls.
Have a project in mind?
Get an instant AI price estimate for it, or talk directly to our team.
One email a month on what we learn building with AI