This article will describe the following features:
AWS Organizations is used to centrally manage multiple AWS accounts, with features such as consolidated billing, security controls, resource sharing, etc. It should be enabled by any entity managing more than one AWS account.
The Management Account is the account used to create the AWS Organization. The account is the organization owner and can perform major actions for any account in the Organization such as closing existing accounts or adding new accounts. Due to the elevated access possible through this account, access to this account should be minimized.
When creating an AWS account, the email and password used to create the account become the credentials for the root user of that account. The root user has access to every service and resource in this account. Due to this, it is recommended to lock down the usage of this user as far as possible. Root user best practices.
Only a root user can perform some privileged actions. Performing these actions requires logging in as a root user.
Trusted access for IAM in AWS Organizations should be enabled for central management of root credentials and temporary root sessions.
The following steps need to be performed in the Management Account of the AWS Organization.
1aws organizations enable-aws-service-access --service-principal iam.amazonaws.com
To verify:
1aws organizations list-aws-service-access-for-organization
The output will include the IAM service:
1{2 "EnabledServicePrincipals": [3 ...4 {5 "ServicePrincipal": "iam.amazonaws.com",6 "DateEnabled": "1970-01-01T00:00:00.000000+00:00"7 },8 ...9 ]10}
Alternatively, if you are already managing your AWS Organization configuration using the aws_organizations_organization block in Terraform, you can add "iam.amazonaws.com" to the aws_service_access_principals array:
1resource "aws_organizations_organization" "organization" {2 aws_service_access_principals = [<other services>, "iam.amazonaws.com"]3 feature_set = "ALL"4 ... other attributes5}
CAUTION: This resource is used to enable AWS Organizations. Enabling AWS Organizations is a major change and should not be done for experimentation. Use the CLI method unless you are already using this resource block to manage your AWS Organization.
The following steps need to be performed in the Management Account of the AWS Organization.
1$ aws iam enable-organizations-root-credentials-management2{3 "OrganizationId": "o-abcxyz",4 "EnabledFeatures": [5 "RootCredentialsManagement"6 ]7}8$ aws iam enable-organizations-root-sessions9{10 "OrganizationId": "o-abcxyz",11 "EnabledFeatures": [12 "RootSessions",13 "RootCredentialsManagement"14 ]15}
Terraform alternative:
1resource "aws_iam_organizations_features" "root" {2 enabled_features = [3 "RootCredentialsManagement",4 "RootSessions"5 ]6}
The following command is used for both RootCredentialsManagement and RootSessions.
1aws sts assume-root --target-principal <account-id> --task-policy-arn arn=arn:aws:iam::aws:policy/root-task/<TaskPolicy>
If RootCredentialsManagement is enabled, the following TaskPolicies can be used:
arn:aws:iam::aws:policy/root-task/IAMAuditRootUserCredentials
arn:aws:iam::aws:policy/root-task/IAMCreateRootUserPassword
arn:aws:iam::aws:policy/root-task/IAMDeleteRootUserCredentials
If RootSessions is enabled, the following TaskPolicies can be used:
arn:aws:iam::aws:policy/root-task/S3UnlockBucketPolicy
arn:aws:iam::aws:policy/root-task/SQSUnlockQueuePolicy
A detailed reference for what is allowed for each policy can be found here.
To minimize logins to the Organization Management account for the use of this feature, it is recommended that delegated access be enabled so that another account can also assume root access. This account can be any other account in the AWS Organization.
1aws organizations register-delegated-administrator --service-principal iam.amazonaws.com --account-id <account_id>
Terraform alternative:
1resource "aws_organizations_delegated_administrator" "delegate_iam" {2 account_id = "<account_id>"3 service_principal = "iam.amazonaws.com"4}
Based on my experimentation, delegated accounts:
aws sts assume-root
aws iam disable-organizations-root-credentials-management
aws iam disable-organizations-root-sessions
aws iam enable-organizations-root-credentials-management
aws iam enable-organizations-root-sessions
The following script demonstrates the deletion of root credentials from all non-Management accounts in an AWS organization using aws sts assume-root
. It can also be modified to perform similar actions in one or more accounts using one of the above task policies.
1#!/bin/bash23# Backup original credentials if they were set via variables4export BACKUP_AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID5export BACKUP_AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY6export BACKUP_AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN78MANAGEMENT_ACCOUNT_ID=$(aws sts get-caller-identity | jq -r '.Account')910# Get all account IDs except management account11AWS_ACCOUNT_IDS=($(aws organizations list-accounts | jq -r '.Accounts[].Id | select(. != $MANAGEMENT_ACCOUNT_ID)' --arg MANAGEMENT_ACCOUNT_ID $MANAGEMENT_ACCOUNT_ID))1213for AWS_ACCOUNT_ID in "${AWS_ACCOUNT_IDS[@]}"14do15 CREDENTIALS=$(aws sts assume-root --target-principal ${AWS_ACCOUNT_ID} --task-policy-arn arn=arn:aws:iam::aws:policy/root-task/IAMDeleteRootUserCredentials)16 # Set credentials for a specific account17 export AWS_ACCESS_KEY_ID=$(echo $CREDENTIALS | jq -r '.Credentials.AccessKeyId')18 export AWS_SECRET_ACCESS_KEY=$(echo $CREDENTIALS | jq -r '.Credentials.SecretAccessKey')19 export AWS_SESSION_TOKEN=$(echo $CREDENTIALS | jq -r '.Credentials.SessionToken')20 # This will delete root credentials for the account21 aws iam delete-login-profile22 # Restore backed-up values23 export AWS_ACCESS_KEY_ID=$BACKUP_AWS_ACCESS_KEY_ID24 export AWS_SECRET_ACCESS_KEY=$BACKUP_AWS_SECRET_ACCESS_KEY25 export AWS_SESSION_TOKEN=$BACKUP_AWS_SESSION_TOKEN26done27