AWS Root Account Security Best Practices

Complete guide to securing your AWS root account with MFA, eliminating daily root usage, setting up break-glass procedures, and implementing account recovery safeguards.

8 min readUpdated 2026-01-13

Your AWS root account is the master key to your entire cloud environment. Compromising the root account gives attackers unrestricted access to all resources, billing information, and the ability to delete your entire infrastructure. Properly securing the root account is the most critical security measure you can take in AWS.

This article is part of our comprehensive Cloud Security Tips for 2026 guide covering essential practices for protecting your cloud environment.

Why Root Account Security Matters

The root account has unique properties that make it especially dangerous:

Root Account CapabilityRisk Level
Cannot be restricted by IAM policiesCritical
Can close the entire AWS accountCritical
Can access all billing and payment methodsHigh
Can change account email and contact infoHigh
Can delete any resource without restrictionCritical

Step 1: Enable MFA on Root Account

Using AWS Console

  1. Sign in to the AWS Management Console as root user
  2. Click your account name in the top right, then Security credentials
  3. In the Multi-factor authentication (MFA) section, click Assign MFA device
  4. Enter a device name (e.g., "root-yubikey" or "root-authenticator")
  5. Select your MFA device type:
    • Hardware TOTP token - Most secure option
    • Authenticator app - Good security, widely available
    • Security key - FIDO2 hardware key like YubiKey
  6. Follow the prompts to register your device
  7. Enter two consecutive MFA codes to verify setup

Using AWS CLI (For Virtual MFA)

# Create virtual MFA device
aws iam create-virtual-mfa-device \
  --virtual-mfa-device-name root-mfa \
  --outfile qrcode.png \
  --bootstrap-method QRCodePNG

# Display the QR code and scan with your authenticator app
# Then enable MFA with two consecutive codes
aws iam enable-mfa-device \
  --user-name root \
  --serial-number arn:aws:iam::123456789012:mfa/root-mfa \
  --authentication-code1 123456 \
  --authentication-code2 789012

Step 2: Create Administrative IAM Users

Create IAM users for all administrative tasks instead of using root:

# Create an admin user
aws iam create-user --user-name admin-john

# Attach administrator policy
aws iam attach-user-policy \
  --user-name admin-john \
  --policy-arn arn:aws:iam::aws:policy/AdministratorAccess

# Create login profile for console access
aws iam create-login-profile \
  --user-name admin-john \
  --password 'TempPassword123!' \
  --password-reset-required

# Enable MFA for the admin user
aws iam create-virtual-mfa-device \
  --virtual-mfa-device-name admin-john-mfa \
  --outfile admin-john-qr.png \
  --bootstrap-method QRCodePNG

Terraform Configuration

resource "aws_iam_user" "admin" {
  name = "admin-john"
  tags = {
    Purpose = "Administrative access"
  }
}

resource "aws_iam_user_policy_attachment" "admin_attach" {
  user       = aws_iam_user.admin.name
  policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess"
}

resource "aws_iam_user_login_profile" "admin_login" {
  user                    = aws_iam_user.admin.name
  password_reset_required = true
}

Step 3: Remove Root Access Keys

Root access keys should never exist. If any exist, delete them immediately:

Using AWS Console

  1. Sign in as root user
  2. Go to Security credentials
  3. Under Access keys, delete any existing keys
  4. Never create new access keys for root

Check for Root Access Keys via CLI

# Generate credential report
aws iam generate-credential-report

# Wait for report generation
sleep 5

# Check root access key status
aws iam get-credential-report \
  --query 'Content' \
  --output text | base64 -d | head -2

# Output shows if root has access keys:
# user,arn,user_creation_time,access_key_1_active,access_key_2_active
# <root_account>,arn:aws:iam::123456789012:root,2020-01-01,false,false

Step 4: Configure CloudTrail Alerts for Root Usage

Set up immediate alerts when anyone uses the root account:

# Create CloudWatch log group for CloudTrail
aws logs create-log-group --log-group-name /aws/cloudtrail/root-activity

# Create metric filter for root account usage
aws logs put-metric-filter \
  --log-group-name /aws/cloudtrail/root-activity \
  --filter-name RootAccountUsage \
  --filter-pattern '{ $.userIdentity.type = "Root" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != "AwsServiceEvent" }' \
  --metric-transformations \
    metricName=RootAccountUsageCount,metricNamespace=SecurityMetrics,metricValue=1

# Create alarm
aws cloudwatch put-metric-alarm \
  --alarm-name root-account-usage \
  --alarm-description "Alert when root account is used" \
  --metric-name RootAccountUsageCount \
  --namespace SecurityMetrics \
  --statistic Sum \
  --period 300 \
  --threshold 1 \
  --comparison-operator GreaterThanOrEqualToThreshold \
  --evaluation-periods 1 \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:security-alerts

