예제 #1
0
    def test_write_template_with_sts_actions(self):
        cfg = {
            "mode":
            "crud",
            "name":
            "RoleNameWithCRUD",
            "sts": {
                "assume-role-with-web-identity":
                ["arn:aws:iam::123456789012:role/demo"]
            },
            "list": [
                "arn:aws:secretsmanager:us-east-1:123456789012:secret:anothersecret"
            ],
        }
        sid_group = SidGroup()
        rendered_policy = sid_group.process_template(cfg)
        desired_output = {
            "Version":
            "2012-10-17",
            "Statement": [{
                "Sid": "AssumeRoleWithWebIdentity",
                "Effect": "Allow",
                "Action": ["sts:AssumeRoleWithWebIdentity"],
                "Resource": ["arn:aws:iam::123456789012:role/demo"]
            }]
        }

        # print(json.dumps(rendered_policy, indent=4))
        self.assertEqual(rendered_policy, desired_output)
 def test_write_actions_policy_with_library_only(self):
     """test_write_actions_policy_with_library_only: Write an actions mode policy without using the command line at all (library only)"""
     db_session = connect_db("bundled")
     actions_template = get_actions_template_dict()
     # print(actions_template)
     actions_to_add = [
         "kms:CreateGrant",
         "kms:CreateCustomKeyStore",
         "ec2:AuthorizeSecurityGroupEgress",
         "ec2:AuthorizeSecurityGroupIngress",
     ]
     actions_template["mode"] = "actions"
     actions_template["actions"].extend(actions_to_add)
     # Modify it
     sid_group = SidGroup()
     minimize = None
     policy = sid_group.process_template(
         db_session, actions_template, minimize=minimize
     )
     self.maxDiff = None
     # print("desired_actions_policy")
     # print(json.dumps(desired_actions_policy, indent=4))
     # print("policy")
     print(json.dumps(policy, indent=4))
     self.assertDictEqual(desired_actions_policy, policy)
예제 #3
0
 def test_write_actions_policy_with_library_only(self):
     """test_write_actions_policy_with_library_only: Write an actions mode policy without using the command line at all (library only)"""
     actions_template = get_actions_template_dict()
     # print(actions_template)
     actions_to_add = [
         "kms:CreateGrant",
         "kms:CreateCustomKeyStore",
         "ec2:AuthorizeSecurityGroupEgress",
         "ec2:AuthorizeSecurityGroupIngress",
     ]
     actions_template["mode"] = "actions"
     actions_template["actions"].extend(actions_to_add)
     # Modify it
     sid_group = SidGroup()
     minimize = None
     policy = sid_group.process_template(actions_template,
                                         minimize=minimize)
     self.maxDiff = None
     print(json.dumps(policy, indent=4))
     expected_statement_ids = [
         "KmsPermissionsmanagementKey", "MultMultNone",
         "Ec2WriteSecuritygroup"
     ]
     # self.assertDictEqual(policy, desired_actions_policy)
     for statement in policy.get("Statement"):
         self.assertTrue(statement.get("Sid") in expected_statement_ids)
예제 #4
0
 def test_actions_test_case(self):
     cfg = {
         "mode":
         "actions",
         "name":
         "RoleNameWithCRUD",
         "description":
         "Why I need these privs",
         "role_arn":
         "arn:aws:iam::123456789012:role/RiskyEC2",
         "actions": [
             "kms:CreateGrant",
             "kms:CreateCustomKeyStore",
             "ec2:AuthorizeSecurityGroupEgress",
             "ec2:AuthorizeSecurityGroupIngress",
         ],
     }
     sid_group = SidGroup()
     output = sid_group.process_template(db_session, cfg)
     print(json.dumps(output, indent=4))
     desired_output = {
         "Version":
         "2012-10-17",
         "Statement": [
             {
                 "Sid":
                 "KmsPermissionsmanagementKey",
                 "Effect":
                 "Allow",
                 "Action": ["kms:CreateGrant"],
                 "Resource":
                 ["arn:${Partition}:kms:${Region}:${Account}:key/${KeyId}"],
             },
             {
                 "Sid":
                 "Ec2WriteSecuritygroup",
                 "Effect":
                 "Allow",
                 "Action": [
                     "ec2:AuthorizeSecurityGroupEgress",
                     "ec2:AuthorizeSecurityGroupIngress",
                 ],
                 "Resource": [
                     "arn:${Partition}:ec2:${Region}:${Account}:security-group/${SecurityGroupId}"
                 ],
             },
             {
                 "Sid":
                 "MultMultNone",
                 "Effect":
                 "Allow",
                 "Action":
                 ["cloudhsm:DescribeClusters", "kms:CreateCustomKeyStore"],
                 "Resource": ["*"],
             },
         ],
     }
     self.maxDiff = None
     print(output)
     self.assertDictEqual(output, desired_output)
 def test_write_with_template(self):
     cfg = {
         "mode":
         "crud",
         "name":
         "RoleNameWithCRUD",
         "permissions-management":
         ["arn:aws:s3:::example-org-s3-access-logs"],
         "list": [
             "arn:aws:secretsmanager:us-east-1:123456789012:secret:anothersecret"
         ],
     }
     sid_group = SidGroup()
     rendered_policy = sid_group.process_template(cfg)
     desired_output = {
         "Version":
         "2012-10-17",
         "Statement": [{
             "Sid":
             "S3PermissionsmanagementBucket",
             "Effect":
             "Allow",
             "Action": [
                 "s3:DeleteBucketPolicy",
                 "s3:PutBucketAcl",
                 "s3:PutBucketPolicy",
                 "s3:PutBucketPublicAccessBlock",
             ],
             "Resource": ["arn:aws:s3:::example-org-s3-access-logs"],
         }],
     }
     # print(json.dumps(rendered_policy, indent=4))
     self.assertEqual(rendered_policy, desired_output)
 def test_add_by_list_of_actions(self):
     actions_test_data_1 = ["kms:CreateCustomKeyStore", "kms:CreateGrant"]
     sid_group = SidGroup()
     sid_group.add_by_list_of_actions(actions_test_data_1)
     output = sid_group.get_rendered_policy()
     desired_output = {
         "Version":
         "2012-10-17",
         "Statement": [
             {
                 "Sid":
                 "KmsPermissionsmanagementKey",
                 "Effect":
                 "Allow",
                 "Action": ["kms:CreateGrant"],
                 "Resource":
                 ["arn:${Partition}:kms:${Region}:${Account}:key/${KeyId}"],
             },
             {
                 "Sid":
                 "MultMultNone",
                 "Effect":
                 "Allow",
                 "Action": [
                     "cloudhsm:DescribeClusters",
                     "kms:CreateCustomKeyStore",
                 ],
                 "Resource": ["*"],
             },
         ],
     }
     print(json.dumps(output, indent=4))
     self.maxDiff = None
     self.assertDictEqual(output, desired_output)
