Home

IAM policies for different roles

The policies here were defined by looking at the policy that aws officially provides. The ec2 admin policy is basically the same, while the s3 upoaded was created by guessing. The auditor was lessened in characters just so it would fit in the in-browser text editor.

EC2 admin

This policy allows just about everything to be able to run EC2 instances, and manage them. Thus, this is quite simple using wildcard!

{
    "Version": "2025-06-23",
    "Statement": [
        {
            "Action": "ec2:*",
            "Effect": "Allow",
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "elasticloadbalancing:*",
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "cloudwatch:*",
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "autoscaling:*",
            "Resource": "*"
        }
    ]
}

S3 uploader

This policy is for only uploading to S3, it cannot read or list objects.

    {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Statement0",
            "Effect": "Allow",
            "Action": "s3:PutObject*",
            "Resource": "arn:aws:s3:::*/*"
        },
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads",
                "s3:ListBucketVersions",
                "s3:ListMultipartUploadParts",
                "s3:ListMultiRegionAccessPoints",
                "s3:ListTagsForResource",
                "s3:RestoreObject"
            ],
            "Resource": [
                "arn:aws:s3:::*/*"
            ]
        }
    ]
}

Read only auditor

Since this is a very vague role, the rules here are quite complex. I have reduced them to basic security things, as well as ec2 and s3. Unused services like lambda and sns are not included.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "BaseSecurityAuditStatement",
            "Effect": "Allow",
            "Action": [
                "autoscaling:Describe*",
                "backup:DescribeGlobalSettings",
                "backup:DescribeRegionSettings",
                "backup:GetBackupVaultAccessPolicy",
                "backup:ListBackupVaults",
                "cloudwatch:Describe*",
                "cloudwatch:GetDashboard",
                "cloudwatch:ListDashboards",
                "config:Get*",
                "config:List*",
                "ec2:Describe*",
                "ec2:GetEbsEncryptionByDefault",
                "ec2:GetImageBlockPublicAccessState",
                "ec2:GetManagedPrefixListAssociations",
                "ec2:GetManagedPrefixListEntries",
                "ec2:GetNetworkInsightsAccessScopeAnalysisFindings",
                "ec2:GetNetworkInsightsAccessScopeContent",
                "ec2:GetTransitGatewayAttachmentPropagations",
                "ec2:GetTransitGatewayMulticastDomainAssociations",
                "ec2:GetTransitGatewayPrefixListReferences",
                "ec2:GetTransitGatewayRouteTableAssociations",
                "ec2:GetTransitGatewayRouteTablePropagations",
                "ec2:SearchTransitGatewayRoutes",
                "ecr-public:DescribeImages*",
                "iam:GenerateCredentialReport",
                "iam:GenerateServiceLastAccessedDetails",
                "iam:Get*",
                "iam:List*",
                "iam:SimulateCustomPolicy",
                "iam:SimulatePrincipalPolicy",
                "network-firewall:DescribeFirewall*",
                "network-firewall:DescribeLoggingConfiguration",
                "network-firewall:DescribeResourcePolicy",
                "network-firewall:DescribeRuleGroup",
                "network-firewall:ListFirewall*",
                "network-firewall:ListRuleGroups",
                "networkmanager:DescribeGlobalNetworks",
                "s3-outposts:ListEndpoints",
                "s3-outposts:ListOutpostsWithS3",
                "s3-outposts:ListSharedEndpoints",
                "s3:GetAccelerateConfiguration",
                "s3:GetAccessGrantsInstanceResourcePolicy",
                "s3:GetAccessPoint",
                "s3:GetAccessPointPolicy",
                "s3:GetAccessPointPolicyStatus",
                "s3:GetAccountPublicAccessBlock",
                "s3:GetAnalyticsConfiguration",
                "s3:GetBucket*",
                "s3:GetEncryptionConfiguration",
                "s3:GetInventoryConfiguration",
                "s3:GetLifecycleConfiguration",
                "s3:GetMetricsConfiguration",
                "s3:GetMultiRegionAccessPoint*",
                "s3:GetObjectAcl",
                "s3:GetObjectVersionAcl",
                "s3:GetReplicationConfiguration",
                "s3:GetStorageLensGroup",
                "s3:GetStorageLensConfiguration",
                "s3:ListAccessPoints",
                "s3:ListAllMyBuckets",
                "s3:ListMultiRegionAccessPoints",
                "s3:ListStorageLensGroups",
                "s3:ListJobs",
                "s3:ListCallerAccessGrants",
                "s3:ListAccessGrantsInstances",
                "s3:ListAccessGrants",
                "s3:ListStorageLensConfigurations",
                "s3express:ListAllMyDirectoryBuckets",
                "s3express:GetEncryptionConfiguration",
                "s3express:GetBucketPolicy",
                "s3tables:ListTableBuckets",
                "s3tables:ListNamespaces",
                "s3tables:ListTables",
                "s3tables:GetNamespace",
                "s3tables:GetTableBucketPolicy",
                "s3tables:GetTableBucketMaintenanceConfiguration",
                "s3tables:GetTableMaintenanceConfiguration",
                "s3tables:GetTablePolicy",
                "sagemaker:Describe*",
                "sagemaker:List*",
                "secretsmanager:DescribeSecret",
                "secretsmanager:GetResourcePolicy",
                "secretsmanager:ListSecrets",
                "secretsmanager:ListSecretVersionIds",
                "securityhub:BatchGetAutomationRules",
                "securityhub:BatchGetConfigurationPolicyAssociations",
                "securityhub:BatchGetControlEvaluations",
                "securityhub:BatchGetSecurityControls",
                "securityhub:BatchGetStandardsControlAssociations",
                "securityhub:Describe*",
                "securityhub:Get*",
                "securityhub:List*"
            ],
            "Resource": "*"
        }
    ]
}

