Skip to main content

AWS Organization Delegated Administrators

Overview

This check verifies that your AWS Organization only has trusted accounts designated as delegated administrators. Delegated administrators are member accounts that can manage specific AWS services on behalf of the management account.

The check compares your current delegated administrators against a predefined list of trusted accounts. Any delegated administrator not on the trusted list will be flagged.

Risk

Unapproved delegated administrators pose serious security risks:

  • Privilege escalation: Unauthorized accounts could modify Service Control Policies (SCPs) or create privileged roles
  • Account manipulation: Attackers could alter account settings across your organization
  • Compromised guardrails: Organization-wide security policies could be weakened or bypassed
  • Data exposure: Sensitive data across all accounts could be accessed or exfiltrated

Severity: Critical

Remediation Steps

Prerequisites

  • Access to the organization management account (the root account of your AWS Organization)
  • Permissions to view and modify delegated administrators
  • A documented list of approved/trusted accounts that should be delegated administrators
Required IAM permissions

You need the following permissions on the management account:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"organizations:ListDelegatedAdministrators",
"organizations:ListDelegatedServicesForAccount",
"organizations:DeregisterDelegatedAdministrator",
"organizations:RegisterDelegatedAdministrator"
],
"Resource": "*"
}
]
}

AWS Console Method

  1. Sign in to the AWS Management Console using the organization management account
  2. Navigate to AWS Organizations (search for "Organizations" in the search bar)
  3. In the left sidebar, click Services
  4. Select Delegated administrators from the submenu
  5. Review each delegated administrator account:
    • Compare the Account ID against your approved/trusted accounts list
    • Note which AWS services each account administers
  6. For any untrusted account:
    • Select the account
    • Click Deregister for each service delegation
    • Confirm the deregistration when prompted
  7. Repeat until only approved accounts remain as delegated administrators

Important: Before deregistering a delegated administrator, verify that removing the delegation will not disrupt critical services. Some AWS services require delegated administrators to function properly.

AWS CLI (optional)

List all delegated administrators:

aws organizations list-delegated-administrators \
--region us-east-1

List delegated administrators for a specific service:

aws organizations list-delegated-administrators \
--service-principal guardduty.amazonaws.com \
--region us-east-1

List services delegated to a specific account:

aws organizations list-delegated-services-for-account \
--account-id 123456789012 \
--region us-east-1

Deregister an untrusted delegated administrator:

aws organizations deregister-delegated-administrator \
--account-id <untrusted-account-id> \
--service-principal <service-principal> \
--region us-east-1

Replace:

  • <untrusted-account-id> with the 12-digit AWS account ID
  • <service-principal> with the service (e.g., guardduty.amazonaws.com, securityhub.amazonaws.com)

Example - Remove GuardDuty delegation from an untrusted account:

aws organizations deregister-delegated-administrator \
--account-id 111122223333 \
--service-principal guardduty.amazonaws.com \
--region us-east-1

Note: AWS Organizations API calls must be made to the us-east-1 region, regardless of where your resources are located.

CloudFormation (optional)

AWS CloudFormation does not currently provide a dedicated resource type for managing delegated administrators directly. To manage delegated administrators with Infrastructure as Code, consider using:

  1. Terraform (see the Terraform section below)
  2. AWS CloudFormation custom resources with Lambda functions
  3. AWS CDK with custom constructs

If you need a CloudFormation-based solution, you can create a custom resource:

AWSTemplateFormatVersion: '2010-09-09'
Description: Custom resource for managing delegated administrators

Resources:
DelegatedAdminFunction:
Type: AWS::Lambda::Function
Properties:
FunctionName: ManageDelegatedAdmin
Runtime: python3.11
Handler: index.handler
Role: !GetAtt LambdaExecutionRole.Arn
Timeout: 60
Code:
ZipFile: |
import boto3
import cfnresponse

def handler(event, context):
orgs = boto3.client('organizations', region_name='us-east-1')