예제 #7
0
 def test_add_crud_with_wildcard(self):
     cfg = {
         "mode":
         "crud",
         "name":
         "RoleNameWithCRUD",
         "description":
         "Why I need these privs",
         "role_arn":
         "arn:aws:iam::123456789012:role/RiskyEC2",
         "permissions-management":
         ["arn:aws:s3:::example-org-s3-access-logs"],
         "wildcard": [
             # The first three are legitimately wildcard only.
             # Verify with `policy_sentry query action-table --service secretsmanager --wildcard-only`
             "ram:enablesharingwithawsorganization",
             "ram:getresourcepolicies",
             "secretsmanager:createsecret",
             # This last one can be "secret" ARN type OR wildcard. We want to prevent people from
             # bypassing this mechanism, while allowing them to explicitly
             # request specific privs that require wildcard mode. This next value -
             # secretsmanager:putsecretvalue - is an example of someone trying to beat the tool.
             "secretsmanager:putsecretvalue",
         ],
     }
     sid_group = SidGroup()
     rendered_policy = sid_group.process_template(db_session, cfg)
     desired_output = {
         "Version":
         "2012-10-17",
         "Statement": [
             {
                 "Sid":
                 "MultMultNone",
                 "Effect":
                 "Allow",
                 "Action": [
                     "ram:enablesharingwithawsorganization",
                     "ram:getresourcepolicies",
                     "secretsmanager:createsecret",
                 ],
                 "Resource": ["*"],
             },
             {
                 "Sid":
                 "S3PermissionsmanagementBucket",
                 "Effect":
                 "Allow",
                 "Action": [
                     "s3:deletebucketpolicy",
                     "s3:putbucketacl",
                     "s3:putbucketpolicy",
                     "s3:putbucketpublicaccessblock",
                 ],
                 "Resource": ["arn:aws:s3:::example-org-s3-access-logs"],
             },
         ],
     }
     # print(json.dumps(rendered_policy, indent=4))
     self.assertDictEqual(rendered_policy, desired_output)
예제 #8
0
 def test_minimize_rw_different(self):
     cfg = {
         "mode":
         "crud",
         "name":
         "",
         "read": [
             "arn:aws:ssm:us-east-1:123456789012:parameter/myparameter",
             "arn:aws:ssm:us-east-1:123456789012:parameter/myparameter2"
         ],
         "write": [
             "arn:aws:ssm:us-east-1:123456789012:parameter/myparameter",
             "arn:aws:ssm:us-east-1:123456789012:parameter/myparameter10"
         ]
     }
     sid_grp = SidGroup()
     write_format = sid_grp.process_template(cfg, minimize=1)
     write_format.pop('Version')
     self.assertEqual(len(write_format['Statement']), 2,
                      "More than one statement returned, expected 1")
     self.assertEqual(write_format['Statement'][0]['Action'],
                      ['ssm:getpar*'], "extra actions are returned")
     self.assertEqual(write_format['Statement'][0]['Resource'], cfg['read'],
                      "Wrong resources were returned")
     self.assertEqual(write_format['Statement'][1]['Action'],
                      ['ssm:deletepar*', 'ssm:la*', 'ssm:putp*'],
                      "extra actions are returned")
     self.assertEqual(write_format['Statement'][1]['Resource'],
                      cfg['write'], "Wrong resources were returned")
