Granting Read-Only AWS Console Access: The Right IAM Policy for Junior Developers
Onboarding a new junior developer to your AWS environment is a common scenario — but handing them full access is a security risk you cannot afford. The principle of least privilege demands you give them exactly what they need: the ability to see resources, never to change them.
TL;DR
| Goal | AWS Managed Policy | ARN |
|---|---|---|
| Read-only access to ALL AWS services | ReadOnlyAccess | arn:aws:iam::aws:policy/ReadOnlyAccess |
| View billing & cost data only | AWSBillingReadOnlyAccess | arn:aws:iam::aws:policy/AWSBillingReadOnlyAccess |
| View IAM resources only | IAMReadOnlyAccess | arn:aws:iam::aws:policy/IAMReadOnlyAccess |
The primary policy you want is ReadOnlyAccess — an AWS managed policy that grants List*, Get*, Describe*, and View* actions across virtually all AWS services, with zero write permissions.
Architecture: What We're Building
The flow is straightforward: create a dedicated IAM user, attach the ReadOnlyAccess managed policy, enforce MFA, and provide console access credentials. Here's the full picture:
- IAM Admin creates a new IAM user with console access enabled.
- The ReadOnlyAccess AWS managed policy is attached directly to the user (or via a group — preferred).
- An MFA device is enforced via an IAM policy condition, preventing console use without MFA.
- The junior developer logs in via the AWS Console sign-in URL and can view — but never mutate — any resource.
Analogy: Think of ReadOnlyAccess like a museum visitor badge. You can walk through every gallery, read every exhibit label, and observe every artifact — but the velvet rope prevents you from touching anything.
Step-by-Step Implementation
Step 1 — Create an IAM Group (Best Practice)
Always attach policies to groups, not individual users. This makes future access management scalable — add or remove users from the group instead of managing per-user policies.
# Create the group
aws iam create-group --group-name ReadOnlyDevelopers
# Attach the AWS managed ReadOnlyAccess policy to the group
aws iam attach-group-policy \
--group-name ReadOnlyDevelopers \
--policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess
Step 2 — Create the IAM User with Console Access
🔽 Click to expand: Full user creation CLI commands
# Create the IAM user
aws iam create-user --user-name junior-dev-jane
# Create a login profile (enables AWS Console access)
# Replace 'TempP@ssw0rd!' with a strong temporary password
aws iam create-login-profile \
--user-name junior-dev-jane \
--password 'TempP@ssw0rd!' \
--password-reset-required
# Add the user to the ReadOnlyDevelopers group
aws iam add-user-to-group \
--user-name junior-dev-jane \
--group-name ReadOnlyDevelopers
Step 3 — Enforce MFA with an IAM Policy
Attaching ReadOnlyAccess alone is not enough. Without MFA enforcement, a leaked password exposes your entire AWS environment to a read-only attacker who can enumerate infrastructure, harvest ARNs, and plan further attacks. Attach the following inline policy to the group to deny all actions unless MFA is active.
🔽 Click to expand: MFA enforcement IAM policy (JSON)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyAllWithoutMFA",
"Effect": "Deny",
"NotAction": [
"iam:CreateVirtualMFADevice",
"iam:EnableMFADevice",
"iam:GetUser",
"iam:ListMFADevices",
"iam:ListVirtualMFADevices",
"iam:ResyncMFADevice",
"sts:GetSessionToken"
],
"Resource": "*",
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": "false"
}
}
}
]
}
# Save the above JSON as enforce-mfa.json, then run:
aws iam put-group-policy \
--group-name ReadOnlyDevelopers \
--policy-name EnforceMFA \
--policy-document file://enforce-mfa.json
Step 4 — Share the Console Sign-In URL
Your account-specific console URL follows this format:
https://<your-account-id>.signin.aws.amazon.com/console
Retrieve your Account ID with:
aws sts get-caller-identity --query Account --output text
Verification: Confirm the Policy is Attached
Always verify the effective permissions after setup. Never assume — confirm.
# List policies attached to the group
aws iam list-attached-group-policies --group-name ReadOnlyDevelopers
# Simulate what actions the user can perform (IAM Policy Simulator)
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789012:user/junior-dev-jane \
--action-names "ec2:DescribeInstances" "ec2:TerminateInstances" "s3:GetObject" "s3:DeleteObject"
Expected result: ec2:DescribeInstances and s3:GetObject → allowed. ec2:TerminateInstances and s3:DeleteObject → denied.
What ReadOnlyAccess Does NOT Cover
Be aware of these important boundaries before assuming full visibility:
| Scope | Included in ReadOnlyAccess? | Notes |
|---|---|---|
| AWS service resource metadata | ✅ Yes | EC2, S3, RDS, Lambda, etc. |
| AWS Billing & Cost data | ❌ No | Requires separate billing console activation + AWSBillingReadOnlyAccess |
| AWS Organizations data | ❌ No | Requires explicit Organizations read permissions |
| Secrets Manager secret values | ❌ No | GetSecretValue is a write-risk action; not included by design |
| S3 object contents | ⚠️ Partial | Bucket listing allowed; object-level access depends on bucket policy |
IAM Best Practices Checklist
- ✅ Use IAM Groups — never attach policies directly to individual users for team scenarios.
- ✅ Use AWS Managed Policies (
ReadOnlyAccess) — AWS maintains and updates them as new services launch. - ✅ Enforce MFA — mandatory for any human IAM user with console access.
- ✅ Enable IAM Access Analyzer — continuously monitors for overly permissive access.
- ✅ Set a password policy — enforce minimum length, complexity, and rotation via
aws iam update-account-password-policy. - ✅ Consider AWS IAM Identity Center (SSO) for teams larger than 2-3 people — it's the modern, recommended approach over long-lived IAM users.
Modern Alternative: AWS IAM Identity Center
For teams, AWS recommends AWS IAM Identity Center (formerly AWS SSO) over creating individual IAM users. It provides centralized access management, supports external identity providers (Okta, Azure AD), and issues short-lived credentials — eliminating the risk of long-lived IAM user access keys entirely. Assign the ReadOnlyAccess permission set within IAM Identity Center for the same effect with far better security posture.
Glossary
| Term | Definition |
|---|---|
| AWS Managed Policy | A standalone IAM policy created and maintained by AWS. Automatically updated when new services or actions are added. |
| Least Privilege | The security principle of granting only the minimum permissions required to perform a task — nothing more. |
| IAM Group | A collection of IAM users. Policies attached to a group apply to all users within it, simplifying access management. |
| MFA (Multi-Factor Authentication) | A second layer of identity verification beyond a password, required before granting console or API access. |
| IAM Policy Simulator | An AWS tool that evaluates IAM policies to determine what actions a principal is allowed or denied, without making real API calls. |
Next Steps
- 📖 AWS Docs: Managed vs. Inline Policies
- 📖 AWS IAM Security Best Practices
- 📖 AWS IAM Identity Center (Recommended for Teams)
- 🔧 Run the IAM Policy Simulator to validate effective permissions before handing over credentials.
Comments
Post a Comment