Package: aws-iam-utils
aws-iam-utilsaws-iam-utils is a Python library with some utility functions for working with AWS IAM policies. I wrote this because, although many awesome AWS utility libraries exist, there was no simple toolset I could find that brings them together for practical use when you want the minimum code/scripting to get things done, particularly without learning a complex API.Featuresaws-iam-utils allows you to:check if two policies provide the same permissions (taking account of wildcards)check the level of access a policy provides (i.e. list, read-only, write, tagging or permissions-management) so you can verify that a policy does what you think it doescombine two policies together (i.e. merge theirStatements)collapse multiple policies in order to minimise or enhance readability (see below)generate list-only, read-only, read-write or full-access policies for any AWS service (with built-in assertions that the generated policies are correct according to the checks above)simplify policies by changing arrays for Actions, Resources and Principals into strings if they contain only one itemSee example code below to get started.There is an extensive test suite covering all features. Remember it is your responsibility to use this code wisely and satisfy yourself that its outputs are secure for your needs.All the data that supports the policy generation and access levels comes from the excellentpolicyuniverseandpolicy_sentrylibraries, which in turn get their data from AWS's own API documentation.InstallationAs easy as:pip install aws-iam-utilsExamplesHere are simple examples for all the use cases above. More example code can be found in thetestsdirectory.Check if two policies are equalfromaws_iam_utils.checksimportpolicies_are_equalfirst_policy={"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":["s3:PutObject","s3:PutObjectVersionAcl","s3:PutObjectVersionTagging",],"Resource":"*",}]}second_policy={"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"s3:PutObject","Resource":"*",},{"Effect":"Allow","Action":["s3:PutObjectVersionAcl","s3:PutObjectVersionTagging",],"Resource":"*",}]}print(policies_are_equal(first_policy,second_policy))# TrueCheck the level of access a policy providesfromaws_iam_utils.checksimportis_list_only_policyfromaws_iam_utils.utilimportcreate_policyp=create_policy({"Effect":"Allow","Action":["s3:ListBucket","s3:ListBucketVersions","s3:GetObjectVersion",],"Resource":"*",})print(is_list_only_policy(p))# False (because GetObjectVersion is a read operation)There is alsois_read_only_policy()(which returns True if the policy allows only read and list operations), andis_read_write_policy()(which returns True if the policy allows only read, list and write operations, but not tagging or permissions management operations).Notice the call tocreate_policy()? This is a simple function that creates the boilerplateVersionandStatementfields for you, simply pass in one or moreStatements as dicts. It helps to cut down (just slightly) on repetitive code. The latest version (2012-10-17) is used by default but can be overridden withcreate_policy(..., version='new_version'). Usingcreate_policyis completely optional.Combine policies togetheraws-iam-utilsallows you to merge policy documents, which simply means concatenatingStatements together. This is useful for policies generated elsewhere (e.g. byaws_iam_utilsor other tools) that you want to use together.fromaws_iam_utils.combinerimportcombine_policy_statementsfirst_policy={"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":["s3:PutObject","s3:PutObjectVersionAcl","s3:PutObjectVersionTagging",],"Resource":"*",}]}second_policy={"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":["s3:PutObjectVersionAcl","s3:PutObjectVersionTagging",],"Resource":"*",}]}print(combine_policy_statements(first_policy,second_policy))# {#   "Version": "2012-10-17",#   "Statement": [#     {#       "Effect": "Allow",#       "Action": [#           "s3:PutObjectVersionAcl",#           "s3:PutObjectVersionTagging",#       ],#       "Resource": "*",#     },#     {#       "Effect": "Allow",#       "Action": [#           "s3:PutObject",#           "s3:PutObjectVersionAcl",#           "s3:PutObjectVersionTagging",#       ],#       "Resource": "*",#     }#   ]# }combine_policy_statementsis a simple concatenation ofStatements with no intelligence whatsoever. If you also want to mergeStatements together where it is safe to do so, see collapsing in the next section.Collapse policies togetherWherecombiningpolicies is a simple concatenation operation,collapsingone or more policies examines the statements and merges together those statements that apply the same effect to the same Principals, Resources and Conditions.For example, let's repeat the example we had above:fromaws_iam_utils.combinerimportcollapse_policy_statementsfirst_policy={"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":["s3:PutObject","s3:PutObjectVersionAcl","s3:PutObjectVersionTagging",],"Resource":"*",}]}second_policy={"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":["s3:PutObjectVersionAcl","s3:PutObjectVersionTagging",],"Resource":"*",}]}print(collapse_policy_statements(first_policy,second_policy))# {#   "Version": "2012-10-17",#   "Statement": [#     {#       "Effect": "Allow",#       "Action": [#           "s3:PutObjectVersionAcl",#           "s3:PutObjectVersionTagging",#           "s3:PutObject",#       ],#       "Resource": "*",#     }#   ]# }Note how any duplicates are removed, and because all the Actions related to the same Resource, they were merged. If the Resource differs, the merge would not take place. Effect, Principals and Conditions are also included in the comparison: if any of those differ, the statement is not merged.Generate policiesThis is a simple policy-generation API that generates policies for a particular service based on an access level (read, write, list, tagging or permissions management).fromaws_iam_utils.generatorimportgenerate_read_only_policy_for_serviceprint(generate_read_only_policy_for_service('kinesis'))# {#   "Version": "2012-10-17",#   "Statement": [#     {#       "Effect": "Allow",#       "Action": [#         "kinesis:Describe*",#         "kinesis:Get*",#         "kinesis:List*",#         "kinesis:Subscribe*"#       ],#       "Resource": "*"#     }#   ]# }The generation engine will by default try to use verb wildcards, as you see above. You can turn this off by calling the generate function withuse_wildcard_verbs=False. When using wildcards the generator verifies that the wildcards do not provide any extra permissions (e.g. wheres3:Put*would includes3:PutBucketPolicy) - if the wildcards would result in extra permissions being given beyond the access level requested, the entire actions list is returned instead.There is alsogenerate_read_write_policy_for_serviceandgenerate_list_only_policy_for_service, andgenerate_full_policy_for_service.You can now generate policies that cater to specific ARN types as well. For example, to create a policy that can read/write S3 objects, but not buckets:fromaws_iam_utils.generatorimportgenerate_read_write_policy_for_service_arn_typeprint(generate_read_write_policy_for_service_arn_type('s3','object'))# {#   "Version": "2012-10-17",#   "Statement": [#     {#       "Effect": "Allow",#       "Action": [#         "s3:AbortMultipartUpload",#         "s3:DeleteObject",#         "s3:DeleteObjectVersion",#         "s3:GetObject",#         "s3:GetObjectAcl",#         "s3:GetObjectAttributes",#         "s3:GetObjectLegalHold",#         "s3:GetObjectRetention",#         "s3:GetObjectTagging",#         "s3:GetObjectTorrent",#         "s3:GetObjectVersion",#         "s3:GetObjectVersionAcl",#         "s3:GetObjectVersionAttributes",#         "s3:GetObjectVersionForReplication",#         "s3:GetObjectVersionTagging",#         "s3:GetObjectVersionTorrent",#         "s3:InitiateReplication",#         "s3:ListMultipartUploadParts",#         "s3:PutObject",#         "s3:PutObjectLegalHold",#         "s3:PutObjectRetention",#         "s3:ReplicateDelete",#         "s3:ReplicateObject",#         "s3:RestoreObject"#       ],#       "Resource": "*"#     }#   ]# }DocumentationComing soon. In the meantime each function already has documentation - check the sources. For example usage, see the tests.LicenceMIT