예제 #9
0
 def test_write_crud_policy_with_library_only(self):
     """test_write_crud_policy_with_library_only: Write a policy in CRUD mode without using the command line at all (library only)"""
     another_crud_template = get_crud_template_dict()
     wildcard_actions_to_add = [
         "kms:CreateCustomKeyStore",
         # "cloudhsm:describeclusters",
     ]
     another_crud_template["mode"] = "crud"
     another_crud_template["read"].append(
         "arn:aws:secretsmanager:us-east-1:123456789012:secret:mysecret")
     another_crud_template["write"].append(
         "arn:aws:secretsmanager:us-east-1:123456789012:secret:mysecret")
     another_crud_template["list"].append(
         "arn:aws:s3:::example-org-sbx-vmimport/stuff")
     another_crud_template["permissions-management"].append(
         "arn:aws:kms:us-east-1:123456789012:key/123456")
     another_crud_template["tagging"].append(
         "arn:aws:ssm:us-east-1:123456789012:parameter/test")
     another_crud_template["wildcard-only"]["single-actions"].extend(
         wildcard_actions_to_add)
     another_crud_template["sts"]["assume-role"].append(
         "arn:aws:iam::123456789012:role/demo")
     # Modify it
     sid_group = SidGroup()
     # minimize = None
     result = sid_group.process_template(another_crud_template)
     expected_statement_ids = [
         "MultMultNone", "SecretsmanagerReadSecret",
         "SecretsmanagerWriteSecret", "S3ListObject", "SsmTaggingParameter",
         "KmsPermissionsmanagementKey", "AssumeRole"
     ]
     self.maxDiff = None
     print(json.dumps(result, indent=4))
     for statement in result.get("Statement"):
         self.assertTrue(statement.get("Sid") in expected_statement_ids)
 def test_write_crud_policy_with_library_only(self):
     """test_write_crud_policy_with_library_only: Write a policy in CRUD mode without using the command line at all (library only)"""
     db_session = connect_db("bundled")
     crud_template = get_crud_template_dict()
     wildcard_actions_to_add = [
         "kms:CreateCustomKeyStore",
         # "cloudhsm:describeclusters",
     ]
     crud_template["mode"] = "crud"
     crud_template["read"].append(
         "arn:aws:secretsmanager:us-east-1:123456789012:secret:mysecret"
     )
     crud_template["write"].append(
         "arn:aws:secretsmanager:us-east-1:123456789012:secret:mysecret"
     )
     crud_template["list"].append("arn:aws:s3:::example-org-sbx-vmimport/stuff")
     crud_template["permissions-management"].append(
         "arn:aws:kms:us-east-1:123456789012:key/123456"
     )
     crud_template["wildcard"].extend(wildcard_actions_to_add)
     crud_template["tagging"].append(
         "arn:aws:ssm:us-east-1:123456789012:parameter/test"
     )
     # Modify it
     sid_group = SidGroup()
     minimize = None
     policy = sid_group.process_template(
         db_session, crud_template, minimize=minimize
     )
     # print("desired_crud_policy")
     # print(json.dumps(desired_crud_policy, indent=4))
     # print("policy")
     # print(json.dumps(policy, indent=4))
     self.maxDiff = None
     self.assertDictEqual(desired_crud_policy, policy)
예제 #11
0
    def test_exclude_actions_empty_sid_from_crud_output(self):
        sid_group = SidGroup()
        crud_with_exclude_actions_empty_sid = os.path.abspath(
            os.path.join(
                os.path.dirname(__file__),
                os.path.pardir,
                os.path.pardir,
                "examples",
                "yml",
                "crud-with-exclude-actions-empty-sid.yml",
            ))

        with open(crud_with_exclude_actions_empty_sid, "r") as this_yaml_file:
            crud_with_exclude_actions_empty_sid_cfg = yaml.safe_load(
                this_yaml_file)
        # crud_with_exclude_actions_empty_sid_cfg = {
        #     "mode": "crud",
        #     "write": [
        #         "arn:aws:s3:::test"
        #     ],
        #     "exclude-actions": [
        #         "iam:Pass*"
        #     ]
        # }

        # print(json.dumps(crud_with_exclude_actions_empty_sid_cfg, indent=4))
        sid_group.process_template(crud_with_exclude_actions_empty_sid_cfg)
        result = sid_group.get_rendered_policy(
            crud_with_exclude_actions_empty_sid_cfg)
        # print(json.dumps(result, indent=4))
        expected_result = {
            "Version":
            "2012-10-17",
            "Statement": [{
                "Sid":
                "S3WriteBucket",
                "Effect":
                "Allow",
                "Action": [
                    "s3:CreateBucket", "s3:DeleteBucket",
                    "s3:DeleteBucketOwnershipControls",
                    "s3:DeleteBucketWebsite", "s3:PutAccelerateConfiguration",
                    "s3:PutAnalyticsConfiguration", "s3:PutBucketCORS",
                    "s3:PutBucketLogging", "s3:PutBucketNotification",
                    "s3:PutBucketObjectLockConfiguration",
                    "s3:PutBucketOwnershipControls",
                    "s3:PutBucketRequestPayment", "s3:PutBucketVersioning",
                    "s3:PutBucketWebsite", "s3:PutEncryptionConfiguration",
                    "s3:PutIntelligentTieringConfiguration",
                    "s3:PutInventoryConfiguration",
                    "s3:PutLifecycleConfiguration",
                    "s3:PutMetricsConfiguration",
                    "s3:PutReplicationConfiguration"
                ],
                "Resource": ["arn:aws:s3:::test"]
            }]
        }
        self.assertDictEqual(result, expected_result)
