コード例 #1
0
 def test_eks_gh_155(self):
     """test_eks_gh_155: Test EKS issue raised in GH-155"""
     template_file_path = os.path.abspath(
         os.path.join(
             os.path.dirname(__file__),
             os.path.pardir,
             "files",
             "eks-service-wide.yml",
         )
     )
     cfg = read_yaml_file(template_file_path)
     result = write_policy_with_template(cfg)
     print(json.dumps(result, indent=4))
     expected_results = {
         "Version": "2012-10-17",
         "Statement": [
             {
                 "Sid": "MultMultNone",
                 "Effect": "Allow",
                 "Action": [
                     "eks:ListClusters",
                     "eks:CreateCluster"
                 ],
                 "Resource": [
                     "*"
                 ]
             }
         ]
     }
     self.assertDictEqual(result, expected_results)
コード例 #2
0
    def test_gh_204_multiple_resource_types_wildcards(self):
        """test_gh_204_multiple_resource_types_wildcards: Address github issue #204 not having unit tests"""
        crud_template = {
            "mode": "crud",
            'read': ["arn:aws:rds:us-east-1:123456789012:*:*"],
            'write': ["arn:aws:rds:us-east-1:123456789012:*:*"],
            'list': ["arn:aws:rds:us-east-1:123456789012:*:*"]
        }

        # Let's only check the read level ones, or that will get exhausting.
        expected_statement_ids = [
            "RdsReadDb",
            "RdsReadEs",
            "RdsReadOg",
            "RdsReadPg",
            "RdsReadProxy",
            "RdsReadRi",
            "RdsReadSecgrp",
            "RdsReadSnapshot",
            "RdsReadSubgrp",
            "RdsReadTargetgroup",
            "MultMultNone",
        ]
        # In the real world, we would want to minimize, but that would just result in two different Sids:
        #   RdsMult
        #   MultMultNone
        # And in this test, we are trying to verify them individually to make sure they are not excluded.
        # So we will skip --minimize just for this test.
        policy = write_policy_with_template(crud_template)
        statement_ids = []
        for statement in policy.get("Statement"):
            statement_ids.append(statement.get("Sid"))
        for expected_sid in expected_statement_ids:
            self.assertTrue(expected_sid in statement_ids)
コード例 #3
0
 def test_rds_policy_read_only(self):
     """test_rds_policy_read_only: Make sure that the RDS Policies work properly"""
     policy_file_path = os.path.abspath(
         os.path.join(
             os.path.dirname(__file__),
             os.path.pardir,
             os.path.pardir,
             "examples",
             "yml",
             "crud-rds-read.yml",
         )
     )
     cfg = read_yaml_file(policy_file_path)
     desired_output = {
         "Version": "2012-10-17",
         "Statement": [
             {
                 "Sid": "RdsReadDb",
                 "Effect": "Allow",
                 "Action": [
                     "rds:DownloadDBLogFilePortion",
                     "rds:ListTagsForResource"
                 ],
                 "Resource": [
                     "arn:aws:rds:us-east-1:123456789012:db:mydatabase"
                 ]
             }
         ]
     }
     policy = write_policy_with_template(cfg)
     print(json.dumps(policy, indent=4))
     self.assertDictEqual(desired_output, policy)
コード例 #4
0
 def test_empty_strings_in_access_level_categories(self):
     """
     test_empty_strings_in_access_level_categories: If the content of a list is an empty string, it should NOT sysexit
     :return:
     """
     crud_file_input = {
         "mode": "crud",
         "name": "RoleNameWithCRUD",
         "read": ["arn:aws:ssm:us-east-1:123456789012:parameter/test",],
         "write": ["arn:aws:ssm:us-east-1:123456789012:parameter/test",],
         "list": ["arn:aws:ssm:us-east-1:123456789012:parameter/test",],
         "tagging": [""],
         "permissions-management": [""],
     }
     desired_output = {
         "Version": "2012-10-17",
         "Statement": [
             {
                 "Sid": "SsmReadParameter",
                 "Effect": "Allow",
                 "Action": [
                     "ssm:GetParameter",
                     "ssm:GetParameterHistory",
                     "ssm:GetParameters",
                     "ssm:GetParametersByPath"
                 ],
                 "Resource": [
                     "arn:aws:ssm:us-east-1:123456789012:parameter/test"
                 ]
             },
             {
                 "Sid": "SsmWriteParameter",
                 "Effect": "Allow",
                 "Action": [
                     "ssm:DeleteParameter",
                     "ssm:DeleteParameters",
                     "ssm:LabelParameterVersion",
                     "ssm:PutParameter"
                 ],
                 "Resource": [
                     "arn:aws:ssm:us-east-1:123456789012:parameter/test"
                 ]
             },
             {
                 "Sid": "SsmListParameter",
                 "Effect": "Allow",
                 "Action": [
                     "ssm:ListTagsForResource"
                 ],
                 "Resource": [
                     "arn:aws:ssm:us-east-1:123456789012:parameter/test"
                 ]
             }
         ]
     }
     # with self.assertRaises(Exception):
     result = write_policy_with_template(crud_file_input)
     # print(json.dumps(result, indent=4))
     self.assertDictEqual(desired_output, result)
