Example #1
0
def get_actions_that_support_wildcard_arns_only(service_prefix):
    """
    Get a list of actions that do not support restricting the action to resource ARNs.
    Set service to "all" to get a list of actions across all services.

    :param service_prefix: A single AWS service prefix, like `s3` or `kms`
    :return: A list of actions
    """
    results = []
    if service_prefix == "all":
        for some_prefix in all_service_prefixes:
            service_prefix_data = get_service_prefix_data(some_prefix)
            for some_action in service_prefix_data["privileges"]:
                if len(some_action["resource_types"]) == 1:
                    if some_action["resource_types"][0]["resource_type"] == "":
                        results.append(
                            f"{some_prefix}:{some_action['privilege']}")
    else:
        service_prefix_data = get_service_prefix_data(service_prefix)
        for some_action in service_prefix_data["privileges"]:
            if len(some_action["resource_types"]) == 1:
                for resource_type in some_action["resource_types"]:
                    if resource_type["resource_type"] == "":
                        results.append(
                            f"{service_prefix}:{some_action['privilege']}")
    return results
Example #2
0
def get_actions_matching_condition_key(service_prefix, condition_key):
    """
    Get a list of actions under a service that allow the use of a specified condition key

    :param service_prefix: A single AWS service prefix
    :param condition_key: The condition key to look for.
    :return: A list of actions
    """
    results = []
    if service_prefix == "all":
        for some_prefix in all_service_prefixes:
            service_prefix_data = get_service_prefix_data(some_prefix)
            for some_action in service_prefix_data["privileges"]:
                for some_resource_type in some_action["resource_types"]:
                    if condition_key in some_resource_type["condition_keys"]:
                        results.append(
                            f"{some_prefix}:{some_action['privilege']}")
    else:
        service_prefix_data = get_service_prefix_data(service_prefix)
        for some_action in service_prefix_data["privileges"]:
            for some_resource_type in some_action["resource_types"]:
                if condition_key in some_resource_type["condition_keys"]:
                    results.append(
                        f"{service_prefix}:{some_action['privilege']}")
    return results
Example #3
0
def get_actions_with_access_level(service_prefix, access_level):
    """
    Get a list of actions in a service under different access levels.

    Arguments:
        service_prefix: A single AWS service prefix, like `s3` or `kms`
        access_level: An access level as it is written in the database, such as 'Read', 'Write', 'List', 'Permisssions management', or 'Tagging'

    Returns:
        List: A list of actions with that access level and service prefix
    """
    results = []
    if service_prefix == "all":
        for some_prefix in all_service_prefixes:
            service_prefix_data = get_service_prefix_data(some_prefix)
            for action_name, action_data in service_prefix_data[
                    "privileges"].items():
                if action_data["access_level"] == access_level:
                    results.append(f"{some_prefix}:{action_data['privilege']}")
    else:
        service_prefix_data = get_service_prefix_data(service_prefix)
        for action_name, action_data in service_prefix_data[
                "privileges"].items():
            if action_data["access_level"] == access_level:
                results.append(f"{service_prefix}:{action_data['privilege']}")
    return results
Example #4
0
def get_actions_at_access_level_that_support_wildcard_arns_only(
        service_prefix, access_level):
    """
    Get a list of actions at an access level that do not support restricting the action to resource ARNs.
    Set service to "all" to get a list of actions across all services.

    Arguments:
        service_prefix: A single AWS service prefix, like `s3` or `kms`
        access_level: An access level as it is written in the database, such as 'Read', 'Write', 'List', 'Permisssions management', or 'Tagging'
    Returns:
        List: A list of actions at that access level that do not support resource ARN constraints
    """
    results = []
    if service_prefix == "all":
        for some_prefix in all_service_prefixes:
            service_prefix_data = get_service_prefix_data(some_prefix)
            for action_name, action_data in service_prefix_data[
                    "privileges"].items():
                if len(action_data["resource_types"]) == 1:
                    if (action_data["access_level"] == access_level
                            and action_data["resource_types"].get("")):
                        results.append(
                            f"{some_prefix}:{action_data['privilege']}")
    else:
        service_prefix_data = get_service_prefix_data(service_prefix)
        for action_name, action_data in service_prefix_data[
                "privileges"].items():
            if len(action_data["resource_types"]) == 1:
                if (action_data["access_level"] == access_level
                        and action_data["resource_types"].get("")):
                    results.append(
                        f"{service_prefix}:{action_data['privilege']}")
    return results