예제 #12
0
 def test_add_crud_with_wildcard(self):
     cfg = {
         "mode": "crud",
         "name": "RoleNameWithCRUD",
         "permissions-management":
         ["arn:aws:s3:::example-org-s3-access-logs"],
         "wildcard-only": {
             "single-actions": [
                 # The first three are legitimately wildcard only.
                 # Verify with `policy_sentry query action-table --service secretsmanager --wildcard-only`
                 "ram:enablesharingwithawsorganization",
                 "ram:getresourcepolicies",
                 "secretsmanager:createsecret",
                 # This last one can be "secret" ARN type OR wildcard. We want to prevent people from
                 # bypassing this mechanism, while allowing them to explicitly
                 # request specific privs that require wildcard mode. This next value -
                 # secretsmanager:putsecretvalue - is an example of someone trying to beat the tool.
                 "secretsmanager:putsecretvalue",
             ],
         }
     }
     sid_group = SidGroup()
     output = sid_group.process_template(db_session, cfg)
     desired_output = {
         "Version":
         "2012-10-17",
         "Statement": [
             {
                 "Sid":
                 "MultMultNone",
                 "Effect":
                 "Allow",
                 "Action": [
                     "ram:EnableSharingWithAwsOrganization",
                     "ram:GetResourcePolicies",
                     "secretsmanager:CreateSecret",
                 ],
                 "Resource": ["*"],
             },
             {
                 "Sid":
                 "S3PermissionsmanagementBucket",
                 "Effect":
                 "Allow",
                 "Action": [
                     "s3:DeleteBucketPolicy",
                     "s3:PutBucketAcl",
                     "s3:PutBucketPolicy",
                     "s3:PutBucketPublicAccessBlock",
                 ],
                 "Resource": ["arn:aws:s3:::example-org-s3-access-logs"],
             },
         ],
     }
     self.maxDiff = None
     print("Yolo")
     print(json.dumps(output, indent=4))
     self.assertDictEqual(output, desired_output)
예제 #13
0
    def test_minimize_rw_same(self):
        cfg = {
            "mode":
            "crud",
            "name":
            "",
            "read": [
                "arn:aws:ssm:us-east-1:123456789012:parameter/myparameter",
                "arn:aws:ssm:us-east-1:123456789012:parameter/myparameter2"
            ],
            "write": [
                "arn:aws:ssm:us-east-1:123456789012:parameter/myparameter",
                "arn:aws:ssm:us-east-1:123456789012:parameter/myparameter2"
            ]
        }
        sid_grp = SidGroup()
        write_format = sid_grp.process_template(cfg, minimize=1)
        # print(json.dumps(write_format, indent=4))
        """
        the output will look like:

        {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Sid": "SsmParameterMyparameter",
                    "Effect": "Allow",
                    "Action": [
                        "ssm:getpar*",
                        "ssm:deletepar*",
                        "ssm:la*",
                        "ssm:putp*"
                    ],
                    "Resource": [
                        "arn:aws:ssm:us-east-1:123456789012:parameter/myparameter",
                        "arn:aws:ssm:us-east-1:123456789012:parameter/myparameter2"
                    ]
                }
            ]
        }
        """
        # To future-proof this unit test...
        # (1) check that there is only one SID so it was combined during minimization
        sid_names = get_sid_names_from_policy(write_format)
        self.assertEqual(len(sid_names), 1,
                         "More than one statement returned, expected 1")

        # (2) Check for the presence of certain actions that we know will be there
        expected_action = [
            'ssm:getpar*', 'ssm:deletepar*', 'ssm:la*', 'ssm:putp*'
        ]
        self.assertEqual(write_format['Statement'][0]['Action'],
                         expected_action, "extra actions are returned")
        self.assertEqual(write_format['Statement'][0]['Resource'], cfg['read'],
                         "Wrong resources were returned")