コード例 #5
0
 def test_wildcard_when_not_necessary(self):
     """test_wildcard_when_not_necessary: Attempts bypass of CRUD mode wildcard-only"""
     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",
             ],
         }
     }
     db_session = connect_db("bundled")
     output = write_policy_with_template(db_session, cfg)
     # print(json.dumps(output, indent=4))
     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(output)
     self.assertDictEqual(desired_output, output)
コード例 #6
0
def write_policy_dir(input_dir, output_dir, minimize, log_level):
    """
    write_policy, but this time with an input directory of YML/YAML files, and an output directory for all the JSON files
    """
    set_log_level(logger, log_level)

    db_session = connect_db(DATABASE_FILE_PATH)
    input_dir = os.path.abspath(input_dir)
    output_dir = os.path.abspath(output_dir)

    if not minimize:
        logger.warning(
            "Note: --minimize option is not set. If the policy is too large, "
            "it can hit the AWS IAM Policy character limit. "
            "We'll execute as-is, but try using `--minimize 0` functionality "
            "for production to optimize policy size.\n")
    # Construct the path
    # Get the list of files
    # Write a list of the names
    if not check_valid_file_path(input_dir):
        logger.critical("Input directory is invalid")
        sys.exit()
    if not check_valid_file_path(output_dir):
        logger.critical("Output directory is invalid")
        sys.exit()

    input_files = glob.glob(str(input_dir + "/*.yml"), recursive=False)
    if not input_files:
        logger.critical(
            "Directory is empty or does not have files with *.yml extension. "
            "Please check the folder contents and/or extension spelling.")

    logger.info("Writing the policy JSON files from %s to %s...\n", input_dir,
                output_dir)
    for yaml_file in input_files:
        # Get the name of the file, and strip the extension. This is what the
        # policy name will be
        base_name = os.path.basename(yaml_file)
        base_name_no_extension = os.path.splitext(
            os.path.basename(yaml_file))[0]
        cfg = read_yaml_file(yaml_file)
        policy = write_policy_with_template(db_session, cfg, minimize)
        logger.info("Writing policy for %s\n", base_name)

        target_file = str(output_dir + "/" + base_name_no_extension + ".json")
        if os.path.exists(target_file):
            logger.info(
                "Target file for %s.json exists in the target directory. "
                "Removing it and writing a new file.\n",
                target_file,
            )
            os.remove(target_file)
        write_json_file(target_file, policy)

    logger.info("Finished")
コード例 #7
0
 def test_empty_strings_in_access_level_categories(self):
     """
     test_empty_strings_in_access_level_categories: If the content of a list is an empty string, it should NOT sysexit
     :return:
     """
     crud_file_input = {
         "mode": "crud",
         "name": "RoleNameWithCRUD",
         "description": "Why I need these privs",
         "role_arn": "arn:aws:iam::123456789012:role/RiskyEC2",
         "read": [
             "arn:aws:ssm:us-east-1:123456789012:parameter/test",
         ],
         "write": [
             "arn:aws:ssm:us-east-1:123456789012:parameter/test",
         ],
         "list": [
             "arn:aws:ssm:us-east-1:123456789012:parameter/test",
         ],
         "tagging": [""],
         "permissions-management": [""],
     }
     desired_output = {
         "Version":
         "2012-10-17",
         "Statement": [{
             "Sid":
             "SsmReadParameter",
             "Effect":
             "Allow",
             "Action": [
                 "ssm:getparameter", "ssm:getparameterhistory",
                 "ssm:getparameters", "ssm:getparametersbypath",
                 "ssm:listtagsforresource"
             ],
             "Resource":
             ["arn:aws:ssm:us-east-1:123456789012:parameter/test"]
         }, {
             "Sid":
             "SsmWriteParameter",
             "Effect":
             "Allow",
             "Action": [
                 "ssm:deleteparameter", "ssm:deleteparameters",
                 "ssm:labelparameterversion", "ssm:putparameter"
             ],
             "Resource":
             ["arn:aws:ssm:us-east-1:123456789012:parameter/test"]
         }]
     }
     # with self.assertRaises(Exception):
     result = write_policy_with_template(db_session, crud_file_input)
     print(json.dumps(result, indent=4))
     self.assertDictEqual(desired_output, result)