Example #5
0
def get_actions_matching_condition_key(service_prefix, condition_key):
    """
    Get a list of actions under a service that allow the use of a specified condition key

    Arguments:
        service_prefix: A single AWS service prefix
        condition_key: The condition key to look for.
    Returns:
        List: A list of actions
    """
    results = []
    if service_prefix == "all":
        for some_prefix in all_service_prefixes:
            service_prefix_data = get_service_prefix_data(some_prefix)
            for action_name, action_data in service_prefix_data[
                    "privileges"].items():
                for resource_name, resource_data in action_data[
                        "resource_types"].items():
                    if condition_key in resource_data["condition_keys"]:
                        results.append(
                            f"{service_prefix}:{action_data['privilege']}")
    else:
        service_prefix_data = get_service_prefix_data(service_prefix)
        for action_name, action_data in service_prefix_data[
                "privileges"].items():
            for resource_name, resource_data in action_data[
                    "resource_types"].items():
                if condition_key in resource_data["condition_keys"]:
                    results.append(
                        f"{service_prefix}:{action_data['privilege']}")
    return results
Example #6
0
def get_actions_that_support_wildcard_arns_only(service_prefix):
    """
    Get a list of actions that do not support restricting the action to resource ARNs.
    Set service to "all" to get a list of actions across all services.

    Arguments:
        service_prefix: A single AWS service prefix, like `s3` or `kms`

    Returns:
        List: A list of actions that do not support resource ARN constraints
    """
    results = []
    if service_prefix == "all":
        for some_prefix in all_service_prefixes:
            service_prefix_data = get_service_prefix_data(some_prefix)
            for action_name, action_data in service_prefix_data[
                    "privileges"].items():
                if len(action_data["resource_types"].keys()) == 1:
                    for resource_type in action_data["resource_types"]:
                        if resource_type == '':
                            results.append(f"{service_prefix}:{action_name}")
    else:
        service_prefix_data = get_service_prefix_data(service_prefix)
        for action_name, action_data in service_prefix_data[
                "privileges"].items():
            if len(action_data["resource_types"].keys()) == 1:
                for resource_type in action_data["resource_types"]:
                    if resource_type == '':
                        results.append(f"{service_prefix}:{action_name}")
    return results
Example #7
0
def get_actions_with_arn_type_and_access_level(service_prefix,
                                               resource_type_name,
                                               access_level):
    """
    Get a list of actions in a service under different access levels, specific to an ARN format.

    Arguments:
        service_prefix: A single AWS service prefix, like `s3` or `kms`
        resource_type_name: The ARN type name, like `bucket` or `key`
        access_level: Access level like "Read" or "List" or "Permissions management"
    Return:
        List: A list of actions that have that ARN type and Access level
    """
    service_prefix_data = get_service_prefix_data(service_prefix)
    results = []

    if resource_type_name == '*':
        return get_actions_at_access_level_that_support_wildcard_arns_only(
            service_prefix, access_level)

    if service_prefix == "all":
        for some_prefix in all_service_prefixes:
            service_prefix_data = get_service_prefix_data(some_prefix)
            for action_name, action_data in service_prefix_data[
                    "privileges"].items():
                if action_data["access_level"] == access_level:
                    for resource_name, resource_data in action_data[
                            "resource_types"].items():
                        this_resource_type = resource_data[
                            "resource_type"].strip("*")
                        if this_resource_type.lower(
                        ) == resource_type_name.lower():
                            results.append(
                                f"{service_prefix}:{action_data['privilege']}")
                            break
    else:
        for action_name, action_data in service_prefix_data[
                "privileges"].items():
            if action_data["access_level"] == access_level:
                for resource_name, resource_data in action_data[
                        "resource_types"].items():
                    this_resource_type = resource_data["resource_type"].strip(
                        "*")
                    if this_resource_type.lower() == resource_type_name.lower(
                    ):
                        results.append(
                            f"{service_prefix}:{action_data['privilege']}")
                        break
    return results