예제 #14
0
    def test_minimize_rw_different(self):
        cfg = {
            "mode": "crud",
            "name": "",
            "read": [
                "arn:aws:ssm:us-east-1:123456789012:parameter/myparameter",
                "arn:aws:ssm:us-east-1:123456789012:parameter/myparameter2"
            ],
            "write": [
                "arn:aws:ssm:us-east-1:123456789012:parameter/myparameter",
                "arn:aws:ssm:us-east-1:123456789012:parameter/myparameter10"
            ]
        }
        sid_grp = SidGroup()
        write_format = sid_grp.process_template(cfg, minimize=1)
        """
        Expected result:

        {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Sid": "SsmReadParameter",
                    "Effect": "Allow",
                    "Action": [
                        "ssm:getpar*"
                    ],
                    "Resource": [
                        "arn:aws:ssm:us-east-1:123456789012:parameter/myparameter",
                        "arn:aws:ssm:us-east-1:123456789012:parameter/myparameter2"
                    ]
                },
                {
                    "Sid": "SsmWriteParameter",
                    "Effect": "Allow",
                    "Action": [
                        "ssm:deletepar*",
                        "ssm:la*",
                        "ssm:putp*"
                    ],
                    "Resource": [
                        "arn:aws:ssm:us-east-1:123456789012:parameter/myparameter",
                        "arn:aws:ssm:us-east-1:123456789012:parameter/myparameter10"
                    ]
                }
            ]
        }
        """
        self.assertEqual(len(write_format['Statement']), 2, "More than two statements returned, expected 2")
        self.assertEqual(write_format['Statement'][0]['Action'], ['ssm:getpar*'], "extra actions are returned")
        self.assertEqual(write_format['Statement'][0]['Resource'], cfg['read'], "Wrong resources were returned")
        self.assertEqual(write_format['Statement'][1]['Action'], ['ssm:deletepar*', 'ssm:la*', 'ssm:putp*'],
                         "extra actions are returned")
        self.assertEqual(write_format['Statement'][1]['Resource'], cfg['write'], "Wrong resources were returned")
예제 #15
0
 def test_minimize_arn_case_7(self):
     """minimization test with ARN types from test_does_arn_match_case_1"""
     cfg = {
         "mode": "crud",
         "read": ["arn:aws:greengrass:${Region}:${Account}:/greengrass/definition/devices/1234567/versions/1"],
         "write": ["arn:aws:greengrass:${Region}:${Account}:/greengrass/definition/devices/1234567/versions/1"]
     }
     sid_group = SidGroup()
     results = sid_group.process_template(cfg, minimize=0)
     sid_names = get_sid_names_from_policy(results)
     self.assertEqual(len(sid_names), 1, "More than one statement returned, expected 1")
예제 #16
0
def write_policy_with_template(db_session, cfg, minimize=None):
    """
    This function is called by write-policy so the config can be passed in as a dict without running into a Click-related error. Use this function, rather than the write-policy function, if you are using Policy Sentry as a python library.

    :param db_session: SQL Alchemy database session object
    :param cfg: The loaded YAML as a dict. Must follow Policy Sentry dictated format.
    :param minimize: Minimize the resulting statement with *safe* usage of wildcards to reduce policy length. Set this to the character length you want - for example, 0, or 4. Defaults to none.
    """
    sid_group = SidGroup()
    policy = sid_group.process_template(db_session, cfg, minimize)
    return policy
예제 #17
0
 def test_minimize_arn_case_6(self):
     """minimization test with ARN types from test_does_arn_match_case_1"""
     cfg = {
         "mode": "crud",
         "read": ["arn:aws:states:region:account-id:execution:stateMachineName:executionName"],
         "write": ["arn:aws:states:region:account-id:execution:stateMachineName:executionName"]
     }
     sid_group = SidGroup()
     results = sid_group.process_template(cfg, minimize=0)
     sid_names = get_sid_names_from_policy(results)
     self.assertEqual(len(sid_names), 1, "More than one statement returned, expected 1")
예제 #18
0
 def test_minimize_arn_case_1(self):
     """minimization test with ARN types from test_does_arn_match_case_1"""
     cfg = {
         "mode": "crud",
         "read": ["arn:aws:codecommit:us-east-1:123456789012:MyDemoRepo"],
         "write": ["arn:aws:codecommit:us-east-1:123456789012:MyDemoRepo"]
     }
     sid_group = SidGroup()
     results = sid_group.process_template(cfg, minimize=0)
     sid_names = get_sid_names_from_policy(results)
     self.assertEqual(len(sid_names), 1, "More than one statement returned, expected 1")
예제 #19
0
 def test_minimize_arn_case_3(self):
     """minimization test with ARN types from test_does_arn_match_case_1"""
     cfg = {
         "mode": "crud",
         "read": ["arn:aws:kinesis:us-east-1:account-id:firehose/myfirehose/consumer/someconsumer:${ConsumerCreationTimpstamp}"],
         "write": ["arn:aws:kinesis:us-east-1:account-id:firehose/myfirehose/consumer/someconsumer:${ConsumerCreationTimpstamp}"]
     }
     sid_group = SidGroup()
     results = sid_group.process_template(cfg, minimize=0)
     sid_names = get_sid_names_from_policy(results)
     self.assertEqual(len(sid_names), 1, "More than one statement returned, expected 1")