try:
if event['RequestType'] == 'Create':
orgs.register_delegated_administrator(
AccountId=event['ResourceProperties']['AccountId'],
ServicePrincipal=event['ResourceProperties']['ServicePrincipal']
)
elif event['RequestType'] == 'Delete':
orgs.deregister_delegated_administrator(
AccountId=event['ResourceProperties']['AccountId'],
ServicePrincipal=event['ResourceProperties']['ServicePrincipal']
)
cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
except Exception as e:
cfnresponse.send(event, context, cfnresponse.FAILED, {'Error': str(e)})

LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: OrganizationsAccess
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- organizations:RegisterDelegatedAdministrator
- organizations:DeregisterDelegatedAdministrator
Resource: '*'

# Example: Register a trusted account as delegated admin
TrustedDelegatedAdmin:
Type: Custom::DelegatedAdministrator
Properties:
ServiceToken: !GetAtt DelegatedAdminFunction.Arn
AccountId: '123456789012' # Replace with your trusted account ID
ServicePrincipal: guardduty.amazonaws.com

Note: This template must be deployed from the organization management account.

Terraform (optional)

Terraform provides native support for managing delegated administrators.

List current delegated administrators (data source):

terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}

provider "aws" {
region = "us-east-1"
}

# Query all current delegated administrators
data "aws_organizations_delegated_administrators" "current" {}

output "current_delegated_admins" {
value = data.aws_organizations_delegated_administrators.current.delegated_administrators
}

Register trusted accounts as delegated administrators:

terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}

provider "aws" {
region = "us-east-1"
}

# Register a trusted account as delegated administrator for GuardDuty
resource "aws_organizations_delegated_administrator" "guardduty" {
account_id = "123456789012"
service_principal = "guardduty.amazonaws.com"
}

# Register for Security Hub
resource "aws_organizations_delegated_administrator" "securityhub" {
account_id = "123456789012"
service_principal = "securityhub.amazonaws.com"
}

# Register for AWS Config
resource "aws_organizations_delegated_administrator" "config" {
account_id = "123456789012"
service_principal = "config.amazonaws.com"
}

Managing multiple services with a variable:

variable "trusted_admin_account_id" {
description = "The account ID of the trusted delegated administrator"
type = string
default = "123456789012"
}

variable "delegated_services" {
description = "List of service principals to delegate"
type = list(string)
default = [
"guardduty.amazonaws.com",
"securityhub.amazonaws.com",
"config.amazonaws.com",
"access-analyzer.amazonaws.com"
]
}

resource "aws_organizations_delegated_administrator" "trusted" {
for_each = toset(var.delegated_services)

account_id = var.trusted_admin_account_id
service_principal = each.value
}

Important notes:

  • This Terraform configuration must be applied from the organization management account
  • To remove an untrusted delegated administrator, simply remove or comment out the corresponding resource block and run terraform apply
  • Importing existing delegated administrators: terraform import aws_organizations_delegated_administrator.example 123456789012/guardduty.amazonaws.com

Verification

After completing remediation:

  1. Return to AWS Organizations > Services > Delegated administrators
  2. Confirm that only trusted accounts appear in the list
  3. Document the approved delegated administrators for future audits
CLI verification commands

Verify all remaining delegated administrators are trusted:

aws organizations list-delegated-administrators \
--region us-east-1 \
--query 'DelegatedAdministrators[*].[Id,Name,Status]' \
--output table

Re-run the Prowler check:

prowler aws --checks organizations_delegated_administrators

Additional Resources

Notes

  • Trusted accounts list: Work with your security team to maintain a documented list of approved delegated administrator accounts
  • Service disruption: Deregistering a delegated administrator may affect services that rely on that delegation. Test in a non-production environment first
  • Least privilege: Only delegate the minimum set of services necessary for each account's role
  • Regular reviews: Schedule periodic reviews of delegated administrators as part of your security governance process
  • Audit trail: All delegated administrator changes are logged in AWS CloudTrail for audit purposes
  • Region requirement: AWS Organizations API calls must target us-east-1, regardless of where your resources are deployed