Examples

Below you can find some examples on how PolicyGlass can be used to understand complex policies in a consistent way.

We’re going to use policy_shards_to_json() to make the output a bit easier to read.

Tip

Remember PolicyShard objects are not policies. They represent policies in an abstracted way that makes them easier to understand programmatically, the JSON output you see in the examples is not a policy you can use directly in AWS.

Simple

>>> from policyglass import Policy, dedupe_policy_shards, policy_shards_effect, policy_shards_to_json
>>> policy_a = Policy(**{
...     "Version": "2012-10-17",
...     "Statement": [
...         {
...             "Effect": "Allow",
...             "Action": [
...                 "s3:*"
...             ],
...             "Resource": "*"
...         }
...     ]
... })
>>> policy_b = Policy(**{
...     "Version": "2012-10-17",
...     "Statement": [
...         {
...             "Effect": "Deny",
...             "Action": [
...                 "s3:*"
...             ],
...             "Resource": "arn:aws:s3:::examplebucket/*"
...         }
...     ]
... })
>>> policy_shards = policy_shards_effect([*policy_a.policy_shards, *policy_b.policy_shards])
>>> print(policy_shards_to_json(policy_shards, exclude_defaults=True, indent=2))
[
   {
     "effective_action": {
       "inclusion": "s3:*"
     },
     "effective_resource": {
       "inclusion": "*",
       "exclusions": [
         "arn:aws:s3:::examplebucket/*"
       ]
     },
     "effective_principal": {
       "inclusion": {
         "type": "AWS",
         "value": "*"
       }
     }
   }
 ]
PolicyShard #1 (first dictonary in list) tells us:
  1. s3:* is allowed for all resources except arn:aws:s3:::examplebucket/*

What occurred:
  1. The resource from the deny was added to the allow’s EffectiveResource’s exclusions

De-duplicate

>>> from policyglass import Policy, dedupe_policy_shards, policy_shards_to_json
>>> policy_a = Policy(**{
...     "Version": "2012-10-17",
...     "Statement": [
...         {
...             "Effect": "Allow",
...             "Action": [
...                 "s3:*"
...             ],
...             "Resource": "*"
...         }
...     ]
... })
>>> policy_b = Policy(**{
...     "Version": "2012-10-17",
...     "Statement": [
...         {
...             "Effect": "Allow",
...             "Action": [
...                 "s3:*"
...             ],
...             "Resource": "*"
...         }
...     ]
... })
>>> policy_shards = dedupe_policy_shards([*policy_a.policy_shards, *policy_b.policy_shards])
>>> print(policy_shards_to_json(policy_shards, exclude_defaults=True, indent=2))
[
   {
     "effective_action": {
       "inclusion": "s3:*"
     },
     "effective_resource": {
       "inclusion": "*"
     },
     "effective_principal": {
       "inclusion": {
         "type": "AWS",
         "value": "*"
       }
     }
   }
 ]
PolicyShard #1 (first dictonary in list) tells us:
  1. s3:* is allowed on all resources.

What occurred:
  1. One of the two s3:* policy shards was removed because it was a duplicate.

Complex Single Policy

>>> from policyglass import Policy, dedupe_policy_shards, policy_shards_effect, policy_shards_to_json
>>> policy_a = Policy(**{
...     "Version": "2012-10-17",
...     "Statement": [
...         {
...             "Effect": "Allow",
...             "Action": [
...                 "s3:*",
...                 "s3:GetObject"
...             ],
...             "Resource": "*"
...         },
...         {
...             "Effect": "Deny",
...             "Action": [
...                 "s3:PutObject",
...             ],
...             "NotResource": "arn:aws:s3:::examplebucket/*",
...             "Condition": {
...                  "StringNotEquals": {
...                      "s3:x-amz-server-side-encryption": "AES256"
...                  }
...             }
...         }
...     ]
... })
>>> deduped_shards = dedupe_policy_shards(policy_a.policy_shards)
>>> shards_effect = policy_shards_effect(deduped_shards)
>>> print(policy_shards_to_json(shards_effect, exclude_defaults=True, indent=2))
[
   {
     "effective_action": {
       "inclusion": "s3:*",
       "exclusions": [
         "s3:PutObject"
       ]
     },
     "effective_resource": {
       "inclusion": "*"
     },
     "effective_principal": {
       "inclusion": {
         "type": "AWS",
         "value": "*"
       }
     }
   },
   {
     "effective_action": {
       "inclusion": "s3:PutObject"
     },
     "effective_resource": {
       "inclusion": "*",
       "exclusions": [
         "arn:aws:s3:::examplebucket/*"
       ]
     },
     "effective_principal": {
       "inclusion": {
         "type": "AWS",
         "value": "*"
       }
     },
     "not_conditions": [
       {
         "key": "StringNotEquals",
         "operator": "s3:x-amz-server-side-encryption",
         "values": [
           "AES256"
         ]
       }
     ]
   }
 ]

The output has two policy shards.

PolicyShard #1 (first dictionary in list) tells us:
  1. Allow s3:* except for s3:PutObject

  2. On all resources.

  3. No conditions

PolicyShard #2 (second dictionary in list) tells us:
  1. Allow s3:PutObject

  2. On all resources except arn:aws:s3:::examplebucket/*

  3. except If the condition applies.

What occurred:
  1. s3:GetObject was removed from the allow because it was totally within s3:*

  2. s3:PutObject was added to the EffectiveAction’s exclusions so it could be split out into a second PolicyShard.

  3. A new PolicyShard was created with s3:PutObject

  4. The deny’s condition became a not_condition on the new PolicyShard.