Skip to main content

IAM SecurityAudit Role Created

Overview

This check verifies that at least one IAM role in your AWS account has the AWS managed SecurityAudit policy attached. The SecurityAudit policy provides read-only access to security-relevant configurations across AWS services, enabling security teams to review settings without the risk of making changes.

Risk

Without a dedicated security audit role:

  • Security teams lack safe, read-only visibility into AWS configurations and logs
  • Misconfigurations may go undetected longer
  • Incident response becomes slower due to limited visibility
  • Auditors may need overly broad permissions to perform reviews

Remediation Steps

Prerequisites

You need IAM permissions to create roles and attach policies. Specifically, you need:

  • iam:CreateRole (if creating a new role)
  • iam:AttachRolePolicy
Check your current permissions

To verify you have the necessary permissions, try listing your IAM permissions or contact your AWS administrator. You'll need IAM administrative access or a policy that allows the actions listed above.

AWS Console Method

Option A: Attach to an existing role

  1. Sign in to the AWS Console
  2. Go to IAM (search for "IAM" in the top search bar)
  3. Click Roles in the left sidebar
  4. Find and click on an appropriate audit role (or any role you want to grant audit access)
  5. Click the Add permissions button
  6. Select Attach policies
  7. Search for SecurityAudit
  8. Check the box next to SecurityAudit (the AWS managed policy)
  9. Click Add permissions

Option B: Create a new security audit role

  1. Sign in to the AWS Console
  2. Go to IAM > Roles
  3. Click Create role
  4. Select AWS account as the trusted entity type
  5. Choose This account (or specify another account for cross-account access)
  6. Check Require MFA for added security (recommended)
  7. Click Next
  8. Search for SecurityAudit and check the box next to it
  9. Click Next
  10. Enter a role name (e.g., SecurityAuditRole)
  11. Add a description (e.g., "Read-only role for security auditing")
  12. Click Create role
AWS CLI (optional)

Attach SecurityAudit policy to an existing role:

aws iam attach-role-policy \
--role-name <your-role-name> \
--policy-arn arn:aws:iam::aws:policy/SecurityAudit \
--region us-east-1

Create a new role and attach the policy:

First, create a trust policy file:

cat > trust-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<your-account-id>:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
}
EOF

Then create the role and attach the policy:

# Create the role
aws iam create-role \
--role-name SecurityAuditRole \
--assume-role-policy-document file://trust-policy.json \
--description "Read-only role for security auditing" \
--region us-east-1

# Attach the SecurityAudit policy
aws iam attach-role-policy \
--role-name SecurityAuditRole \
--policy-arn arn:aws:iam::aws:policy/SecurityAudit \
--region us-east-1

Replace <your-account-id> with your 12-digit AWS account ID.

CloudFormation (optional)
AWSTemplateFormatVersion: '2010-09-09'
Description: Creates an IAM role with the SecurityAudit managed policy for security auditing

Parameters:
RoleName:
Type: String
Default: SecurityAuditRole
Description: Name for the security audit role

TrustedAccountId:
Type: String
Description: AWS Account ID that can assume this role (for cross-account access)
Default: ''

Conditions:
HasTrustedAccount: !Not [!Equals [!Ref TrustedAccountId, '']]

Resources:
SecurityAuditRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Ref RoleName
Description: Read-only role for security auditing with SecurityAudit managed policy
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
AWS: !If
- HasTrustedAccount
- !Sub 'arn:aws:iam::${TrustedAccountId}:root'
- !Sub 'arn:aws:iam::${AWS::AccountId}:root'
Action: 'sts:AssumeRole'
Condition:
Bool:
'aws:MultiFactorAuthPresent': 'true'
ManagedPolicyArns:
- arn:aws:iam::aws:policy/SecurityAudit
Tags:
- Key: Purpose
Value: SecurityAudit

Outputs:
RoleArn:
Description: ARN of the SecurityAudit role
Value: !GetAtt SecurityAuditRole.Arn
Export:
Name: !Sub '${AWS::StackName}-RoleArn'

RoleName:
Description: Name of the SecurityAudit role
Value: !Ref SecurityAuditRole

Deploy the stack:

aws cloudformation create-stack \
--stack-name security-audit-role \
--template-body file://template.yaml \
--capabilities CAPABILITY_NAMED_IAM \
--region us-east-1
Terraform (optional)
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.0"
}
}
}

variable "role_name" {
description = "Name for the security audit role"
type = string
default = "SecurityAuditRole"
}

variable "trusted_account_id" {
description = "AWS Account ID that can assume this role (optional, defaults to current account)"
type = string
default = ""
}

variable "require_mfa" {
description = "Whether to require MFA when assuming the role"
type = bool
default = true
}

data "aws_caller_identity" "current" {}

locals {
trusted_account = var.trusted_account_id != "" ? var.trusted_account_id : data.aws_caller_identity.current.account_id
}

data "aws_iam_policy_document" "assume_role" {
statement {
effect = "Allow"
actions = ["sts:AssumeRole"]

principals {
type = "AWS"
identifiers = ["arn:aws:iam::${local.trusted_account}:root"]
}

dynamic "condition" {
for_each = var.require_mfa ? [1] : []
content {
test = "Bool"
variable = "aws:MultiFactorAuthPresent"
values = ["true"]
}
}
}
}

resource "aws_iam_role" "security_audit" {
name = var.role_name
description = "Read-only role for security auditing with SecurityAudit managed policy"
assume_role_policy = data.aws_iam_policy_document.assume_role.json

tags = {
Purpose = "SecurityAudit"
}
}

resource "aws_iam_role_policy_attachment" "security_audit" {
role = aws_iam_role.security_audit.name
policy_arn = "arn:aws:iam::aws:policy/SecurityAudit"
}

output "role_arn" {
description = "ARN of the SecurityAudit role"
value = aws_iam_role.security_audit.arn
}

output "role_name" {
description = "Name of the SecurityAudit role"
value = aws_iam_role.security_audit.name
}

Deploy:

terraform init
terraform plan
terraform apply

Verification

After completing the remediation, verify the SecurityAudit policy is attached:

  1. Go to IAM > Roles in the AWS Console
  2. Click on your security audit role
  3. Under the Permissions tab, confirm SecurityAudit appears in the list
Verify with AWS CLI
# List policies attached to the role
aws iam list-attached-role-policies \
--role-name SecurityAuditRole \
--region us-east-1

# Expected output should include:
# {
# "AttachedPolicies": [
# {
# "PolicyName": "SecurityAudit",
# "PolicyArn": "arn:aws:iam::aws:policy/SecurityAudit"
# }
# ]
# }

Re-run Prowler to confirm the check passes:

prowler aws --check iam_securityaudit_role_created

Additional Resources

Notes

  • MFA Requirement: The examples above require MFA when assuming the role. This is a security best practice but can be removed if your use case requires it.

  • Cross-Account Access: To allow a security team from another AWS account to assume this role, specify their account ID in the trust policy instead of your own.

  • Federated Access: For organizations using AWS IAM Identity Center (SSO) or other identity providers, consider creating permission sets that include the SecurityAudit policy rather than standalone IAM roles.

  • Policy Scope: The SecurityAudit policy is read-only and provides broad visibility across AWS services. Review the policy document to understand exactly what access it grants.

  • Multiple Roles: You can attach the SecurityAudit policy to multiple roles if different teams need audit access with different trust relationships.