Example #8
0
    def update_database_by_matching_compliance_names_with_iam_names(
            self, db_session, transformed_scraping_database):
        """
        The names of AWS services in the compliance pages vary; let's change the names of those services to directly
        match the names of the services as listed on the AWS IAM pages.
        """
        for standard in self.standard_names(db_session):

            # The service name in IAM-land
            iam_service_names = {}
            for service_prefix in ALL_SERVICE_PREFIXES:
                iam_service_names[service_prefix] = get_service_prefix_data(
                    service_prefix)["service_name"]

            # The service name in compliance land
            compliance_service_names = (
                transformed_scraping_database.
                get_service_names_matching_compliance_standard(
                    db_session, standard))
            for iam_service_prefix in list(iam_service_names.keys()):
                iam_name = iam_service_names[iam_service_prefix]
                compliance_names = list(compliance_service_names.keys())
                if iam_name in compliance_names:
                    self.update_compliance_status(
                        db_session=db_session,
                        service_prefix=
                        iam_service_prefix,  # this is the IAM prefix
                        compliance_standard=standard,
                        status="true",
                    )
Example #9
0
def get_actions_matching_arn(arn):
    """
    Given a user-supplied ARN, get a list of all actions that correspond to that ARN.

    Arguments:
        arn: A user-supplied arn
    Returns:
        List: A list of all actions that can match it.
    """
    raw_arns = get_matching_raw_arns(arn)
    results = []
    for raw_arn in raw_arns:
        resource_type_name = get_resource_type_name_with_raw_arn(raw_arn)
        service_prefix = get_service_from_arn(raw_arn)
        service_prefix_data = get_service_prefix_data(service_prefix)
        for action_name, action_data in service_prefix_data[
                "privileges"].items():
            # for some_action in service_prefix_data["privileges"]:
            for resource_name, resource_data in action_data[
                    "resource_types"].items():
                this_resource_type = resource_data["resource_type"].strip("*")
                if this_resource_type.lower() == resource_type_name.lower():
                    results.append(
                        f"{service_prefix}:{action_data['privilege']}")
    results = list(dict.fromkeys(results))
    results.sort()
    return results
Example #10
0
def get_all_actions(lowercase=False):
    """
    Gets a huge list of all IAM actions. This is used as part of the policyuniverse approach to minimizing
    IAM Policies to meet AWS-mandated character limits on policies.

    :param lowercase: Set to true to have the list of actions be in all lowercase strings.
    :return: A list of all actions present in the database.
    """
    all_actions = set()

    all_service_prefixes = get_all_service_prefixes()
    for service_prefix in all_service_prefixes:
        service_prefix_data = get_service_prefix_data(service_prefix)
        for action_name in service_prefix_data["privileges"]:
            if lowercase:
                all_actions.add(
                    f"{service_prefix}:{action_name.lower()}"
                )
            else:
                all_actions.add(
                    f"{service_prefix}:{action_name}"
                )

    # results = list(set(results))
    # results.sort()
    return all_actions
Example #11
0
def get_service_name_matching_iam_service_prefix(iam_service_prefix):
    if iam_definition.get(iam_service_prefix):
        service_name = get_service_prefix_data(
            iam_service_prefix)["service_name"]
        return service_name
    else:
        return None
Example #12
0
def create_empty_compliance_database(db_session):
    """
    Fill in the compliance database table with the service prefix (ex: s3)
        and the Service name (Simple Storage Service) and set all the values to blank strings
    """
    for service_prefix in ALL_SERVICE_PREFIXES:
        name = get_service_prefix_data(service_prefix)["service_name"]
        db_session.add(
            ComplianceTable(
                service_prefix=service_prefix,
                name=name,
                SOC="",
                PCI="",
                ISO="",
                FedRAMP_High="",
                FedRAMP_Moderate="",
                DoDCCSRG_IL2_EW="",
                DoDCCSRG_IL2_GC="",
                DoDCCSRG_IL4_GC="",
                DoDCCSRG_IL5_GC="",
                HIPAA="",
                HITRUST="",
                IRAP="",
                OSPAR="",
                FINMA="",
            )
        )
        db_session.commit()
Example #13
0
def get_actions_with_arn_type_and_access_level(service_prefix,
                                               resource_type_name,
                                               access_level):
    """
    Get a list of actions in a service under different access levels, specific to an ARN format.

    Arguments:
        service_prefix: A single AWS service prefix, like `s3` or `kms`
        resource_type_name: The ARN type name, like `bucket` or `key`
        access_level: Access level like "Read" or "List" or "Permissions management"
    Return:
        List: A list of actions that have that ARN type and Access level
    """
    service_prefix_data = get_service_prefix_data(service_prefix)
    results = []

    for some_action in service_prefix_data["privileges"]:
        if some_action["access_level"] == access_level:
            for some_resource_type in some_action["resource_types"]:
                this_resource_type = some_resource_type["resource_type"].strip(
                    "*")
                if this_resource_type.lower() == resource_type_name.lower():
                    results.append(
                        f"{service_prefix}:{some_action['privilege']}")
                    break
    return results