MFA enforcement

Taken from: https://repost.aws/knowledge-center/mfa-iam-user-aws-cli
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_aws_my-sec-creds-self-manage-mfa-only.html

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowViewAccountInfo",
            "Effect": "Allow",
            "Action": "iam:ListVirtualMFADevices",
            "Resource": "*"
        },
        {
            "Sid": "AllowManageOwnVirtualMFADevice",
            "Effect": "Allow",
            "Action": [
                "iam:CreateVirtualMFADevice"
            ],
            "Resource": "arn:aws:iam::*:mfa/*"
        },
        {
            "Sid": "AllowManageOwnUserMFA",
            "Effect": "Allow",
            "Action": [
                "iam:DeactivateMFADevice",
                "iam:EnableMFADevice",
                "iam:GetUser",
                "iam:GetMFADevice",
                "iam:ListMFADevices",
                "iam:ResyncMFADevice"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        },
        {
            "Sid": "DenyAllExceptListedIfNoMFA",
            "Effect": "Deny",
            "NotAction": [
                "iam:CreateVirtualMFADevice",
                "iam:EnableMFADevice",
                "iam:GetUser",
                "iam:ListMFADevices",
                "iam:ListVirtualMFADevices",
                "iam:ResyncMFADevice",
                "sts:GetSessionToken"
            ],
            "Resource": "*",
            "Condition": {
                "BoolIfExists": {"aws:MultiFactorAuthPresent": "false"}
            }
        },
        {
            "Sid": "BlockMostAccessUnlessSignedInWithMFA",
            "Effect": "Deny",
            "NotAction": [
              "iam:CreateVirtualMFADevice",
              "iam:DeleteVirtualMFADevice",
              "iam:ListVirtualMFADevices",
              "iam:EnableMFADevice",
              "iam:ResyncMFADevice",
              "iam:ListAccountAliases",
              "iam:ListUsers",
              "iam:ListSSHPublicKeys",
              "iam:ListAccessKeys",
              "iam:ListServiceSpecificCredentials",
              "iam:ListMFADevices",
              "iam:GetAccountSummary",
              "sts:GetSessionToken"
            ],
            "Resource": "*",
            "Condition": {
              "Bool": {
                "aws:MultiFactorAuthPresent": "false",
                "aws:ViaAWSService": "false"
              }
            }
        }
    ]
}