Ejemplo n.º 1
0
import unittest
import json
from policy_sentry.shared.database import connect_db
from policy_sentry.writing.sid_group import SidGroup
from policy_sentry.querying.actions import get_action_data
from policy_sentry.shared.constants import DATABASE_FILE_PATH

db_session = connect_db(DATABASE_FILE_PATH)


class SidGroupActionsTestCase(unittest.TestCase):
    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))
#!/usr/bin/env python
from policy_sentry.shared.database import connect_db
from policy_sentry.querying.conditions import get_condition_keys_for_service
import json

if __name__ == '__main__':
    db_session = connect_db('bundled')
    output = get_condition_keys_for_service(db_session, "cloud9")
    print(json.dumps(output, indent=4))
"""
Output:

[
    'cloud9:EnvironmentId',
    'cloud9:EnvironmentName',
    'cloud9:InstanceType',
    'cloud9:Permissions',
    'cloud9:SubnetId',
    'cloud9:UserArn'
]
"""
Ejemplo n.º 3
0
import unittest
from pathlib import Path
from policy_sentry.shared.arns import does_arn_match
from policy_sentry.shared.database import connect_db

home = str(Path.home())
config_directory = '/.policy_sentry/'
database_file_name = 'aws.sqlite3'
database_path = home + config_directory + database_file_name
db_session = connect_db(database_path)

# "Does Arn Match" tests
# See docs for this list: # https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#genref-arns
# Case 1: arn:partition:service:region:account-id:resource
# Case 2: arn:partition:service:region:account-id:resourcetype/resource
# Case 3: arn:partition:service:region:account-id:resourcetype/resource/qualifier
# Case 4: arn:partition:service:region:account-id:resourcetype/resource:qualifier
# Case 5: arn:partition:service:region:account-id:resourcetype:resource
# Case 6: arn:partition:service:region:account-id:resourcetype:resource:qualifier


class ArnsTestCase(unittest.TestCase):

    def test_does_arn_match_case_bucket(self):
        # Case 1: arn:partition:service:region:account-id:resource
        arn_to_test = "arn:aws:s3:::bucket_name"
        arn_in_database = "arn:aws:s3:::${BucketName}"
        self.assertTrue(does_arn_match(arn_to_test, arn_in_database))

    def test_does_arn_match_case_1(self):
        # Case 1: arn:partition:service:region:account-id:resource
Ejemplo n.º 4
0
def write_policy_dir(input_dir, output_dir, crud, minimize):
    """
    write_policy, but this time with an input directory of YML/YAML files, and an output directory for all the JSON files
    """
    db_session = connect_db(DATABASE_FILE_PATH)
    input_dir = os.path.abspath(input_dir)
    output_dir = os.path.abspath(output_dir)

    if not crud:
        print(
            "Warning: If you are using ARNs from Terraform to generate your policies, "
            "try using the CRUD functionality instead of the default actions-based policy writing functionality."
        )

    if not minimize:
        print(
            "Warning: --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):
        print("Input directory is invalid")
        sys.exit()
    if not check_valid_file_path(output_dir):
        print("Output directory is invalid")
        sys.exit()

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

    print("Writing the policy JSON files from " + input_dir + " to " +
          output_dir + "...\n")
    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)
        # User supplies file containing resource-specific access levels
        if crud:
            policy = write_policy_with_access_levels(cfg, db_session, minimize)
        # User supplies file containing a list of IAM actions
        else:
            policy = write_policy_with_actions(cfg, db_session, minimize)
        print("Writing policy for " + base_name + '\n')

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

    print("Finished")
Ejemplo n.º 5
0
def action_table(name, service, access_level, condition, wildcard_only, fmt, log_level):
    """Query the Action Table from the Policy Sentry database"""
    set_log_level(logger, log_level)

    db_session = connect_db(DATABASE_FILE_PATH)
    # Actions on all services
    if service == "all":
        all_services = get_all_service_prefixes(db_session)
        if access_level:
            level = transform_access_level_text(access_level)
            print(f"{access_level} actions across ALL services:\n")
            results = []
            for serv in all_services:
                output = get_actions_with_access_level(db_session, serv, level)
                results.extend(output)
            print(yaml.dump(results)) if fmt == "yaml" else [
                print(result) for result in results
            ]
        # Get a list of all services in the database
        else:
            print("All services in the database:\n")
            print(yaml.dump(all_services)) if fmt == "yaml" else [
                print(item) for item in all_services
            ]
    elif name is None and access_level and not wildcard_only:
        print(
            f"All IAM actions under the {service} service that have the access level {access_level}:"
        )
        level = transform_access_level_text(access_level)
        output = get_actions_with_access_level(db_session, service, level)
        print(yaml.dump(output)) if fmt == "yaml" else [
            print(json.dumps(output, indent=4))
        ]
    elif name is None and access_level and wildcard_only:
        print(
            f"{service} {access_level.upper()} actions that must use wildcards in the resources block:"
        )
        output = get_actions_at_access_level_that_support_wildcard_arns_only(
            db_session, service, access_level
        )
        print(yaml.dump(output)) if fmt == "yaml" else [
            print(json.dumps(output, indent=4))
        ]
    # Get a list of all IAM actions under the service that support the specified condition key.
    elif condition:
        print(
            f"IAM actions under {service} service that support the {condition} condition only:"
        )
        output = get_actions_matching_condition_key(db_session, service, condition)
        print(yaml.dump(output)) if fmt == "yaml" else [
            print(json.dumps(output, indent=4))
        ]
    # Get a list of IAM Actions under the service that only support resources = "*"
    # (i.e., you cannot restrict it according to ARN)
    elif wildcard_only:
        print(
            f"IAM actions under {service} service that support wildcard resource values only:"
        )
        output = get_actions_that_support_wildcard_arns_only(db_session, service)
        print(yaml.dump(output)) if fmt == "yaml" else [
            print(json.dumps(output, indent=4))
        ]
    elif name and access_level is None:
        output = get_action_data(db_session, service, name)
        print(yaml.dump(output)) if fmt == "yaml" else [
            print(json.dumps(output, indent=4))
        ]
    else:
        # Get a list of all IAM Actions available to the service
        action_list = get_actions_for_service(db_session, service)
        print(f"ALL {service} actions:")
        print(yaml.dump(action_list)) if fmt == "yaml" else [
            print(item) for item in action_list
        ]