Terraform Configuration

resource "aws_cloudwatch_log_metric_filter" "root_usage" {
  name           = "RootAccountUsage"
  pattern        = "{ $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }"
  log_group_name = aws_cloudwatch_log_group.cloudtrail.name

  metric_transformation {
    name      = "RootAccountUsageCount"
    namespace = "SecurityMetrics"
    value     = "1"
  }
}

resource "aws_cloudwatch_metric_alarm" "root_usage_alarm" {
  alarm_name          = "root-account-usage"
  comparison_operator = "GreaterThanOrEqualToThreshold"
  evaluation_periods  = 1
  metric_name         = "RootAccountUsageCount"
  namespace           = "SecurityMetrics"
  period              = 300
  statistic           = "Sum"
  threshold           = 1
  alarm_description   = "Alert when root account is used"
  alarm_actions       = [aws_sns_topic.security_alerts.arn]
}

Step 5: Set Up Break-Glass Procedure

Document a secure process for emergency root access:

Break-Glass Process

  1. Physical Security: Store root credentials in a physical safe or secure vault
  2. Dual Control: Require two authorized personnel to access root credentials
  3. Documentation: Log all root access with ticket number and justification
  4. Time-Limited: Complete task and sign out immediately
  5. Post-Access Audit: Review CloudTrail logs after each root session

Secure Storage Options

Storage MethodProsCons
Physical SafeNo digital exposurePhysical access required
Hardware Security ModuleTamper-resistant, auditableExpensive
Split KnowledgeNo single person has full accessComplex recovery
Sealed Envelope + SafeSimple, effectiveManual process

Step 6: Use AWS Organizations with SCPs

Service Control Policies can restrict root account actions across member accounts:

# Create SCP to deny root actions
aws organizations create-policy \
  --name DenyRootActions \
  --description "Deny dangerous root account actions" \
  --type SERVICE_CONTROL_POLICY \
  --content '{
    "Version": "2012-10-17",
    "Statement": [
      {
        "Sid": "DenyRootActions",
        "Effect": "Deny",
        "Action": [
          "ec2:*",
          "s3:*",
          "iam:*"
        ],
        "Resource": "*",
        "Condition": {
          "StringLike": {
            "aws:PrincipalArn": "arn:aws:iam::*:root"
          }
        }
      }
    ]
  }'

Step 7: Account Recovery Setup

Configure account recovery options before you need them:

Update Account Contact Information

  1. Sign in as root to the Account Settings page
  2. Update Alternate Contacts with security and operations team emails
  3. Verify the Account email address is monitored
  4. Add a Phone number for account verification

Store Recovery Information Securely

# Document these items in your break-glass envelope:
# - AWS Account ID: 123456789012
# - Root email address: [email protected]
# - Phone number on file: +1-555-123-4567
# - MFA device serial number: arn:aws:iam::123456789012:mfa/root-yubikey
# - MFA backup codes (if virtual MFA)
# - Answers to security questions (if configured)

Audit Your Root Account Security

#!/bin/bash
# Root account security audit script

echo "=== AWS Root Account Security Audit ==="

# Check for root access keys
echo -e "\n1. Checking for root access keys..."
aws iam generate-credential-report > /dev/null 2>&1
sleep 3
ROOT_KEYS=$(aws iam get-credential-report --query 'Content' --output text | base64 -d | grep "^" | cut -d',' -f9,14)
echo "Root access keys status: $ROOT_KEYS"

# Check for root MFA
echo -e "\n2. Checking root MFA status..."
ROOT_MFA=$(aws iam get-credential-report --query 'Content' --output text | base64 -d | grep "^" | cut -d',' -f8)
echo "Root MFA enabled: $ROOT_MFA"

# Check recent root logins
echo -e "\n3. Checking recent root activity..."
aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=Username,AttributeValue=root \
  --max-results 5 \
  --query 'Events[*].[EventTime,EventName,EventSource]' \
  --output table

echo -e "\n=== Audit Complete ==="

Best Practices Checklist

Security ControlPriorityStatus
Enable hardware MFA on rootCritical[ ]
Delete root access keysCritical[ ]
Create IAM admin usersCritical[ ]
Set up CloudTrail alertsHigh[ ]
Document break-glass procedureHigh[ ]
Store credentials securelyHigh[ ]
Update account contactsMedium[ ]
Apply SCPs (Organizations)Medium[ ]

Frequently Asked Questions

Find answers to common questions

No, the root account should never be used for daily operations. Create IAM users or roles with appropriate permissions for day-to-day tasks. The root account has unrestricted access to all resources and billing information, making it extremely dangerous if compromised. Reserve root access only for critical account-level tasks that cannot be performed by IAM users, such as changing account settings, closing the account, or recovering from IAM lockouts.

Need Professional Help?

Our team of experts can help you implement and configure these solutions for your organization.