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.
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": "*"
}
]
}
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:::*/*"
]
}
]
}
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": "*"
}
]
}
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"
}
}
}
]
}