Example #14
0
def get_action_data(service, action_name):
    """
    Get details about an IAM Action in JSON format.

    Arguments:
        service: An AWS service prefix, like `s3` or `kms`. Case insensitive.
        action_name: The name of an AWS IAM action, like `GetObject`. To get data about all actions in a service, specify "*". Case insensitive.

    Returns:
        List: A dictionary containing metadata about an IAM Action.
    """
    results = []
    action_data_results = {}
    try:
        service_info = get_service_prefix_data(service)
        for privilege_info in service_info["privileges"]:
            # Get the baseline conditions and dependent actions
            condition_keys = []
            dependent_actions = []
            rows = []
            if action_name == "*":
                rows = privilege_info["resource_types"]
            else:
                for resource_type_entry in privilege_info["resource_types"]:
                    if privilege_info["privilege"].lower(
                    ) == action_name.lower():
                        rows.append(resource_type_entry)
            # for resource_type_entry in privilege_info["resource_types"]:
            for row in rows:
                # Set default value for if no other matches are found
                resource_arn_format = "*"
                # Get the dependent actions
                if row["dependent_actions"]:
                    dependent_actions.extend(row["dependent_actions"])
                # Get the condition keys
                for service_resource in service_info["resources"]:
                    if row["resource_type"] == "":
                        continue
                    if row["resource_type"].strip(
                            "*") == service_resource["resource"]:
                        resource_arn_format = service_resource.get("arn", "*")
                        condition_keys = service_resource.get("condition_keys")
                        break
                temp_dict = {
                    "action":
                    f"{service_info['prefix']}:{privilege_info['privilege']}",
                    "description": privilege_info["description"],
                    "access_level": privilege_info["access_level"],
                    "resource_arn_format": resource_arn_format,
                    "condition_keys": condition_keys,
                    "dependent_actions": dependent_actions,
                }
                results.append(temp_dict)
        action_data_results[service] = results
    except TypeError as t_e:
        logger.debug(t_e)

    # if results:
    return action_data_results
Example #15
0
def get_actions_matching_arn_type(service_prefix, resource_type_name):
    """
    Get a list of actions in a service specific to ARN type.

    Arguments:
        service_prefix: A single AWS service prefix, like `s3` or `kms`
        resource_type_name: The ARN type name, like `bucket` or `key`
    Return:
        List: A list of actions that have that ARN type
    """
    if resource_type_name == '*':
        return get_actions_that_support_wildcard_arns_only(service_prefix)

    service_prefix_data = get_service_prefix_data(service_prefix)
    results = []

    if service_prefix == "all":
        for some_prefix in all_service_prefixes:
            service_prefix_data = get_service_prefix_data(some_prefix)
            for action_name, action_data in service_prefix_data[
                    "privileges"].items():
                for resource_name, resource_data in action_data[
                        "resource_types"].items():
                    this_resource_type = resource_data["resource_type"].strip(
                        "*")
                    if this_resource_type.lower() == resource_type_name.lower(
                    ):
                        results.append(
                            f"{service_prefix}:{action_data['privilege']}")
                        break
    else:
        for action_name, action_data in service_prefix_data[
                "privileges"].items():
            for resource_name, resource_data in action_data[
                    "resource_types"].items():
                this_resource_type = resource_data["resource_type"].strip("*")
                if this_resource_type.lower() == resource_type_name.lower():
                    results.append(
                        f"{service_prefix}:{action_data['privilege']}")
                    break
    return results
 def test_get_service_prefix_data(self):
     result = get_service_prefix_data("cloud9")
     desired_output_schema = Schema({
         "service_name": "AWS Cloud9",
         "prefix": "cloud9",
         "privileges": dict,
         "resources": dict,
         "conditions": dict
     })
     valid_output = check(desired_output_schema, result)
     # print(json.dumps(result, indent=4))
     self.assertTrue(valid_output)