コード例 #8
0
 def test_actions_missing_actions(self):
     """
     test_actions_missing_actions: write-policy actions if the actions block is missing
     :return:
     """
     cfg_with_missing_actions = {
         "mode": "actions",
         "name": "RoleNameWithActions",
     }
     with self.assertRaises(Exception):
         policy = write_policy_with_template(cfg_with_missing_actions)
コード例 #9
0
ファイル: app.py プロジェクト: dustye/policyguru
def write_crud_policy(event, context):
    request_data = json.loads(event.get("body"))

    crud_template = {
        "mode": "crud",
    }
    if "read" in request_data:
        crud_template["read"] = request_data.get("read")
    if "write" in request_data:
        crud_template["write"] = request_data.get("write")
    if "list" in request_data:
        crud_template["list"] = request_data.get("list")
    if "tagging" in request_data:
        crud_template["tagging"] = request_data.get("tagging")
    if "permissions-management" in request_data:
        crud_template["permissions-management"] = request_data.get(
            "permissions-management")

    # Wildcard only section
    crud_template["wildcard-only"] = {}
    if "service-read" in request_data:
        crud_template["wildcard-only"]["service-read"] = request_data.get(
            "service-read")
    if "service-write" in request_data:
        crud_template["wildcard-only"]["service-write"] = request_data.get(
            "service-write")
    if "service-list" in request_data:
        crud_template["wildcard-only"]["service-list"] = request_data.get(
            "service-list")
    if "service-tagging" in request_data:
        crud_template["wildcard-only"]["service-tagging"] = request_data.get(
            "service-tagging")
    if "service-permissions-management" in request_data:
        crud_template["wildcard-only"][
            "service-permissions-management"] = request_data.get(
                "service-permissions-management")
    if "single-actions" in request_data:
        crud_template["wildcard-only"]["single-actions"] = request_data.get(
            "single-actions")

    if "exclude-actions" in request_data:
        crud_template["exclude-actions"] = request_data.get("exclude-actions")

    if "skip-resource-constraints" in request_data:
        crud_template["skip-resource-constraints"] = request_data.get(
            "skip-resource-constraints")

    output = write_policy_with_template(crud_template)
    # logger.info(output)
    return output
コード例 #10
0
 def test_actions_missing_actions(self):
     """
     test_actions_missing_actions: write-policy actions if the actions block is missing
     :return:
     """
     cfg_with_missing_actions = {
         "mode": "actions",
         "name": "RoleNameWithActions",
         "description": "Why I need these privs",
         "role_arn": "arn:aws:iam::123456789102:role/RiskyEC2",
     }
     with self.assertRaises(Exception):
         policy = write_policy_with_template(db_session,
                                             cfg_with_missing_actions)
コード例 #11
0
ファイル: app.py プロジェクト: dustye/policyguru
def ui_response_handler(event, context):
    event = event['body']
    print("performing decode, event value is", event)
    event = parse_qs(event)
    print(event)
    output_data = {
        'mode': 'crud',
        'name': '',
        'read': [],
        'write': [],
        'list': [],
        'tagging': [],
        'permissions-management': [],
        'wildcard-only': {
            'single-actions': [],
            'service-read': [],
            'service-write': [],
            'service-list': [],
            'service-tagging': [],
            'service-permissions-management': []
        }
    }
    for key, val in event.items():
        indx = key.split('_')[-1]
        if 'arn' in key:
            if key.startswith('action'):
                action_name = event['action_name_' + indx][0]
                update_data = output_data
            else:
                action_name = event['wc_name_' + indx][0]
                update_data = output_data['wildcard-only']
            val = list(map(lambda x: x.strip(), unquote(val[0]).split(',')))
            update_data[action_name].extend(val)

    print("output data", output_data)

    return {
        "statusCode": 200,
        'headers': {
            'Access-Control-Allow-Headers':
            'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token',
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Credentials': True,
            'Access-Control-Allow-Methods': 'POST,GET',
            'Content-Type': 'application/json'
        },
        "body": json.dumps(write_policy_with_template(output_data))
    }
コード例 #12
0
    def test_allow_missing_access_level_categories_in_cfg(self):
        """
        test_allow_missing_access_level_categories_in_cfg: write-policy when the YAML file is missing access level categories. It should write a policy regardless.
        """

        crud_file_input = {
            "mode": "crud",
            "name": "RoleNameWithCRUD",
            "read": ["arn:aws:ssm:us-east-1:123456789012:parameter/test",],
            "write": ["arn:aws:ssm:us-east-1:123456789012:parameter/test",],
            "list": ["arn:aws:ssm:us-east-1:123456789012:parameter/test",],
        }
        self.maxDiff = None

        result = write_policy_with_template(crud_file_input)
        print(json.dumps(result, indent=4))
