Ensure No IAM Groups Have Administrator Access Policy
Overview
This check ensures that no IAM groups in your AWS account have the AdministratorAccess managed policy attached. Groups with this policy grant unrestricted access to all AWS services and resources to any user in the group.
Risk
Assigning AdministratorAccess at the group level creates significant security exposure. If an account is compromised, attackers could:
- Extract sensitive data and credentials
- Modify or destroy resources and configurations
- Disable logging and security controls
- Create backdoor access for persistence
- Incur unexpected charges through resource creation
Severity: High
Remediation Steps
Prerequisites
You need IAM permissions to view and modify group policies. Specifically, you need:
iam:ListAttachedGroupPolicies(to view current policies)iam:DetachGroupPolicy(to remove the AdministratorAccess policy)iam:AttachGroupPolicyoriam:PutGroupPolicy(to add replacement policies)
AWS Console Method
- Sign in to the AWS Management Console
- Navigate to IAM (search for "IAM" in the search bar)
- Click User groups in the left sidebar
- Select the group that has the
AdministratorAccesspolicy - Click the Permissions tab
- Find
AdministratorAccessin the list of attached policies - Select the checkbox next to
AdministratorAccess - Click Remove and confirm the action
- Click Add permissions > Attach policies
- Search for and select policies that provide only the permissions your team needs (see "Choosing Replacement Policies" below)
- Click Attach policies
Choosing Replacement Policies
Instead of AdministratorAccess, use policies that follow the principle of least privilege:
| Team Role | Suggested AWS Managed Policies |
|---|---|
| Developers (read-only) | ReadOnlyAccess |
| Developers (specific services) | AmazonS3FullAccess, AmazonEC2FullAccess (only what's needed) |
| Database admins | AmazonRDSFullAccess, AmazonDynamoDBFullAccess |
| Security auditors | SecurityAudit, ReadOnlyAccess |
| Billing viewers | AWSBillingReadOnlyAccess |
For production environments, create custom policies that grant access only to specific resources.
AWS CLI (optional)
Detach the AdministratorAccess Policy
aws iam detach-group-policy \
--group-name <your-group-name> \
--policy-arn arn:aws:iam::aws:policy/AdministratorAccess \
--region us-east-1
Replace <your-group-name> with the actual group name (e.g., Developers, Admins).
List Current Policies on a Group
To see what policies are currently attached:
aws iam list-attached-group-policies \
--group-name <your-group-name> \
--region us-east-1
Attach a Replacement Policy
aws iam attach-group-policy \
--group-name <your-group-name> \
--policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess \
--region us-east-1
Find All Groups with AdministratorAccess
To audit all groups in your account:
for group in $(aws iam list-groups --query 'Groups[*].GroupName' --output text --region us-east-1); do
policies=$(aws iam list-attached-group-policies --group-name "$group" --query "AttachedPolicies[?PolicyArn=='arn:aws:iam::aws:policy/AdministratorAccess'].PolicyName" --output text --region us-east-1)
if [ -n "$policies" ]; then
echo "Group '$group' has AdministratorAccess attached"
fi
done
CloudFormation (optional)
This CloudFormation template creates an IAM group with least-privilege permissions instead of AdministratorAccess. Customize the policy statements for your specific use case.
AWSTemplateFormatVersion: '2010-09-09'
Description: >
Example IAM group with least-privilege permissions instead of AdministratorAccess.
Replace the policy statements with permissions appropriate for your use case.
Parameters:
GroupName:
Type: String
Description: Name for the IAM group
Default: DevelopersGroup
Resources:
LeastPrivilegeGroup:
Type: AWS::IAM::Group
Properties:
GroupName: !Ref GroupName
ManagedPolicyArns:
# Example: Read-only access instead of AdministratorAccess
- arn:aws:iam::aws:policy/ReadOnlyAccess
Policies:
- PolicyName: CustomLeastPrivilegePolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: AllowSpecificS3Actions
Effect: Allow
Action:
- s3:GetObject
- s3:PutObject
- s3:ListBucket
Resource:
- arn:aws:s3:::my-application-bucket
- arn:aws:s3:::my-application-bucket/*
- Sid: AllowSpecificEC2Actions
Effect: Allow
Action:
- ec2:DescribeInstances
- ec2:StartInstances
- ec2:StopInstances
Resource: '*'
Condition:
StringEquals:
aws:ResourceTag/Environment: development
Outputs:
GroupArn:
Description: ARN of the created IAM group
Value: !GetAtt LeastPrivilegeGroup.Arn
Important: This template creates a new group. To modify an existing group, you'll need to update your existing CloudFormation stack or use the console/CLI to detach the policy.
Terraform (optional)
This Terraform configuration creates an IAM group with least-privilege permissions. Customize the policy for your specific requirements.
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
variable "group_name" {
description = "Name for the IAM group"
type = string
default = "DevelopersGroup"
}
# IAM group with least-privilege permissions (no AdministratorAccess)
resource "aws_iam_group" "least_privilege" {
name = var.group_name
}
# Attach a managed policy with appropriate permissions
resource "aws_iam_group_policy_attachment" "readonly" {
group = aws_iam_group.least_privilege.name
policy_arn = "arn:aws:iam::aws:policy/ReadOnlyAccess"
}
# Custom inline policy for specific permissions needed
resource "aws_iam_group_policy" "custom_permissions" {
name = "CustomLeastPrivilegePolicy"
group = aws_iam_group.least_privilege.name
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "AllowSpecificS3Actions"
Effect = "Allow"
Action = [
"s3:GetObject",
"s3:PutObject",
"s3:ListBucket"
]
Resource = [
"arn:aws:s3:::my-application-bucket",
"arn:aws:s3:::my-application-bucket/*"
]
},
{
Sid = "AllowSpecificEC2Actions"
Effect = "Allow"
Action = [
"ec2:DescribeInstances",
"ec2:StartInstances",
"ec2:StopInstances"
]
Resource = "*"
Condition = {
StringEquals = {
"aws:ResourceTag/Environment" = "development"
}
}
}
]
})
}
output "group_arn" {
description = "ARN of the IAM group"
value = aws_iam_group.least_privilege.arn
}
To remove AdministratorAccess from an existing Terraform-managed group:
If you're currently attaching AdministratorAccess via Terraform, simply remove or replace the policy attachment:
# REMOVE this:
# resource "aws_iam_group_policy_attachment" "admin" {
# group = aws_iam_group.my_group.name
# policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess"
# }
# REPLACE with appropriate least-privilege policy
resource "aws_iam_group_policy_attachment" "readonly" {
group = aws_iam_group.my_group.name
policy_arn = "arn:aws:iam::aws:policy/ReadOnlyAccess"
}
Verification
After removing the AdministratorAccess policy:
- Go to IAM > User groups in the AWS Console
- Click on the group you modified
- Check the Permissions tab
- Confirm that
AdministratorAccessis no longer listed - Verify that appropriate replacement policies are attached
CLI Verification
aws iam list-attached-group-policies \
--group-name <your-group-name> \
--region us-east-1
The output should not include AdministratorAccess:
{
"AttachedPolicies": [
{
"PolicyName": "ReadOnlyAccess",
"PolicyArn": "arn:aws:iam::aws:policy/ReadOnlyAccess"
}
]
}
Additional Resources
- AWS IAM Best Practices
- Granting Least Privilege
- AWS Managed Policies for Job Functions
- IAM Access Analyzer - helps identify unused permissions
Notes
-
Test before removing: Before detaching
AdministratorAccess, ensure users in the group have the permissions they need through other policies. Removing admin access could break workflows if users depend on broad permissions. -
Consider IAM roles instead: For administrative tasks, consider using IAM roles that users can assume temporarily (with MFA required) rather than granting permanent admin-level permissions to groups.
-
Use permission boundaries: For groups that need elevated permissions, consider implementing permission boundaries to limit the maximum permissions.
-
Audit regularly: Use IAM Access Analyzer to identify permissions that are granted but not used, helping you refine policies over time.
-
Related compliance frameworks: C5, CCC, KISA-ISMS-P