예제 #20
0
def write_policy_with_template(cfg, minimize=None):
    """
    This function is called by write-policy so the config can be passed in as a dict without running into a Click-related error. Use this function, rather than the write-policy function, if you are using Policy Sentry as a python library.

    Arguments:
        cfg: The loaded YAML as a dict. Must follow Policy Sentry dictated format.
        minimize: Minimize the resulting statement with *safe* usage of wildcards to reduce policy length. Set this to the character length you want - for example, 0, or 4. Defaults to none.
    Returns:
        Dictionary: The JSON policy
    """
    if minimize is not None and minimize < 0:
        minimize = None
    sid_group = SidGroup()
    policy = sid_group.process_template(cfg, minimize)
    return policy
예제 #21
0
    def test_minimize_arn_case_bucket(self):
        cfg = {
            "mode": "crud",
            "read": ["arn:aws:s3:::bucket_name"],
            "write": ["arn:aws:s3:::bucket_name"]
        }
        sid_group = SidGroup()
        results = sid_group.process_template(cfg, minimize=0)

        # print(json.dumps(results, indent=4))
        # To future-proof this unit test...
        # (1) check that there is only one SID so it was combined during minimization
        sid_names = get_sid_names_from_policy(results)
        # For S3, it does require iam:PassRole lol because of s3:PutReplicationConfiguration requiring it as an action
        self.assertEqual(len(sid_names), 2, "More than 2 statements returned, expected 2")
예제 #22
0
 def test_sid_group_override(self):
     sid_group = SidGroup()
     output = sid_group.process_template(crud_with_override_template_cfg)
     self.maxDiff = None
     desired_output = {
         "Version": "2012-10-17",
         "Statement": [
             {
                 "Sid": "MultMultNone",
                 "Effect": "Allow",
                 "Action": [
                     "secretsmanager:CreateSecret"
                 ],
                 "Resource": [
                     "*"
                 ]
             },
             {
                 "Sid": "S3PermissionsmanagementBucket",
                 "Effect": "Allow",
                 "Action": [
                     "s3:DeleteBucketPolicy",
                     "s3:PutBucketAcl",
                     "s3:PutBucketPolicy",
                     "s3:PutBucketPublicAccessBlock"
                 ],
                 "Resource": [
                     "arn:aws:s3:::example-org-s3-access-logs"
                 ]
             },
             {
                 "Sid": "SkipResourceConstraints",
                 "Effect": "Allow",
                 "Action": [
                     "ssm:GetParameter",
                     "ssm:GetParameters",
                     "ssm:GetParametersByPath"
                 ],
                 "Resource": [
                     "*"
                 ]
             }
         ]
     }
     print(json.dumps(output, indent=4))
     self.assertDictEqual(output, desired_output)
 def test_resource_restriction_plus_dependent_action(self):
     """
     test_resource_restriction_plus_dependent_action
     """
     # Given iam:generateorganizationsaccessreport with resource constraint, make sure these are added:
     #  organizations:DescribePolicy,organizations:ListChildren,organizations:ListParents,
     #  organizations:ListPoliciesForTarget,organizations:ListRoots,organizations:ListTargetsForPolicy
     actions_test_data_1 = ["iam:generateorganizationsaccessreport"]
     sid_group = SidGroup()
     sid_group.add_by_list_of_actions(actions_test_data_1)
     output = sid_group.get_rendered_policy()
     # print(json.dumps(rendered_policy, indent=4))
     desired_output = {
         "Version":
         "2012-10-17",
         "Statement": [
             {
                 "Effect":
                 "Allow",
                 "Action": [
                     "organizations:DescribePolicy",
                     "organizations:ListChildren",
                     "organizations:ListParents",
                     "organizations:ListPoliciesForTarget",
                     "organizations:ListRoots",
                     "organizations:ListTargetsForPolicy",
                 ],
                 "Resource": ["*"],
                 "Sid":
                 "MultMultNone",
             },
             {
                 "Sid":
                 "IamReadAccessreport",
                 "Effect":
                 "Allow",
                 "Action": ["iam:GenerateOrganizationsAccessReport"],
                 "Resource": [
                     "arn:${Partition}:iam::${Account}:access-report/${EntityPath}"
                 ],
             },
         ],
     }
     self.maxDiff = None
     print(json.dumps(output, indent=4))
     self.assertDictEqual(output, desired_output)
예제 #24
0
    def test_resource_restriction_plus_dependent_action_simple_2(self):
        """
        test_resource_restriction_plus_dependent_action_simple_2
        """
        # Given iam:generateorganizationsaccessreport with resource constraint, make sure these are added:
        #  organizations:DescribePolicy,organizations:ListChildren,organizations:ListParents,
        #  organizations:ListPoliciesForTarget,organizations:ListRoots,organizations:ListTargetsForPolicy

        sid_group = SidGroup()
        sid_group.add_by_arn_and_access_level(
            db_session, ["arn:aws:iam::000000000000:access-report/somepath"],
            "Read")
        output = sid_group.get_rendered_policy(db_session)
        desired_output = {
            "Version":
            "2012-10-17",
            "Statement": [
                {
                    "Sid":
                    "MultMultNone",
                    "Effect":
                    "Allow",
                    "Action": [
                        "organizations:DescribePolicy",
                        "organizations:ListChildren",
                        "organizations:ListParents",
                        "organizations:ListPoliciesForTarget",
                        "organizations:ListRoots",
                        "organizations:ListTargetsForPolicy",
                    ],
                    "Resource": ["*"],
                },
                {
                    "Sid":
                    "IamReadAccessreport",
                    "Effect":
                    "Allow",
                    "Action": ["iam:GenerateOrganizationsAccessReport"],
                    "Resource":
                    ["arn:aws:iam::000000000000:access-report/somepath"],
                },
            ],
        }
        print(json.dumps(output, indent=4))
        self.assertDictEqual(output, desired_output)