Example #17
0
def get_condition_keys_for_service(service_prefix):
    """
    Get a list of available conditions per AWS service

    Arguments:
        service_prefix: An AWS service prefix, like `s3` or `kms`
    Returns:
        List: A list of condition keys
    """
    service_prefix_data = get_service_prefix_data(service_prefix)
    results = list(dict.fromkeys(service_prefix_data["conditions"].keys()))
    return results
Example #18
0
def get_actions_with_access_level(service_prefix, access_level):
    """
    Get a list of actions in a service under different access levels.

    :param service_prefix: A single AWS service prefix, like `s3` or `kms`
    :param access_level: An access level as it is written in the database, such as 'Read', 'Write', 'List', 'Permisssions management', or 'Tagging'
    :return: A list of actions
    """
    results = []
    if service_prefix == "all":
        for some_prefix in all_service_prefixes:
            service_prefix_data = get_service_prefix_data(some_prefix)
            for some_action in service_prefix_data["privileges"]:
                if some_action["access_level"] == access_level:
                    results.append(f"{some_prefix}:{some_action['privilege']}")
    else:
        service_prefix_data = get_service_prefix_data(service_prefix)
        for some_action in service_prefix_data["privileges"]:
            if some_action["access_level"] == access_level:
                results.append(f"{service_prefix}:{some_action['privilege']}")
    return results
Example #19
0
def get_actions_for_service(service_prefix):
    """
    Get a list of available actions per AWS service

    :param service_prefix: An AWS service prefix, like `s3` or `kms`
    :return: A list of actions
    """
    service_prefix_data = get_service_prefix_data(service_prefix)
    results = []
    for item in service_prefix_data["privileges"]:
        results.append(f"{service_prefix}:{item['privilege']}")
    return results
Example #20
0
def get_condition_value_type(condition_key):
    """
    Get the data type of the condition key - like Date, String, etc.
    :param condition_key: A condition key, like a4b:filters_deviceType
    :return:
    """
    service_prefix, condition_name = condition_key.split(":")
    service_prefix_data = get_service_prefix_data(service_prefix)

    for condition_key_entry in service_prefix_data["conditions"]:
        if is_condition_key_match(condition_key_entry["condition"], condition_key):

            return condition_key_entry["type"].lower()
Example #21
0
def get_condition_keys_for_service(service_prefix):
    """
    Get a list of available conditions per AWS service

    :param service_prefix: An AWS service prefix, like `s3` or `kms`
    :return: A list of condition keys
    """
    results = []
    service_prefix_data = get_service_prefix_data(service_prefix)
    for resource in service_prefix_data["resources"]:
        results.extend(resource["condition_keys"])
    results = list(dict.fromkeys(results))
    return results
Example #22
0
def get_resource_type_name_with_raw_arn(raw_arn):
    """
    Given a raw ARN, return the resource type name as shown in the database.

    :param raw_arn: The raw ARN stored in the database, like 'arn:${Partition}:s3:::${BucketName}'
    :return: The resource type name, like bucket
    """
    elements = raw_arn.split(":", 5)
    service_prefix = elements[2]
    service_data = get_service_prefix_data(service_prefix)

    for resource in service_data["resources"]:
        if resource["arn"].lower() == raw_arn.lower():
            return resource["resource"]
Example #23
0
def get_arn_types_for_service(service_prefix):
    """
    Get a list of available ARN short names per AWS service.

    Arguments:
        service_prefix: An AWS service prefix, like `s3` or `kms`
    Returns:
        List: A list of ARN types, like `bucket` or `object`
    """
    results = {}
    service_prefix_data = get_service_prefix_data(service_prefix)
    for resource_name, resource_data in service_prefix_data["resources"].items():
        results[resource_data["resource"]] = resource_data["arn"]
    return results
Example #24
0
def get_raw_arns_for_service(service_prefix):
    """
    Get a list of available raw ARNs per AWS service

    Arguments:
        service_prefix: An AWS service prefix, like `s3` or `kms`
    Returns:
        List: A list of raw ARNs
    """
    results = []
    service_prefix_data = get_service_prefix_data(service_prefix)
    for resource_name, resource_data in service_prefix_data["resources"].items():
        results.append(resource_data["arn"])
    return results
