Skip to main content

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:AttachGroupPolicy or iam:PutGroupPolicy (to add replacement policies)

AWS Console Method

  1. Sign in to the AWS Management Console
  2. Navigate to IAM (search for "IAM" in the search bar)
  3. Click User groups in the left sidebar
  4. Select the group that has the AdministratorAccess policy
  5. Click the Permissions tab
  6. Find AdministratorAccess in the list of attached policies
  7. Select the checkbox next to AdministratorAccess
  8. Click Remove and confirm the action
  9. Click Add permissions > Attach policies
  10. Search for and select policies that provide only the permissions your team needs (see "Choosing Replacement Policies" below)
  11. Click Attach policies

Choosing Replacement Policies

Instead of AdministratorAccess, use policies that follow the principle of least privilege:

Team RoleSuggested AWS Managed Policies
Developers (read-only)ReadOnlyAccess
Developers (specific services)AmazonS3FullAccess, AmazonEC2FullAccess (only what's needed)
Database adminsAmazonRDSFullAccess, AmazonDynamoDBFullAccess
Security auditorsSecurityAudit, ReadOnlyAccess
Billing viewersAWSBillingReadOnlyAccess

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:

  1. Go to IAM > User groups in the AWS Console
  2. Click on the group you modified
  3. Check the Permissions tab
  4. Confirm that AdministratorAccess is no longer listed
  5. 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

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