예제 #25
0
 def test_GH_364_remove_duplicates_from_minimize(self):
     cfg = {
         "mode": "crud",
         "read": ["arn:aws:rds:*:*:*:test-*"],
         "write": ["arn:aws:rds:*:*:*:test-*"],
         "list": ["arn:aws:rds:*:*:*:test-*"],
         "tagging": ["arn:aws:rds:*:*:*:test-*"],
         "permissions-management": ["arn:aws:rds:*:*:*:test-*"],
     }
     # Bug introduced in https://github.com/salesforce/policy_sentry/pull/252
     sid_group = SidGroup()
     results = sid_group.process_template(cfg, minimize=0)
     print(json.dumps(results, indent=4))
     actions = results["Statement"][0]["Action"]
     actions_set = set(actions)
     self.assertEqual(
         len(actions_set), len(actions),
         "There should be no duplicate strings in the actions.")
예제 #26
0
 def test_sid_group_override(self):
     sid_group = SidGroup()
     output = sid_group.process_template(crud_with_override_template_cfg)
     self.maxDiff = None
     desired_output = {
         "Version":
         "2012-10-17",
         "Statement": [{
             "Sid": "MultMultNone",
             "Effect": "Allow",
             "Action": ["ram:GetResourcePolicies"],
             "Resource": ["*"]
         }, {
             "Sid":
             "S3PermissionsmanagementBucket",
             "Effect":
             "Allow",
             "Action": [
                 "s3:DeleteBucketPolicy", "s3:PutBucketAcl",
                 "s3:PutBucketPolicy", "s3:PutBucketPublicAccessBlock"
             ],
             "Resource": ["arn:aws:s3:::example-org-s3-access-logs"]
         }, {
             "Sid":
             "SkipResourceConstraints",
             "Effect":
             "Allow",
             "Action": [
                 "ssm:GetParameter", "ssm:GetParameters",
                 "ssm:GetParametersByPath"
             ],
             "Resource": ["*"]
         }]
     }
     # print(json.dumps(output, indent=4))
     expected_statement_ids = [
         "MultMultNone", "S3PermissionsmanagementBucket",
         "SkipResourceConstraints"
     ]
     for statement in output.get("Statement"):
         self.assertTrue(statement.get("Sid") in expected_statement_ids)
예제 #27
0
 def test_minimize_rw_same_one(self):
     cfg = {
         "mode": "crud",
         "name": "",
         "read": [
             "arn:aws:ssm:us-east-1:123456789012:parameter/myparameter",
         ],
         "write": [
             "arn:aws:ssm:us-east-1:123456789012:parameter/myparameter",
         ]
     }
     sid_grp = SidGroup()
     write_format = sid_grp.process_template(cfg, minimize=0)
     """
     Expected result:
     {
         "Version": "2012-10-17",
         "Statement": [
             {
                 "Sid": "SsmMultParametermyparameter",
                 "Effect": "Allow",
                 "Action": [
                     "ssm:getpar*",
                     "ssm:deletepar*",
                     "ssm:la*",
                     "ssm:putp*"
                 ],
                 "Resource": [
                     "arn:aws:ssm:us-east-1:123456789012:parameter/myparameter"
                 ]
             }
         ]
     }
     """
     # To future-proof this unit test...
     # (1) check that there is only one SID so it was combined during minimization
     sid_names = get_sid_names_from_policy(write_format)
     self.assertEqual(len(sid_names), 1,
                      "More than one statement returned, expected 1")
예제 #28
0
 def test_write_with_template(self):
     cfg = {
         "mode":
         "crud",
         "name":
         "RoleNameWithCRUD",
         "description":
         "Why I need these privs",
         "role_arn":
         "arn:aws:iam::123456789012:role/RiskyEC2",
         "permissions-management":
         ["arn:aws:s3:::example-org-s3-access-logs"],
         "list": [
             "arn:aws:secretsmanager:us-east-1:123456789012:secret:anothersecret"
         ],
     }
     sid_group = SidGroup()
     rendered_policy = sid_group.process_template(db_session, cfg)
     desired_output = {
         "Version":
         "2012-10-17",
         "Statement": [{
             "Sid":
             "S3PermissionsmanagementBucket",
             "Effect":
             "Allow",
             "Action": [
                 "s3:deletebucketpolicy",
                 "s3:putbucketacl",
                 "s3:putbucketpolicy",
                 "s3:putbucketpublicaccessblock",
             ],
             "Resource": ["arn:aws:s3:::example-org-s3-access-logs"],
         }],
     }
     # print(json.dumps(rendered_policy, indent=4))
     self.assertEqual(rendered_policy, desired_output)
