Skip to content

Instantly share code, notes, and snippets.

@dacut
Last active April 22, 2022 23:35
Show Gist options
  • Save dacut/090fb0cb6ef6248cb4353b587468f7b0 to your computer and use it in GitHub Desktop.
Save dacut/090fb0cb6ef6248cb4353b587468f7b0 to your computer and use it in GitHub Desktop.
IAM policy to get under the IAM policy size restrictions
#!/usr/bin/env python3
from fnmatch import fnmatch
import json
from os import environ
gopath = environ["GOPATH"]
with open(f"{gopath}/src/github.com/aws/aws-sdk-go-v2/codegen/sdk-codegen/aws-models/backup.json", "r") as fd:
backup_model = json.load(fd)
with open(f"{gopath}/src/github.com/aws/aws-sdk-go-v2/codegen/sdk-codegen/aws-models/ec2.json", "r") as fd:
ec2_model = json.load(fd)
with open(f"{gopath}/src/github.com/aws/aws-sdk-go-v2/codegen/sdk-codegen/aws-models/rds.json", "r") as fd:
rds_model = json.load(fd)
def get_actions_from_model(m):
for shape_name, shape in m["shapes"].items():
if shape.get("type") != "service":
continue
namespace = shape_name.split("#")[0]
actions = []
for operation in shape["operations"]:
assert operation["target"].startswith(namespace + "#"), f"{namespace} - {operation}"
actions.append(operation["target"][len(namespace) + 1:])
return set(actions)
all_actions = set(
[f"backup:{action}" for action in get_actions_from_model(backup_model)] +
[f"ec2:{action}" for action in get_actions_from_model(ec2_model)] +
[f"rds:{action}" for action in get_actions_from_model(rds_model)]
)
def get_effect(action, policy):
statements = policy.get("Statement")
if isinstance(statements, dict):
statements = [statements]
result = ("DEFAULT_DENY", "")
for i, statement in enumerate(statements):
effect = statement.get("Effect")
if effect not in ("Allow", "Deny"):
raise ValueError(f"Statement[{i}] has an invalid Effect: {effect}")
statement_actions = statement.get("Action")
if isinstance(statement_actions, str):
statement_actions = [statement_actions]
for statement_action in statement_actions:
if fnmatch(action, statement_action):
if effect == "Deny":
return "DENY", statement_action
else:
result = ("ALLOW", statement_action)
return result
def compare_policies(a, b):
for action in sorted(all_actions):
effect_a, action_a = get_effect(action, a)
effect_b, action_b = get_effect(action, b)
if effect_a != effect_b and not (effect_a == "DEFAULT_DENY" and effect_b == "DENY"):
print(f"! {action:<48s} {effect_a:<12} {action_a:<16} {effect_b:<12} {action_b:<16}")
with open("policy-full.json", "r") as fd:
policy_full = json.load(fd)
with open("policy-minified.json", "r") as fd:
policy_minified = json.load(fd)
compare_policies(policy_full, policy_minified)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"backup:CreateBackupSelection",
"backup:CreateBackupPlan",
"backup:CreateBackupVault",
"backup:CreateFramework",
"backup:CreateReportPlan",
"backup:DeleteBackupPlan",
"backup:DeleteBackupSelection",
"backup:DeleteBackupVault",
"backup:DeleteBackupVaultNotifications",
"backup:DeleteFramework",
"backup:DeleteRecoveryPoint",
"backup:DeleteReportPlan",
"backup:DescribeBackupJob",
"backup:DescribeBackupVault",
"backup:DescribeCopyJob",
"backup:DescribeFramework",
"backup:DescribeGlobalSettings",
"backup:DescribeProtectedResource",
"backup:DescribeRecoveryPoint",
"backup:DescribeRegionSettings",
"backup:DescribeReportPlan",
"backup:DescribeReportJob",
"backup:DescribeRestoreJob",
"backup:GetBackupPlan",
"backup:GetBackupPlanFromJSON",
"backup:GetBackupPlanFromTemplate",
"backup:GetBackupSelection",
"backup:GetBackupVaultNotifications",
"backup:GetRecoveryPointRestoreMetadata",
"backup:GetSupportedResourceTypes",
"backup:ListBackupJobs",
"backup:ListBackupPlanTemplates",
"backup:ListBackupPlanVersions",
"backup:ListBackupPlans",
"backup:ListBackupSelections",
"backup:ListBackupVaults",
"backup:ListCopyJobs",
"backup:ListFrameworks",
"backup:ListProtectedResources",
"backup:ListRecoveryPointsByBackupVault",
"backup:ListRecoveryPointsByResource",
"backup:ListReportJobs",
"backup:ListReportPlans",
"backup:ListRestoreJobs",
"backup:ListTags",
"backup:PutBackupVaultNotifications",
"backup:StartBackupJob",
"backup:StartCopyJob",
"backup:StartReportJob",
"backup:StartRestoreJob",
"backup:StopBackupJob",
"backup:TagResource",
"backup:UntagResource",
"backup:UpdateBackupPlan",
"backup:UpdateFramework",
"backup:UpdateRecoveryPointLifecycle",
"backup:UpdateRegionSettings",
"backup:UpdateReportPlan",
"ec2:AllocateAddress",
"ec2:AllocateHosts",
"ec2:AssociateAddress",
"ec2:AssociateIamInstanceProfile",
"ec2:AttachNetworkInterface",
"ec2:AttachVolume",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:CancelSpotFleetRequests",
"ec2:CancelSpotInstanceRequests",
"ec2:CreateFleet",
"ec2:CreateImage",
"ec2:CreateKeyPair",
"ec2:CreateLaunchTemplate",
"ec2:CreateLaunchTemplateVersion",
"ec2:CreateManagedPrefixList",
"ec2:CreateNetworkInterface",
"ec2:CreatePlacementGroup",
"ec2:CreateSecurityGroup",
"ec2:CreateSnapshot",
"ec2:CreateSnapshots",
"ec2:CreateStoreImageTask",
"ec2:CreateTags",
"ec2:CreateVolume",
"ec2:DeleteFleets",
"ec2:DeleteNetworkInterface",
"ec2:DeletePlacementGroup",
"ec2:DeleteSecurityGroup",
"ec2:DeleteSnapshot",
"ec2:DeleteTags",
"ec2:DeleteVolume",
"ec2:DeregisterImage",
"ec2:DescribeAddresses",
"ec2:DescribeAddressesAttribute",
"ec2:DescribeAvailabilityZones",
"ec2:DescribeFleetHistory",
"ec2:DescribeFleetInstances",
"ec2:DescribeFleets",
"ec2:DescribeHosts",
"ec2:DescribeIamInstanceProfileAssociations",
"ec2:DescribeImageAttribute",
"ec2:DescribeImages",
"ec2:DescribeInstanceAttribute",
"ec2:DescribeInstanceCreditSpecifications",
"ec2:DescribeInstanceStatus",
"ec2:DescribeInstances",
"ec2:DescribeKeyPairs",
"ec2:DescribeLaunchTemplateVersions",
"ec2:DescribeLaunchTemplates",
"ec2:DescribeManagedPrefixLists",
"ec2:DescribeNetworkInterfaceAttribute",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribeNetworkInterfacePermissions",
"ec2:DescribePlacementGroups",
"ec2:DescribePrefixLists",
"ec2:DescribeSecurityGroupReferences",
"ec2:DescribeSecurityGroupRules",
"ec2:DescribeSecurityGroups",
"ec2:DescribeSnapshotAttribute",
"ec2:DescribeSnapshotTierStatus",
"ec2:DescribeSnapshots",
"ec2:DescribeSpotFleetInstances",
"ec2:DescribeSpotFleetRequestHistory",
"ec2:DescribeSpotFleetRequests",
"ec2:DescribeStaleSecurityGroups",
"ec2:DescribeSubnets",
"ec2:DescribeTags",
"ec2:DescribeVolumeAttribute",
"ec2:DescribeVolumeStatus",
"ec2:DescribeVolumes",
"ec2:DescribeVpcAttribute",
"ec2:DescribeVpcEndpointConnections",
"ec2:DescribeVpcEndpointServices",
"ec2:DescribeVpcEndpointServiceConfigurations",
"ec2:DescribeVpcEndpointServicePermissions",
"ec2:DescribeVpcEndpoints",
"ec2:DescribeVpcs",
"ec2:DetachNetworkInterface",
"ec2:DetachVolume",
"ec2:DisassociateAddress",
"ec2:DisassociateIamInstanceProfile",
"ec2:EnableVolumeIO",
"ec2:GetLaunchTemplateData",
"ec2:GetManagedPrefixListAssociations",
"ec2:GetManagedPrefixListEntries",
"ec2:ImportKeyPair",
"ec2:ModifyAddressAttribute",
"ec2:ModifyFleet",
"ec2:ModifyHosts",
"ec2:ModifyImageAttribute",
"ec2:ModifyInstanceAttribute",
"ec2:ModifyInstanceCreditSpecification",
"ec2:ModifyInstanceMetadataOptions",
"ec2:ModifyInstancePlacement",
"ec2:ModifyLaunchTemplate",
"ec2:ModifyManagedPrefixList",
"ec2:ModifyNetworkInterfaceAttribute",
"ec2:ModifyPrivateDnsNameOptions",
"ec2:ModifySecurityGroupRules",
"ec2:ModifySnapshotAttribute",
"ec2:ModifySnapshotTier",
"ec2:ModifySpotFleetRequest",
"ec2:ModifyVolume",
"ec2:ModifyVolumeAttribute",
"ec2:MonitorInstances",
"ec2:RebootInstances",
"ec2:RegisterImage",
"ec2:ReleaseAddress",
"ec2:ReleaseHosts",
"ec2:RequestSpotFleet",
"ec2:ResetAddressAttribute",
"ec2:ResetImageAttribute",
"ec2:ResetInstanceAttribute",
"ec2:ResetNetworkInterfaceAttribute",
"ec2:ResetSnapshotAttribute",
"ec2:RestoreManagedPrefixListVersion",
"ec2:RestoreSnapshotTier",
"ec2:RevokeSecurityGroupEgress",
"ec2:RevokeSecurityGroupIngress",
"ec2:RunInstances",
"ec2:StartInstances",
"ec2:StopInstances",
"ec2:TerminateInstances",
"ec2:UnmonitorInstances",
"ec2:UpdateSecurityGroupRuleDescriptionsEgress",
"ec2:UpdateSecurityGroupRuleDescriptionsIngress",
"rds:AddRoleToDBCluster",
"rds:AddRoleToDBInstance",
"rds:AddTagsToResource",
"rds:AuthorizeDBSecurityGroupIngress",
"rds:CopyDBClusterParameterGroup",
"rds:CopyDBClusterSnapshot",
"rds:CopyDBParameterGroup",
"rds:CopyDBSnapshot",
"rds:CopyOptionGroup",
"rds:CreateDBCluster",
"rds:CreateDBClusterEndpoint",
"rds:CreateDBClusterParameterGroup",
"rds:CreateDBClusterSnapshot",
"rds:CreateDBInstance",
"rds:CreateDBInstanceReadReplica",
"rds:CreateDBParameterGroup",
"rds:CreateDBSnapshot",
"rds:CreateDBSecurityGroup",
"rds:CreateDBSubnetGroup",
"rds:CreateOptionGroup",
"rds:DeleteDBCluster",
"rds:DeleteDBClusterEndpoint",
"rds:DeleteDBClusterParameterGroup",
"rds:DeleteDBInstance",
"rds:DeleteDBParameterGroup",
"rds:DeleteDBSecurityGroup",
"rds:DeleteDBSubnetGroup",
"rds:DeleteOptionGroup",
"rds:DescribeDBClusterEndpoints",
"rds:DescribeDBClusterParameterGroups",
"rds:DescribeDBClusterParameters",
"rds:DescribeDBClusters",
"rds:DescribeDBClusterSnapshotAttributes",
"rds:DescribeDBClusterSnapshots",
"rds:DescribeDBEngineVersions",
"rds:DescribeDBInstanceAutomatedBackups",
"rds:DescribeDBInstances",
"rds:DescribeDBLogFiles",
"rds:DescribeDBParameterGroups",
"rds:DescribeDBParameters",
"rds:DescribeDBSecurityGroups",
"rds:DescribeDBSnapshotAttributes",
"rds:DescribeDBSnapshots",
"rds:DescribeDBSubnetGroups",
"rds:DescribeOptionGroupOptions",
"rds:DescribeOptionGroups",
"rds:DescribePendingMaintenanceActions",
"rds:DescribeSourceRegions",
"rds:ListTagsForResource",
"rds:ModifyCurrentDBClusterCapacity",
"rds:ModifyDBCluster",
"rds:ModifyDBClusterEndpoint",
"rds:ModifyDBClusterParameterGroup",
"rds:ModifyDBInstance",
"rds:ModifyDBParameterGroup",
"rds:ModifyDBSubnetGroup",
"rds:ModifyOptionGroup",
"rds:PromoteReadReplica",
"rds:PromoteReadReplicaDBCluster",
"rds:RebootDBCluster",
"rds:RebootDBInstance",
"rds:RemoveRoleFromDBCluster",
"rds:RemoveRoleFromDBInstance",
"rds:RemoveTagsFromResource",
"rds:ResetDBClusterParameterGroup",
"rds:ResetDBParameterGroup",
"rds:RestoreDBClusterFromS3",
"rds:RestoreDBClusterFromSnapshot",
"rds:RestoreDBClusterToPointInTime",
"rds:RestoreDBInstanceFromDBSnapshot",
"rds:RestoreDBInstanceFromS3",
"rds:RestoreDBInstanceToPointInTime",
"rds:RevokeDBSecurityGroupIngress",
"rds:StartDBCluster",
"rds:StartDBInstance",
"rds:StopDBCluster",
"rds:StopDBInstance"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "*",
"Condition": {
"StringEquals": {
"iam:PassedToService": [
"backups.amazonaws.com",
"ec2.amazonaws.com",
"rds.amazonaws.com"
]
}
}
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"backup:Cr*",
"backup:De*",
"backup:Get*",
"backup:List*",
"backup:Put*VaultNot*",
"backup:St*",
"backup:*agRes*",
"backup:Upd*",
"ec2:All*Address",
"ec2:All*Hosts",
"ec2:*ssoc*Address",
"ec2:*ssoc*IamIns*",
"ec2:Attach*",
"ec2:Authorize*",
"ec2:CancelSpot*",
"ec2:C*teFleet",
"ec2:C*teImage",
"ec2:C*teKeyPair",
"ec2:C*teLaunch*",
"ec2:C*teMan*Pre*List",
"ec2:C*teNet*Int*e",
"ec2:C*tePla*Gr*",
"ec2:C*teS*",
"ec2:C*teTags",
"ec2:C*teVol*",
"ec2:De*eFleets",
"ec2:De*eNet*Int*",
"ec2:De*ePla*Group",
"ec2:De*eSec*",
"ec2:De*eSnap*",
"ec2:De*eTags",
"ec2:De*eVol*",
"ec2:Der*Im*",
"ec2:D*beA*",
"ec2:D*beFleet*",
"ec2:D*beH*",
"ec2:D*beIam*",
"ec2:D*beImage*",
"ec2:D*beInstance*",
"ec2:D*beK*",
"ec2:D*beL*",
"ec2:D*beManagedPrefix*",
"ec2:D*beP*",
"ec2:D*beSpotFleet*",
"ec2:D*beSubnets",
"ec2:D*beVpc*",
"ec2:Det*Net*Int*",
"ec2:Det*Vol*",
"ec2:EnableVolumeIO",
"ec2:GetLaunch*",
"ec2:GetMan*Pre*List*",
"ec2:Imp*KeyPair",
"ec2:M*fyA*",
"ec2:M*fyF*",
"ec2:M*fyH*",
"ec2:M*fyI*",
"ec2:M*fyL*",
"ec2:M*fyM*",
"ec2:M*fyN*",
"ec2:M*fyP*",
"ec2:M*fyS*",
"ec2:M*fyV*",
"ec2:*onitorIns*",
"ec2:Reboot*",
"ec2:Reg*rImage",
"ec2:R*seAddress",
"ec2:R*seHosts",
"ec2:Re*stSpotFleet",
"ec2:Res*",
"ec2:Revoke*",
"ec2:RunI*",
"ec2:St*Instances",
"ec2:Terminate*",
"ec2:UpdateSecurity*",
"rds:Add*",
"rds:Aut*",
"rds:Cop*",
"rds:Cre*",
"rds:Del*",
"rds:Des*",
"rds:Lis*",
"rds:Mod*",
"rds:Pro*",
"rds:Re*",
"rds:St*"
],
"Resource": "*"
},
{
"Effect": "Deny",
"Action": [
"backup:De*te*VaultLock*",
"backup:*VaultAccessPolicy*",
"backup:Upd*Glo*Set*",
"ec2:*Account*",
"ec2:*Bundle*",
"ec2:*Byoip*",
"ec2:*Classic*",
"ec2:*Datafeed*",
"ec2:*DefaultKms*",
"ec2:De*teNet*Per*",
"ec2:Des*VpcEnd*Not*",
"ec2:*Export*",
"ec2:*Fpga*",
"ec2:*Gateway*",
"ec2:*Imp*Image*",
"ec2:*Imp*Snap*",
"ec2:*Inst*Event*",
"ec2:*Ipam*",
"ec2:*Pool*",
"ec2:*Recycle*",
"ec2:*Vpn*",
"ec2:*Reserv*",
"ec2:C*teSubnet",
"ec2:D*be*Id*",
"ec2:M*fyAvail*ZoneGroup",
"ec2:M*fy*Default*",
"ec2:M*fy*Id*",
"ec2:M*fyInst*Maint*",
"ec2:M*fySubnet*",
"ec2:M*fyVp*",
"rds:*Account*",
"rds:*Activity*",
"rds:*Backtrack*",
"rds:*Custom*",
"rds:*Certifi*",
"rds:*Default*",
"rds:Del*Autom*",
"rds:Del*Snap*",
"rds:Des*Order*",
"rds:Desc*ValidDB*",
"rds:*Event*",
"rds:*Export*",
"rds:*GlobalClus*",
"rds:*Prox*",
"rds:*Reserved*",
"rds:*Subscription*",
"rds:M*fy*Snapshot*",
"rds:St*AutomatedBackups*"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "*",
"Condition": {
"StringEquals": {
"iam:PassedToService": [
"backups.amazonaws.com",
"ec2.amazonaws.com",
"rds.amazonaws.com"
]
}
}
}
]
}
! ec2:DescribeInstanceTypeOfferings DEFAULT_DENY ALLOW ec2:D*beInstance*
! ec2:DescribeInstanceTypes DEFAULT_DENY ALLOW ec2:D*beInstance*
! ec2:DescribeVolumesModifications DEFAULT_DENY ALLOW ec2:De*eVol*
! ec2:DescribeVpcPeeringConnections DEFAULT_DENY ALLOW ec2:D*beVpc*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment