Skip to main content

AWS IAM utility library

Project description

aws-iam-utils

aws-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.

Features

aws-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 does

  • combine two policies together (i.e. merge their Statements)

  • 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 item

See 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 excellent policyuniverse and policy_sentry libraries, which in turn get their data from AWS's own API documentation.

Installation

As easy as:

pip install aws-iam-utils

Examples

Here are simple examples for all the use cases above. More example code can be found in the tests directory.

Check if two policies are equal

from aws_iam_utils.checks import policies_are_equal

first_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))
# True

Check the level of access a policy provides

from aws_iam_utils.checks import is_list_only_policy
from aws_iam_utils.util import create_policy

p = 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 also is_read_only_policy() (which returns True if the policy allows only read and list operations), and is_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 to create_policy()? This is a simple function that creates the boilerplate Version and Statement fields for you, simply pass in one or more Statements 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 with create_policy(..., version='new_version'). Using create_policy is completely optional.

Combine policies together

aws-iam-utils allows you to merge policy documents, which simply means concatenating Statements together. This is useful for policies generated elsewhere (e.g. by aws_iam_utils or other tools) that you want to use together.

from aws_iam_utils.combiner import combine_policy_statements

first_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_statements is a simple concatenation of Statements with no intelligence whatsoever. If you also want to merge Statements together where it is safe to do so, see collapsing in the next section.

Collapse policies together

Where combining policies is a simple concatenation operation, collapsing one 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:

from aws_iam_utils.combiner import collapse_policy_statements

first_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 policies

This 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).

from aws_iam_utils.generator import generate_read_only_policy_for_service

print(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 with use_wildcard_verbs=False. When using wildcards the generator verifies that the wildcards do not provide any extra permissions (e.g. where s3:Put* would include s3: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 also generate_read_write_policy_for_service and generate_list_only_policy_for_service, and generate_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:

from aws_iam_utils.generator import generate_read_write_policy_for_service_arn_type

print(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": "*"
#     }
#   ]
# }

Documentation

Coming soon. In the meantime each function already has documentation - check the sources. For example usage, see the tests.

Licence

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aws-iam-utils-1.8.0.tar.gz (13.6 kB view details)

Uploaded Source

Built Distribution

aws_iam_utils-1.8.0-py3-none-any.whl (13.8 kB view details)

Uploaded Python 3

File details

Details for the file aws-iam-utils-1.8.0.tar.gz.

File metadata

  • Download URL: aws-iam-utils-1.8.0.tar.gz
  • Upload date:
  • Size: 13.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.0 CPython/3.10.5

File hashes

Hashes for aws-iam-utils-1.8.0.tar.gz
Algorithm Hash digest
SHA256 4679b892f31d94e3a9ceaa3ef5af2e61b429be90318d1b4e12cb1656d68e9603
MD5 63717095fdc73bec5d0f748baae1e443
BLAKE2b-256 f9b13831d820e9a784cb4c6a492188780758424e538d614f6a1d515b7cfcb1be

See more details on using hashes here.

File details

Details for the file aws_iam_utils-1.8.0-py3-none-any.whl.

File metadata

File hashes

Hashes for aws_iam_utils-1.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 93a980a5ffc9acdc69c29e4c166c0656d5f10d94338ed9dd57f555fb3db73411
MD5 663e8c04445d606638a81282926a454d
BLAKE2b-256 5f328d15fe02648b4bfcd7d2e0d2688711665c0348544de144cb09d9f3fe42af

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page