예제 #29
0
 def test_sid_group(self):
     desired_output = {
         "S3PermissionsmanagementBucket": {
             "arn": ["arn:aws:s3:::example-org-s3-access-logs"],
             "service":
             "s3",
             "access_level":
             "Permissions management",
             "arn_format":
             "arn:${Partition}:s3:::${BucketName}",
             "actions": [
                 "s3:DeleteBucketPolicy",
                 "s3:PutBucketAcl",
                 "s3:PutBucketPolicy",
                 "s3:PutBucketPublicAccessBlock",
             ],
             "conditions": [],
         }
     }
     sid_group = SidGroup()
     arn_list_from_user = ["arn:aws:s3:::example-org-s3-access-logs"]
     access_level = "Permissions management"
     sid_group.add_by_arn_and_access_level(db_session, arn_list_from_user,
                                           access_level)
     status = sid_group.get_sid_group()
     self.maxDiff = None
     # print(json.dumps(status, indent=4))
     self.assertEqual(status, desired_output)
     rendered_policy = sid_group.get_rendered_policy(db_session)
     desired_policy = {
         "Version":
         "2012-10-17",
         "Statement": [{
             "Sid":
             "S3PermissionsmanagementBucket",
             "Effect":
             "Allow",
             "Action": [
                 "s3:DeleteBucketPolicy",
                 "s3:PutBucketAcl",
                 "s3:PutBucketPolicy",
                 "s3:PutBucketPublicAccessBlock",
             ],
             "Resource": ["arn:aws:s3:::example-org-s3-access-logs"],
         }],
     }
     # print(json.dumps(rendered_policy, indent=4))
     self.maxDiff = None
     self.assertDictEqual(desired_policy, rendered_policy)
    def test_exclude_actions_from_crud_output(self):
        sid_group = SidGroup()
        crud_with_exclude_actions = os.path.abspath(
            os.path.join(
                os.path.dirname(__file__),
                os.path.pardir,
                os.path.pardir,
                "examples",
                "yml",
                "crud-with-exclude-actions.yml",
            ))

        with open(crud_with_exclude_actions, "r") as this_yaml_file:
            crud_with_exclude_actions_cfg = yaml.safe_load(this_yaml_file)
        # crud_with_exclude_actions_cfg = {
        #     "mode": "crud",
        #     "write": [
        #         "arn:aws:kms:us-east-1:123456789012:key/aaaa-bbbb-cccc"
        #     ],
        #     "exclude-actions": [
        #         "kms:Delete*"
        #     ]
        # }

        # print(json.dumps(crud_with_exclude_actions_cfg, indent=4))
        sid_group.process_template(crud_with_exclude_actions_cfg)
        result = sid_group.get_rendered_policy(crud_with_exclude_actions_cfg)
        print(json.dumps(result, indent=4))
        expected_result = {
            "Version":
            "2012-10-17",
            "Statement": [{
                "Sid":
                "KmsWriteKey",
                "Effect":
                "Allow",
                "Action": [
                    "kms:CancelKeyDeletion", "kms:CreateAlias", "kms:Decrypt",
                    "kms:EnableKey", "kms:EnableKeyRotation", "kms:Encrypt",
                    "kms:GenerateDataKey", "kms:GenerateDataKeyPair",
                    "kms:GenerateDataKeyPairWithoutPlaintext",
                    "kms:GenerateDataKeyWithoutPlaintext",
                    "kms:ImportKeyMaterial", "kms:ReEncryptFrom",
                    "kms:ReEncryptTo", "kms:Sign", "kms:UpdateAlias",
                    "kms:UpdateKeyDescription", "kms:Verify"
                ],
                "Resource":
                ["arn:aws:kms:us-east-1:123456789012:key/aaaa-bbbb-cccc"]
            }]
        }
        self.assertDictEqual(result, expected_result)

        crud_with_exclude_actions_cfg = {
            "mode":
            "crud",
            "write": ["arn:aws:kms:us-east-1:123456789012:key/aaaa-bbbb-cccc"],
            # This is really only because KMS is a special case.
            "exclude-actions": [
                "kms:Delete*", "kms:Disable*", "kms:Enable*", "kms:Generate*",
                "kms:Cancel*", "kms:Create*", "kms:Import*", "kms:ReEncrypt*",
                "kms:Sign*", "kms:Schedule*", "kms:Update*", "kms:Verify*"
            ]
        }
        sid_group.process_template(crud_with_exclude_actions_cfg)
        results = sid_group.get_rendered_policy()
        print(json.dumps(results, indent=4))
        expected_result = {
            "Version":
            "2012-10-17",
            "Statement": [{
                "Sid":
                "KmsWriteKey",
                "Effect":
                "Allow",
                "Action": ["kms:Decrypt", "kms:Encrypt"],
                "Resource":
                ["arn:aws:kms:us-east-1:123456789012:key/aaaa-bbbb-cccc"]
            }]
        }
        self.assertDictEqual(results, expected_result)