コード例 #13
0
 def test_allow_missing_name(self):
     """
     test_actions_missing_name: write-policy when the YAML file is missing a name
     :return:
     """
     cfg_with_missing_name = {
         "mode": "actions",
         "actions": [
             "kms:CreateGrant",
             "kms:CreateCustomKeyStore",
             "ec2:AuthorizeSecurityGroupEgress",
             "ec2:AuthorizeSecurityGroupIngress",
         ],
     }
     #  This should NOT raise an exception so leaving it as-is.
     policy = write_policy_with_template(cfg_with_missing_name)
コード例 #14
0
    def test_add_wildcard_only_actions_matching_services_and_access_level(
            self):
        """test_add_wildcard_only_actions_matching_services_and_access_level: We'd never write a policy like this
        IRL but doing this as a quality check against how it handles the database """
        policy_file_path = os.path.abspath(
            os.path.join(
                os.path.dirname(__file__),
                os.path.pardir,
                os.path.pardir,
                "examples",
                "yml",
                "crud-with-wildcard-service-level.yml",
            ))
        cfg = read_yaml_file(policy_file_path)

        output = write_policy_with_template(cfg)
        desired_output = {
            "Version":
            "2012-10-17",
            "Statement": [{
                "Sid":
                "MultMultNone",
                "Effect":
                "Allow",
                "Action": [
                    "ram:EnableSharingWithAwsOrganization",
                    "ram:GetResourcePolicies", "secretsmanager:CreateSecret",
                    "ecr:GetAuthorizationToken", "s3:GetAccessPoint",
                    "s3:GetAccountPublicAccessBlock", "s3:ListAccessPoints",
                    "s3:ListJobs"
                ],
                "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(output, indent=4))
        self.maxDiff = None
        self.assertDictEqual(output, desired_output)
コード例 #15
0
 def test_allow_missing_arn(self):
     """
     test_actions_missing_arn: write-policy actions command when YAML file block is missing an ARN
     :return:
     """
     cfg_with_missing_actions = {
         "mode": "actions",
         "name": "RoleNameWithActions",
         "actions": [
             "kms:CreateGrant",
             "kms:CreateCustomKeyStore",
             "ec2:AuthorizeSecurityGroupEgress",
             "ec2:AuthorizeSecurityGroupIngress",
         ],
     }
     #  This should NOT raise an exception so leaving it as-is.
     policy = write_policy_with_template(cfg_with_missing_actions)
コード例 #16
0
 def test_dynamodb_arn_policy_gh_215(self):
     """test_dynamodb_arn_matching_gh_215: Test writing a policy with DynamoDB"""
     template_file_path = os.path.abspath(
         os.path.join(
             os.path.dirname(__file__),
             os.path.pardir,
             "files",
             "dynamodb_gh_215.yml",
         ))
     cfg = read_yaml_file(template_file_path)
     results = write_policy_with_template(cfg)
     print(json.dumps(results, indent=4))
     expected_statement_ids = [
         "MultMultNone",
         "DynamodbReadTable",
         "DynamodbWriteTable",
     ]
     for statement in results.get("Statement"):
         self.assertTrue(statement.get("Sid") in expected_statement_ids)
コード例 #17
0
 def test_allow_missing_name(self):
     """
     test_actions_missing_name: write-policy when the YAML file is missing a name
     :return:
     """
     cfg_with_missing_name = {
         "mode":
         "actions",
         "description":
         "Why I need these privs",
         "role_arn":
         "arn:aws:iam::123456789102:role/RiskyEC2",
         "actions": [
             "kms:CreateGrant",
             "kms:CreateCustomKeyStore",
             "ec2:AuthorizeSecurityGroupEgress",
             "ec2:AuthorizeSecurityGroupIngress",
         ],
     }
     #  This should NOT raise an exception so leaving it as-is.
     policy = write_policy_with_template(db_session, cfg_with_missing_name)
コード例 #18
0
    def test_add_wildcard_only_actions_matching_services_and_access_level(
            self):
        """test_add_wildcard_only_actions_matching_services_and_access_level: We'd never write a policy like this
        IRL but doing this as a quality check against how it handles the database """
        policy_file_path = abspath(
            join(
                dirname(__file__),
                pardir + "/" + pardir +
                "/examples/yml/crud-with-wildcard-service-level.yml",
            ))
        cfg = read_yaml_file(policy_file_path)

        output = write_policy_with_template(db_session, cfg)
        print(json.dumps(output, indent=4))
        desired_output = {
            "Version":
            "2012-10-17",
            "Statement": [{
                "Sid":
                "MultMultNone",
                "Effect":
                "Allow",
                "Action": [
                    "ecr:GetAuthorizationToken", "s3:GetAccessPoint",
                    "s3:GetAccountPublicAccessBlock", "s3:ListAccessPoints"
                ],
                "Resource": ["*"]
            }, {
                "Sid":
                "S3PermissionsmanagementBucket",
                "Effect":
                "Allow",
                "Action": [
                    "s3:DeleteBucketPolicy", "s3:PutBucketAcl",
                    "s3:PutBucketPolicy", "s3:PutBucketPublicAccessBlock"
                ],
                "Resource": ["arn:aws:s3:::example-org-s3-access-logs"]
            }]
        }
        self.assertDictEqual(output, desired_output)
コード例 #19
0
 def test_rds_policy_read_only(self):
     """test_rds_policy_read_only: Make sure that the RDS Policies work properly"""
     policy_file_path = os.path.abspath(
         os.path.join(
             os.path.dirname(__file__),
             os.path.pardir,
             os.path.pardir,
             "examples",
             "yml",
             "crud-rds-read.yml",
         ))
     cfg = read_yaml_file(policy_file_path)
     desired_output = {
         "Version":
         "2012-10-17",
         "Statement": [{
             "Sid":
             "RdsReadDb",
             "Effect":
             "Allow",
             "Action": [
                 "rds:DownloadCompleteDBLogFile",
                 "rds:DownloadDBLogFilePortion", "rds:ListTagsForResource"
             ],
             "Resource":
             ["arn:aws:rds:us-east-1:123456789012:db:mydatabase"]
         }]
     }
     expected_actions = [
         "rds:DownloadCompleteDBLogFile", "rds:DownloadDBLogFilePortion",
         "rds:ListTagsForResource"
     ]
     output = write_policy_with_template(cfg)
     print(json.dumps(output, indent=4))
     expected_statement_ids = ["RdsReadDb"]
     for statement in output.get("Statement"):
         self.assertTrue(statement.get("Sid") in expected_statement_ids)
     for action in expected_actions:
         self.assertTrue(action in output["Statement"][0]["Action"])
コード例 #20
0
    def test_gh_204_multiple_resource_types_wildcards(self):
        """test_gh_204_multiple_resource_types_wildcards: Address github issue #204 not having unit tests"""
        crud_template = {
            "mode": "crud",
            'read': ["arn:aws:rds:us-east-1:123456789012:*:*"],
            'write': ["arn:aws:rds:us-east-1:123456789012:*:*"],
            'list': ["arn:aws:rds:us-east-1:123456789012:*:*"]
        }

        expected_results_file = os.path.abspath(
            os.path.join(
                os.path.dirname(__file__),
                os.path.pardir,
                "files",
                "test_gh_204_multiple_resource_types_wildcards.json",
            ))

        with open(expected_results_file, "r") as yaml_file:
            expected_results = json.load(yaml_file)
        result = write_policy_with_template(crud_template)
        # print(json.dumps(result, indent=4))
        print(len(result.get("Statement")))
        self.assertTrue(len(result.get("Statement")) > 40)
コード例 #21
0
 def test_gh_211_write_with_empty_access_level_lists(self):
     crud_template = get_crud_template_dict()
     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:::mybucket/stuff")
     # by commenting out the line below, you should not get an IndexError
     # crud_template['permissions-management'].append("arn:aws:kms:us-east-1:123456789012:key/123456")
     # crud_template['tagging'].append("arn:aws:ssm:us-east-1:123456789012:parameter/test")
     wildcard_actions_to_add = [
         "kms:createcustomkeystore", "cloudhsm:describeclusters"
     ]
     crud_template['wildcard-only']['single-actions'].extend(
         wildcard_actions_to_add)
     result = write_policy_with_template(crud_template)
     # print(json.dumps(result, indent=4))
     expected_statement_ids = [
         "MultMultNone",
         "SecretsmanagerReadSecret",
         "SecretsmanagerWriteSecret",
     ]
     for statement in result.get("Statement"):
         self.assertTrue(statement.get("Sid") in expected_statement_ids)
コード例 #22
0
    def test_add_wildcard_only_actions_matching_services_and_access_level(self):
        """test_add_wildcard_only_actions_matching_services_and_access_level: We'd never write a policy like this
        IRL but doing this as a quality check against how it handles the database """
        policy_file_path = os.path.abspath(
            os.path.join(
                os.path.dirname(__file__),
                os.path.pardir,
                os.path.pardir,
                "examples",
                "yml",
                "crud-with-wildcard-service-level.yml",
            )
        )
        cfg = read_yaml_file(policy_file_path)

        results = write_policy_with_template(cfg)

        # The Policy *should* look like this.

        # desired_output = {
        #     "Version": "2012-10-17",
        #     "Statement": [
        #         {
        #             "Sid": "MultMultNone",
        #             "Effect": "Allow",
        #             "Action": [
        #                 "ram:EnableSharingWithAwsOrganization",
        #                 "ram:GetResourcePolicies",
        #                 "ecr:GetAuthorizationToken",
        #                 "s3:GetAccessPoint",
        #                 "s3:GetAccountPublicAccessBlock",
        #                 "s3:ListAccessPoints",
        #                 "s3:ListJobs"
        #             ],
        #             "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(results, indent=4))
        self.maxDiff = None

        # To future-proof this unit test...
        # (1) check the Sid names
        sid_names = get_sid_names_from_policy(results)
        self.assertIn("MultMultNone", sid_names, "Sid is not in the list of expected Statement Ids")
        self.assertIn("S3PermissionsmanagementBucket", sid_names, "Sid is not in the list of expected Statement Ids")

        # (2) Check for the presence of certain actions that we know will be there
        statement_1 = get_statement_from_policy_using_sid(results, "MultMultNone")
        self.assertIn("ram:EnableSharingWithAwsOrganization", statement_1.get("Action"))
        self.assertIn("s3:GetAccountPublicAccessBlock", statement_1.get("Action"))

        statement_2 = get_statement_from_policy_using_sid(results, "S3PermissionsmanagementBucket")
        self.assertIn("s3:DeleteBucketPolicy", statement_2.get("Action"))
        self.assertIn("s3:PutBucketPolicy", statement_2.get("Action"))

        # (3) Check that the length of the list is at least the length that it is right now,
        # since we expect it to grow eventually
        self.assertTrue(len(statement_1.get("Action")) > 5)  # Size is 6 at time of writing
        self.assertTrue(len(statement_2.get("Action")) > 3)  # Size is 4 at time of writing
コード例 #23
0
 def test_rds_policy_read_write_list(self):
     """test_rds_policy_read_write_list: Make sure that the RDS Policies work properly for multiple levels"""
     policy_file_path = os.path.abspath(
         os.path.join(
             os.path.dirname(__file__),
             os.path.pardir,
             os.path.pardir,
             "examples",
             "yml",
             "crud-rds-mult.yml",
         )
     )
     cfg = read_yaml_file(policy_file_path)
     desired_output = {
         "Version": "2012-10-17",
         "Statement": [
             {
                 "Sid": "RdsReadDb",
                 "Effect": "Allow",
                 "Action": [
                     "rds:DownloadDBLogFilePortion",
                     "rds:ListTagsForResource"
                 ],
                 "Resource": [
                     "arn:aws:rds:us-east-1:123456789012:db:mydatabase"
                 ]
             },
             {
                 "Sid": "MultMultNone",
                 "Effect": "Allow",
                 "Action": [
                     "iam:PassRole"
                 ],
                 "Resource": [
                     "*"
                 ]
             },
             {
                 "Sid": "RdsWriteDb",
                 "Effect": "Allow",
                 "Action": [
                     "rds:AddRoleToDBInstance",
                     "rds:ApplyPendingMaintenanceAction",
                     "rds:CreateDBInstance",
                     "rds:CreateDBInstanceReadReplica",
                     "rds:CreateDBSnapshot",
                     "rds:DeleteDBInstance",
                     "rds:DeregisterDBProxyTargets",
                     "rds:ModifyDBInstance",
                     "rds:PromoteReadReplica",
                     "rds:RebootDBInstance",
                     "rds:RemoveRoleFromDBInstance",
                     "rds:RestoreDBInstanceFromDBSnapshot",
                     "rds:RestoreDBInstanceFromS3",
                     "rds:RestoreDBInstanceToPointInTime",
                     "rds:StartDBInstance",
                     "rds:StopDBInstance"
                 ],
                 "Resource": [
                     "arn:aws:rds:us-east-1:123456789012:db:mydatabase"
                 ]
             },
             {
                 "Sid": "RdsListDb",
                 "Effect": "Allow",
                 "Action": [
                     "rds:DescribeDBLogFiles",
                     "rds:DescribeDBProxyTargets",
                     "rds:DescribeDBSnapshots",
                     "rds:DescribePendingMaintenanceActions",
                     "rds:DescribeValidDBInstanceModifications"
                 ],
                 "Resource": [
                     "arn:aws:rds:us-east-1:123456789012:db:mydatabase"
                 ]
             }
         ]
     }
     expected_statement_ids = [
         "RdsReadDb",
         "MultMultNone",
         "RdsWriteDb",
         "RdsListDb"
     ]
     policy = write_policy_with_template(cfg)
     for statement in policy.get("Statement"):
         self.assertTrue(statement.get("Sid") in expected_statement_ids)
コード例 #24
0
#!/usr/bin/env python
from policy_sentry.shared.database import connect_db
from policy_sentry.writing.template import get_actions_template_dict
from policy_sentry.command.write_policy import write_policy_with_template
import json

if __name__ == '__main__':
    db_session = connect_db('bundled')
    actions_template = get_actions_template_dict()
    actions_to_add = [
        'kms:CreateGrant', 'kms:CreateCustomKeyStore',
        'ec2:AuthorizeSecurityGroupEgress', 'ec2:AuthorizeSecurityGroupIngress'
    ]
    actions_template['actions'].extend(actions_to_add)
    policy = write_policy_with_template(db_session, actions_template)
    print(json.dumps(policy, indent=4))
"""
Output:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "KmsPermissionsmanagementKmskey",
            "Effect": "Allow",
            "Action": [
                "kms:creategrant"
            ],
            "Resource": [
                "arn:${Partition}:kms:${Region}:${Account}:key/${KeyId}"
            ]
コード例 #25
0
 def test_dynamodb_arn_policy_gh_215(self):
     """test_dynamodb_arn_matching_gh_215: Test writing a policy with DynamoDB"""
     template_file_path = os.path.abspath(
         os.path.join(
             os.path.dirname(__file__),
             os.path.pardir,
             "files",
             "dynamodb_gh_215.yml",
         )
     )
     cfg = read_yaml_file(template_file_path)
     results = write_policy_with_template(cfg)
     print(json.dumps(results, indent=4))
     expected_results = {
         "Version": "2012-10-17",
         "Statement": [
             {
                 "Sid": "MultMultNone",
                 "Effect": "Allow",
                 "Action": [
                     "dynamodb:DescribeLimits",
                     "dynamodb:DescribeReservedCapacity",
                     "dynamodb:DescribeReservedCapacityOfferings",
                     "dynamodb:ListStreams",
                     "dynamodb:ListBackups",
                     "dynamodb:ListContributorInsights",
                     "dynamodb:ListGlobalTables",
                     "dynamodb:ListTables"
                 ],
                 "Resource": [
                     "*"
                 ]
             },
             {
                 "Sid": "DynamodbReadTable",
                 "Effect": "Allow",
                 "Action": [
                     "dynamodb:BatchGetItem",
                     "dynamodb:ConditionCheckItem",
                     "dynamodb:DescribeContinuousBackups",
                     "dynamodb:DescribeContributorInsights",
                     "dynamodb:DescribeTable",
                     "dynamodb:DescribeTableReplicaAutoScaling",
                     "dynamodb:DescribeTimeToLive",
                     "dynamodb:GetItem",
                     "dynamodb:ListTagsOfResource",
                     "dynamodb:Query",
                     "dynamodb:Scan"
                 ],
                 "Resource": [
                     "arn:aws:dynamodb:us-east-1:123456789123:table/mytable"
                 ]
             },
             {
                 "Sid": "DynamodbWriteTable",
                 "Effect": "Allow",
                 "Action": [
                     "dynamodb:BatchWriteItem",
                     "dynamodb:CreateBackup",
                     "dynamodb:CreateGlobalTable",
                     "dynamodb:CreateTable",
                     "dynamodb:CreateTableReplica",
                     "dynamodb:DeleteItem",
                     "dynamodb:DeleteTable",
                     "dynamodb:DeleteTableReplica",
                     "dynamodb:PutItem",
                     "dynamodb:RestoreTableFromBackup",
                     "dynamodb:RestoreTableToPointInTime",
                     "dynamodb:UpdateContinuousBackups",
                     "dynamodb:UpdateContributorInsights",
                     "dynamodb:UpdateGlobalTable",
                     "dynamodb:UpdateGlobalTableSettings",
                     "dynamodb:UpdateItem",
                     "dynamodb:UpdateTable",
                     "dynamodb:UpdateTableReplicaAutoScaling",
                     "dynamodb:UpdateTimeToLive"
                 ],
                 "Resource": [
                     "arn:aws:dynamodb:us-east-1:123456789123:table/mytable"
                 ]
             }
         ]
     }
     self.assertDictEqual(results, expected_results)
コード例 #26
0
async def write_iam_policy(item: WritePolicyInput):
    template = WritePolicyTemplate(item)
    output = write_policy_with_template(template.json)
    return output
コード例 #27
0
    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
    policy = write_policy_with_template(crud_template)
    print(json.dumps(policy, indent=4))
"""
Output:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "MultMultNone",
            "Effect": "Allow",
            "Action": [
                "kms:createcustomkeystore"
            ],
            "Resource": [
                "*"
コード例 #28
0
 def test_gh_211_write_with_empty_access_level_lists(self):
     expected_results = {
         "Version":
         "2012-10-17",
         "Statement": [{
             "Sid":
             "MultMultNone",
             "Effect":
             "Allow",
             "Action":
             ["cloudhsm:DescribeClusters", "kms:CreateCustomKeyStore"],
             "Resource": ["*"]
         }, {
             "Sid":
             "SecretsmanagerReadSecret",
             "Effect":
             "Allow",
             "Action": [
                 "secretsmanager:DescribeSecret",
                 "secretsmanager:GetResourcePolicy",
                 "secretsmanager:GetSecretValue",
                 "secretsmanager:ListSecretVersionIds"
             ],
             "Resource": [
                 "arn:aws:secretsmanager:us-east-1:123456789012:secret:mysecret"
             ]
         }, {
             "Sid":
             "SecretsmanagerWriteSecret",
             "Effect":
             "Allow",
             "Action": [
                 "secretsmanager:CancelRotateSecret",
                 "secretsmanager:CreateSecret",
                 "secretsmanager:DeleteSecret",
                 "secretsmanager:PutSecretValue",
                 "secretsmanager:RestoreSecret",
                 "secretsmanager:RotateSecret",
                 "secretsmanager:UpdateSecret",
                 "secretsmanager:UpdateSecretVersionStage"
             ],
             "Resource": [
                 "arn:aws:secretsmanager:us-east-1:123456789012:secret:mysecret"
             ]
         }]
     }
     crud_template = get_crud_template_dict()
     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:::mybucket/stuff")
     # by commenting out the line below, you should not get an IndexError
     # crud_template['permissions-management'].append("arn:aws:kms:us-east-1:123456789012:key/123456")
     # crud_template['tagging'].append("arn:aws:ssm:us-east-1:123456789012:parameter/test")
     wildcard_actions_to_add = [
         "kms:createcustomkeystore", "cloudhsm:describeclusters"
     ]
     crud_template['wildcard-only']['single-actions'].extend(
         wildcard_actions_to_add)
     result = write_policy_with_template(crud_template)
     # print(json.dumps(result, indent=4))
     self.assertDictEqual(result, expected_results)
コード例 #29
0
    def test_write_policy_input_schema(self):
        actions_for_resources_at_access_level = {
            "read": [],
            "write": [],
            "list": [],
            "tagging": [],
            "permissions-management": [],
        }
        actions_for_services_without_resource_constraint_support = {
            "single-actions": [],
            "read": [],
            "write": [],
            "list": [],
            "tagging": [],
            "permissions-management": [],
        }
        wildcard_only_section = ActionsForServicesWithoutResourceConstraintSupport(
            read=[],
            write=[],
            list_access=[],
            permissions_management=[],
            tagging=[],
            single_actions=["s3:ListAllMyBuckets"])
        actions_for_resources_at_access_level = ActionsForResourcesAtAccessLevel(
            read=["arn:aws:s3:::mybucket/*"],
            write=[],
            list_access=[],
            permissions_management=[],
            tagging=[],
        )

        write_policy_input = WritePolicyInput(
            name="test",
            actions_for_resources_at_access_level=
            actions_for_resources_at_access_level,
            actions_for_services_without_resource_constraint_support=
            wildcard_only_section,
            skip_resource_constraints=["s3:PutObject"],
            exclude_actions=["kms:Delete*"])
        template = WritePolicyTemplate(write_policy_input)
        results = write_policy_with_template(template.json)
        print(json.dumps(results, indent=4))
        expected_results = {
            "Version":
            "2012-10-17",
            "Statement": [{
                "Sid": "MultMultNone",
                "Effect": "Allow",
                "Action": ["s3:ListAllMyBuckets"],
                "Resource": ["*"]
            }, {
                "Sid":
                "S3ReadObject",
                "Effect":
                "Allow",
                "Action": [
                    "s3:GetObject", "s3:GetObjectAcl", "s3:GetObjectLegalHold",
                    "s3:GetObjectRetention", "s3:GetObjectTagging",
                    "s3:GetObjectTorrent", "s3:GetObjectVersion",
                    "s3:GetObjectVersionAcl",
                    "s3:GetObjectVersionForReplication",
                    "s3:GetObjectVersionTagging", "s3:GetObjectVersionTorrent"
                ],
                "Resource": ["arn:aws:s3:::mybucket/*"]
            }, {
                "Sid": "SkipResourceConstraints",
                "Effect": "Allow",
                "Action": ["s3:PutObject"],
                "Resource": ["*"]
            }]
        }
        self.assertListEqual(get_sid_names_from_policy(results),
                             get_sid_names_from_policy(expected_results))
コード例 #30
0
#!/usr/bin/env python

from policy_sentry.writing.template import get_actions_template_dict
from policy_sentry.command.write_policy import write_policy_with_template
import json

if __name__ == '__main__':

    actions_template = get_actions_template_dict()
    actions_to_add = [
        'kms:CreateGrant', 'kms:CreateCustomKeyStore',
        'ec2:AuthorizeSecurityGroupEgress', 'ec2:AuthorizeSecurityGroupIngress'
    ]
    actions_template['actions'].extend(actions_to_add)
    policy = write_policy_with_template(actions_template)
    print(json.dumps(policy, indent=4))
"""
Output:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "KmsPermissionsmanagementKmskey",
            "Effect": "Allow",
            "Action": [
                "kms:creategrant"
            ],
            "Resource": [
                "arn:${Partition}:kms:${Region}:${Account}:key/${KeyId}"
            ]