Example #25
0
def get_actions_for_service(service_prefix):
    """
    Get a list of available actions per AWS service

    Arguments:
        service_prefix: List: An AWS service prefix, like `s3` or `kms`
    Returns:
        List: A list of actions
    """
    service_prefix_data = get_service_prefix_data(service_prefix)
    results = []
    for item in service_prefix_data["privileges"]:
        results.append(f"{service_prefix}:{item}")
    return results
Example #26
0
def remove_actions_not_matching_access_level(actions_list, access_level):
    """
    Given a list of actions, return a list of actions that match an access level

    Arguments:
        actions_list: A list of actions
        access_level: 'read', 'write', 'list', 'tagging', or 'permissions-management'
    Returns:
        List: An Updated list of actions, where the actions not matching the requested access level are removed.
    """
    new_actions_list = []

    def is_access_level(some_service_prefix, some_action):
        service_prefix_data = get_service_prefix_data(
            some_service_prefix.lower())
        this_result = None
        if service_prefix_data:
            if service_prefix_data.get("privileges"):
                for action_name, action_data in service_prefix_data[
                        "privileges"].items():
                    if action_data.get("access_level") == access_level:
                        if action_data.get(
                                "privilege").lower() == some_action.lower():
                            this_result = f"{some_service_prefix}:{action_data.get('privilege')}"
                            break
        if not this_result:
            return False
        else:
            return this_result

    if actions_list == ["*"]:
        actions_list.clear()
        for some_prefix in all_service_prefixes:
            service_prefix_data = get_service_prefix_data(some_prefix)
            for action_name, action_data in service_prefix_data[
                    "privileges"].items():
                if action_data["access_level"] == access_level:
                    actions_list.append(
                        f"{some_prefix}:{action_data['privilege']}")
    for action in actions_list:
        try:
            service_prefix, action_name = action.split(":")
        except ValueError as v_e:
            logger.debug(f"{v_e} - for action {action}")
            continue
        result = is_access_level(service_prefix, action_name)
        if result:
            new_actions_list.append(result)
            # new_actions_list.append(f"{service_prefix}:{action_name['privilege']}")
    return new_actions_list
Example #27
0
def get_condition_keys_available_to_raw_arn(raw_arn):
    """
    Get a list of condition keys available to a RAW ARN

    :param raw_arn: The value in the database, like arn:${Partition}:s3:::${BucketName}/${ObjectName}
    """
    results = []
    elements = raw_arn.split(":", 5)
    service_prefix = elements[2]
    service_prefix_data = get_service_prefix_data(service_prefix)
    for resource in service_prefix_data["resources"]:
        if resource["arn"] == raw_arn:
            results.extend(resource["condition_keys"])
    results = list(dict.fromkeys(results))
    return results
Example #28
0
def get_actions_matching_arn(arn):
    """Given a user-supplied arn, get a list of all actions that can match it."""
    raw_arn = get_matching_raw_arn(arn)
    resource_type_name = get_resource_type_name_with_raw_arn(raw_arn)
    service_prefix = get_service_from_arn(raw_arn)
    service_prefix_data = get_service_prefix_data(service_prefix)
    results = []
    for some_action in service_prefix_data["privileges"]:
        for some_resource_type in some_action["resource_types"]:
            this_resource_type = some_resource_type["resource_type"].strip("*")
            if this_resource_type.lower() == resource_type_name.lower():
                results.append(f"{service_prefix}:{some_action['privilege']}")
    results = list(dict.fromkeys(results))
    results.sort()
    return results
Example #29
0
 def test_get_service_prefix_data(self):
     result = get_service_prefix_data("cloud9")
     desired_output_schema = Schema(
         {
             "service_name": "AWS Cloud9",
             "service_authorization_url": "https://docs.aws.amazon.com/service-authorization/latest/reference/list_awscloud9.html",
             "prefix": "cloud9",
             "privileges": dict,
             "resources": dict,
             "conditions": dict
         }
     )
     valid_output = check(desired_output_schema, result)
     # print(json.dumps(result, indent=4))
     self.assertTrue(valid_output)
Example #30
0
def get_condition_keys_for_service(service_prefix):
    """
    Get a list of available conditions per AWS service

    Arguments:
        service_prefix: An AWS service prefix, like `s3` or `kms`
    Returns:
        List: A list of condition keys
    """
    results = []
    service_prefix_data = get_service_prefix_data(service_prefix)
    for condition_key_entry in service_prefix_data["conditions"]:
        results.append(condition_key_entry["condition"])
    results = list(dict.fromkeys(results))
    return results