Sign in

IAM Role and Policy Compliance Checks

There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.
  • Use Case: Ensure that IAM roles and policies adhere to the principle of least privilege, and no unnecessary permissions are granted.
  • DagKnows can automate the auditing of IAM roles and policies, identifying any roles with permissions that exceed required levels.
  • The platform can automatically adjust policies or flag them for review, ensuring compliance with security best practices.
  1. 1

    AWS IAM Root Access Key Audit SOC2 Compliance

    There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

    This runbook involves auditing the AWS account to check if the root user has any active access keys. It's essential to ensure root access keys are not used, as they provide unrestricted access to all resources in the AWS account. The audit aims to enhance security by verifying that no root access keys exist, aligning with best practices for AWS account management.

    1
    1. 1.1

      Check whether the root user access key exists or not

      There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

      This task involves verifying the presence of access keys for the AWS root user. It is critical for security to ensure that the root user, which has extensive privileges, does not have active access keys, thereby reducing the risk of unauthorized access and potential security breaches in the AWS environment.

      import boto3 from botocore.exceptions import ClientError, BotoCoreError creds = _get_creds(cred_label)['creds'] access_key = creds['username'] secret_key = creds['password'] # Create a boto3 client for IAM iam_client = boto3.client('iam',aws_access_key_id=access_key,aws_secret_access_key=secret_key) try: # Retrieve the AWS account's details account_summary = iam_client.get_account_summary() # Check if any access keys exist for the root user root_access_keys = account_summary['SummaryMap'].get('AccountAccessKeysPresent', 0) if root_access_keys == 0: print("Compliant: No access keys found for the root user.") else: print("Non-compliant: Access keys found for the root user.") except ClientError as e: print(f"AWS client error occurred: {e}") except BotoCoreError as e: print(f"Boto core error occurred: {e}") except Exception as e: print(f"An unexpected error occurred: {e}")
      copied
      1.1
  2. 2

    AWS IAM Policy No Statements with Admin Access Audit: SOC2 Compliance

    There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

    This runbook reviews and ensures AWS IAM policies don't contain overly permissive statements granting full admin access, adhering to the principle of least privilege for enhanced security.

    2
    1. 2.1

      List all AWS IAM Users

      There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

      This lists all IAM users in an AWS account, providing key details like usernames, user IDs, and creation dates. Essential for managing permissions and auditing access, this function supports security and compliance protocols by offering a clear view of user entities and their access levels. It's instrumental in enforcing security policies and the principle of least privilege in AWS resource access management.

      import boto3 import botocore.exceptions creds = _get_creds(cred_label)['creds'] access_key = creds['username'] secret_key = creds['password'] # Initialize the IAM client iam_client = boto3.client('iam',aws_access_key_id=access_key,aws_secret_access_key=secret_key) try: # Create a paginator for the list_users operation paginator = iam_client.get_paginator('list_users') # Use the paginator to paginate through the users table = context.newtable() table.title = "User list" table.num_cols = 3 table.num_rows = 1 table.has_header_row = True rownum = 0 table.setval(rownum, 0, "User name") table.setval(rownum, 1, "User ID") table.setval(rownum, 2, "Created on") for page in paginator.paginate(): users = page['Users'] table.num_rows += len(page['Users']) # Output user details if users: # print("List of IAM Users:") for user in users: rownum += 1 # print(f"Username: {user['UserName']}, User ID: {user['UserId']}, Created On: {user['CreateDate']}") table.setval(rownum, 0, user['UserName']) table.setval(rownum, 1, user['UserId']) table.setval(rownum, 2, user['CreateDate']) else: print("No IAM users found in this page.") # Handle specific exceptions except botocore.exceptions.NoCredentialsError: print("Credentials not available") except botocore.exceptions.PartialCredentialsError: print("Incomplete credentials provided") except botocore.exceptions.SSLError: print("SSL connection could not be established. Ensure your network allows SSL connections to AWS services") except botocore.exceptions.EndpointConnectionError: print("Unable to connect to the endpoint. Check your AWS configuration and network settings") except botocore.exceptions.ClientError as e: print(f"Unexpected error occurred accessing AWS: {e}") # Handle general exceptions except Exception as e: print(f"An unhandled error occurred: {str(e)}")
      copied
      2.1
    2. 2.2

      Check which Users have AWS IAM Policies with Admin Access: SOC2 Compliance

      There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

      This task audits AWS IAM users to identify those with administrative access. It ensures adherence to security standards by limiting broad access rights, crucial for mitigating risks associated with unauthorized permissions in a cloud environment.

      import boto3 from botocore.exceptions import ClientError, BotoCoreError creds = _get_creds(cred_label)['creds'] access_key = creds['username'] secret_key = creds['password'] def is_admin_policy(policy_document, exclude_permission_boundary): """ Check if the policy document contains admin access statements. """ for statement in policy_document.get('Statement', []): if statement.get('Effect') == 'Allow' and \ statement.get('Action') == '*' and \ statement.get('Resource') == '*': if not exclude_permission_boundary or \ (exclude_permission_boundary and 'Condition' not in statement): return True return False def evaluate_group_policies(user_name, iam, exclude_permission_boundary): """ Evaluate policies attached to groups for a given user. """ reasons = [] try: groups = iam.list_groups_for_user(UserName=user_name)['Groups'] for group in groups: attached_policies = iam.list_attached_group_policies(GroupName=group['GroupName'])['AttachedPolicies'] #print(attached_policies) # for debugging for policy in attached_policies: policy_details = iam.get_policy(PolicyArn=policy['PolicyArn']) if 'DefaultVersionId' in policy_details['Policy']: policy_version = iam.get_policy_version( PolicyArn=policy['PolicyArn'], VersionId=policy_details['Policy']['DefaultVersionId'] ) if is_admin_policy(policy_version['PolicyVersion']['Document'], exclude_permission_boundary): reasons.append(f"Group Attached Policy: {policy['PolicyArn']} ({group['GroupName']})") except ClientError as e: print(f"Error retrieving group policies for user {user_name}: {e}") return reasons def evaluate_attached_policies(user_name, iam, exclude_permission_boundary): """ Evaluate attached managed policies for a given user. """ reasons = [] try: attached_policies = iam.list_attached_user_policies(UserName=user_name)['AttachedPolicies'] #print(attached_policies) # for debugging for policy in attached_policies: policy_details = iam.get_policy(PolicyArn=policy['PolicyArn']) if 'DefaultVersionId' in policy_details['Policy']: policy_version = iam.get_policy_version( PolicyArn=policy['PolicyArn'], VersionId=policy_details['Policy']['DefaultVersionId'] ) if is_admin_policy(policy_version['PolicyVersion']['Document'], exclude_permission_boundary): reasons.append(f"Attached Policy: {policy['PolicyArn']}") except ClientError as e: print(f"Error retrieving attached policies for user {user_name}: {e}") return reasons def evaluate_inline_policies(user_name, iam, exclude_permission_boundary): """ Evaluate inline policies for a given user. """ reasons = [] try: inline_policies = iam.list_user_policies(UserName=user_name)['PolicyNames'] #print(inline_policies) # for debugging for policy_name in inline_policies: policy_document = iam.get_user_policy( UserName=user_name, PolicyName=policy_name )['PolicyDocument'] if is_admin_policy(policy_document, exclude_permission_boundary): reasons.append(f"Inline Policy: {policy_name}") except ClientError as e: print(f"Error retrieving inline policies for user {user_name}: {e}") return reasons def evaluate_iam_users_and_policies(exclude_permission_boundary=False): """ Evaluates IAM users for admin access in attached, inline, and group policies. """ iam = boto3.client('iam',aws_access_key_id=access_key,aws_secret_access_key=secret_key) compliance_report = { 'compliant': [], 'non_compliant': {} } try: users = iam.list_users()['Users'] for user in users: user_name = user['UserName'] print(f"Evaluating user: {user_name}") reasons = evaluate_attached_policies(user_name, iam, exclude_permission_boundary) + \ evaluate_inline_policies(user_name, iam, exclude_permission_boundary) + \ evaluate_group_policies(user_name, iam, exclude_permission_boundary) if reasons: compliance_report['non_compliant'][user_name] = reasons else: compliance_report['compliant'].append(user_name) except ClientError as e: print(f"ClientError while listing IAM users: {e}") except BotoCoreError as e: print(f"BotoCoreError encountered: {e}") except Exception as e: print(f"An unexpected error occurred: {e}") # Print Compliance Report if compliance_report['non_compliant']: print("\nNon-Compliant IAM Users (Admin Access Found):") for user, reasons in compliance_report['non_compliant'].items(): print(f"{user} - Reasons: {', '.join(reasons)}") else: print("\nNo Non-Compliant IAM Users Found.") if compliance_report['compliant']: print("\nCompliant IAM Users (No Admin Access):") for user in compliance_report['compliant']: print(user) else: print("\nAll IAM Users are Non-Compliant.") exclude_permission_boundary = False evaluate_iam_users_and_policies(exclude_permission_boundary) context.skip_sub_tasks=True
      copied
      2.2
      1. 2.2.1

        Remove/Delete an IAM Policy from an AWS IAM User

        There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

        This task is used to detach managed IAM policies or delete inline policies from specific IAM users. This action is crucial for maintaining secure and appropriate access levels within AWS environments, ensuring compliance with best security practices.

        import boto3 from botocore.exceptions import ClientError, NoCredentialsError, BotoCoreError creds = _get_creds(cred_label)['creds'] access_key = creds['username'] secret_key = creds['password'] def remove_or_modify_policy(iam_client, user_name, policy_arn=None, inline_policy_name=None): """ Detach a managed IAM policy or delete an inline IAM policy from a specified AWS IAM user. Args: iam_client: An initialized Boto3 IAM client. user_name: The name of the IAM user. policy_arn: The ARN of the managed IAM policy to be detached. inline_policy_name: The name of the inline IAM policy to be deleted. The function checks if the user exists and whether the specified policies are attached or exist, then proceeds with the appropriate action. """ try: # Check if the user exists iam_client.get_user(UserName=user_name) if policy_arn: # Detach managed policy if it is attached attached_policies = iam_client.list_attached_user_policies(UserName=user_name)['AttachedPolicies'] if any(policy['PolicyArn'] == policy_arn for policy in attached_policies): iam_client.detach_user_policy(UserName=user_name, PolicyArn=policy_arn) print(f"Detached policy {policy_arn} from {user_name}") else: print(f"Policy {policy_arn} is not attached to {user_name}") elif inline_policy_name: # Delete inline policy if it exists inline_policies = iam_client.list_user_policies(UserName=user_name)['PolicyNames'] if inline_policy_name in inline_policies: iam_client.delete_user_policy(UserName=user_name, PolicyName=inline_policy_name) print(f"Deleted inline policy {inline_policy_name} from {user_name}") else: print(f"Inline policy {inline_policy_name} does not exist for {user_name}") except ClientError as e: print(f"An AWS ClientError occurred: {e}") except NoCredentialsError: print("No AWS credentials available. Please configure them.") except BotoCoreError as e: print(f"A BotoCoreError occurred: {e}") except Exception as e: print(f"An unexpected error occurred: {e}") iam_client = boto3.client('iam',aws_access_key_id=access_key,aws_secret_access_key=secret_key) # user_name = 'test_user' # policy_arn_to_remove = 'arn:aws:iam::aws:policy/AdministratorAccess' # Example ARN # inline_policy_name = 'your-inline-policy-name' remove_or_modify_policy(iam_client, user_name, policy_arn=policy_arn_to_remove)
        copied
        2.2.1
  3. 3

    AWS IAM User No Policies Audit: SOC2 Compliance

    There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

    This runbook ensures that AWS IAM users don't have direct policies attached, adhering to SOC2 security guidelines. It mandates permissions be granted via group memberships or IAM roles, enhancing security and simplifying permission management. This audit is key in maintaining structured access control, crucial for SOC2 compliance in cloud environments.

    3
    1. 3.1

      Check which AWS IAM users have directly attached policies

      There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

      This task involves identifying IAM users in an AWS environment who have individual policies attached to their accounts. This is key for security and compliance, ensuring permissions are managed through group memberships or role assumptions, rather than direct attachments, for better access control and security practices.

      import boto3 from botocore.exceptions import ClientError, BotoCoreError creds = _get_creds(cred_label)['creds'] access_key = creds['username'] secret_key = creds['password'] def check_iam_users_for_attached_policies(): """ Check if any IAM users have policies attached directly to them. """ iam = boto3.client('iam',aws_access_key_id=access_key,aws_secret_access_key=secret_key) non_compliant_users = 0 total_users = 0 try: # Initialize pagination paginator = iam.get_paginator('list_users') for page in paginator.paginate(): for user in page['Users']: total_users += 1 username = user['UserName'] # Check for attached user policies attached_policies = iam.list_attached_user_policies(UserName=username)['AttachedPolicies'] if attached_policies: print(f"Non-compliant: User '{username}' has direct policies attached.") non_compliant_users += 1 else: print(f"Compliant: User '{username}' has no direct policies attached.") print(f"\nTotal users checked: {total_users}") print(f"Non-compliant users: {non_compliant_users}") except ClientError as e: print(f"AWS ClientError: {e.response['Error']['Message']}") except BotoCoreError as e: print(f"BotoCoreError: {e}") except Exception as e: print(f"An unexpected error occurred: {e}") # Example usage check_iam_users_for_attached_policies() context.skip_sub_tasks=True
      copied
      3.1
      1. 3.1.1

        Attach an AWS IAM User to a Group

        There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

        This task manages user permissions in AWS by confirming the existence of both IAM users and groups, ensuring users aren't already in the target group, and then adding them if necessary. This process streamlines user access management and maintains organized, best-practice-based user-group associations in AWS IAM.

        import boto3 from botocore.exceptions import ClientError creds = _get_creds(cred_label)['creds'] access_key = creds['username'] secret_key = creds['password'] def add_user_to_group(user_name, group_name): """ Adds an IAM user to an IAM group, after checking if both exist and if the user is not already in the group. :param user_name: The name of the IAM user. :param group_name: The name of the IAM group. """ # Create an IAM client iam_client = boto3.client('iam',aws_access_key_id=access_key,aws_secret_access_key=secret_key) try: # Check if the user exists iam_client.get_user(UserName=user_name) except ClientError as error: if error.response['Error']['Code'] == 'NoSuchEntity': print(f"The user '{user_name}' does not exist.") return else: raise try: # Check if the group exists and if the user is already a member response = iam_client.get_group(GroupName=group_name) if any(user['UserName'] == user_name for user in response['Users']): print(f"User '{user_name}' is already a member of the group '{group_name}'.") return except ClientError as error: if error.response['Error']['Code'] == 'NoSuchEntity': print(f"The group '{group_name}' does not exist.") return else: raise try: # Add user to the group iam_client.add_user_to_group( GroupName=group_name, UserName=user_name ) print(f"User '{user_name}' has been successfully added to the group '{group_name}'.") except ClientError as error: # Handle other possible errors print(f"Unexpected error: {error}") except Exception as e: # Handle any other exception print(f"An error occurred: {e}") # Example usage #username = 'test_user' #groupname = 'your-group-name' add_user_to_group(username, groupname) context.proceed=False
        copied
        3.1.1
      2. 3.1.2

        Attach AWS IAM User Policy to Assume a Role

        There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

        This task assigns a policy to an IAM user, enabling them to assume a specified IAM role. This key security measure allows controlled, temporary access elevation in line with the principle of least privilege. It's essential for secure and efficient permission management in AWS. Note:- This will directly attach a policy to the AWS IAM User.

        import boto3 from botocore.exceptions import ClientError import json creds = _get_creds(cred_label)['creds'] access_key = creds['username'] secret_key = creds['password'] def get_aws_account_id(): """ Retrieves the AWS account ID using STS. """ sts_client = boto3.client('sts',aws_access_key_id=access_key,aws_secret_access_key=secret_key,region_name='us-east-1') try: account_id = sts_client.get_caller_identity()["Account"] return account_id except ClientError as error: print(f"Error retrieving AWS account ID: {error}") return None def get_policy_arn(iam_client, policy_name): """ Retrieves the ARN of a given policy. :param iam_client: The IAM client instance. :param policy_name: The name of the policy. :return: The ARN of the policy or None if not found. """ try: policy = iam_client.get_policy(PolicyArn=f"arn:aws:iam::{get_aws_account_id()}:policy/{policy_name}") return policy['Policy']['Arn'] except ClientError: return None def check_role_exists(iam_client, role_name): """ Checks if the specified IAM role exists. :param iam_client: The IAM client instance. :param role_name: The name of the IAM role to check. :return: True if the role exists, False otherwise. """ try: iam_client.get_role(RoleName=role_name) return True except ClientError as error: if error.response['Error']['Code'] == 'NoSuchEntity': return False else: raise def attach_role_to_user(user_name, role_name): """ Attaches a policy to a user that allows the user to assume a specified role. :param user_name: The name of the IAM user. :param role_name: The name of the IAM role. """ # Create an IAM client iam_client = boto3.client('iam',aws_access_key_id=access_key,aws_secret_access_key=secret_key) # Get AWS account ID account_id = get_aws_account_id() if account_id is None: print("Failed to retrieve AWS account ID. Exiting function.") return policy_name = f"AllowAssumeRole-{role_name}" policy_arn = get_policy_arn(iam_client, policy_name) policy_document = { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": f"arn:aws:iam::{account_id}:role/{role_name}" } ] } # Check if the role exists if not check_role_exists(iam_client, role_name): print(f"The role '{role_name}' does not exist. Exiting function.") return # Create or update policy if policy_arn: print(f"Policy {policy_name} already exists. Updating policy.") try: iam_client.create_policy_version( PolicyArn=policy_arn, PolicyDocument=json.dumps(policy_document), SetAsDefault=True ) except ClientError as error: print(f"Failed to update policy: {error}") return else: try: policy_response = iam_client.create_policy( PolicyName=policy_name, PolicyDocument=json.dumps(policy_document) ) policy_arn = policy_response['Policy']['Arn'] except ClientError as error: print(f"Failed to create policy: {error}") return # Attach the policy to the user try: iam_client.attach_user_policy( UserName=user_name, PolicyArn=policy_arn ) print(f"Policy {policy_name} attached to user {user_name} allowing to assume role {role_name}.") except ClientError as error: print(f"Failed to attach policy to user: {error}") # Example usage #username = 'test_user' #rolename = 'AWSServiceRoleForECS' attach_role_to_user(username, rolename) context.proceed=False
        copied
        3.1.2
  4. 4

    Check and Rotate Expiring Access Keys for AWS IAM Users

    There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

    This runbook involves monitoring the age of IAM user access keys and replacing them periodically. Access keys are used to authenticate programmatic requests to AWS services. Over time, the risk of these keys being compromised increases, either through unintentional exposure or malicious activities. By routinely checking the age of these keys, organizations can identify which ones are nearing or past their recommended lifespan. Rotating, or replacing, these old keys reduces potential security vulnerabilities. The process typically involves creating a new set of access keys, updating all applications or services to use the new keys, and then deactivating the old keys. This proactive approach ensures that AWS access remains secure and aligns with industry standards for credential management.

    threshold_age=90 #Hardcoded for a single execution result, can be changed as per the user
    copied
    4
    1. 4.1

      List all AWS IAM Users

      There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

      This lists all IAM users in an AWS account, providing key details like usernames, user IDs, and creation dates. Essential for managing permissions and auditing access, this function supports security and compliance protocols by offering a clear view of user entities and their access levels. It's instrumental in enforcing security policies and the principle of least privilege in AWS resource access management.

      import boto3 import botocore.exceptions creds = _get_creds(cred_label)['creds'] access_key = creds['username'] secret_key = creds['password'] # Initialize the IAM client iam_client = boto3.client('iam',aws_access_key_id=access_key,aws_secret_access_key=secret_key) try: # Create a paginator for the list_users operation paginator = iam_client.get_paginator('list_users') # Use the paginator to paginate through the users table = context.newtable() table.title = "User list" table.num_cols = 3 table.num_rows = 1 table.has_header_row = True rownum = 0 table.setval(rownum, 0, "User name") table.setval(rownum, 1, "User ID") table.setval(rownum, 2, "Created on") for page in paginator.paginate(): users = page['Users'] table.num_rows += len(page['Users']) # Output user details if users: # print("List of IAM Users:") for user in users: rownum += 1 # print(f"Username: {user['UserName']}, User ID: {user['UserId']}, Created On: {user['CreateDate']}") table.setval(rownum, 0, user['UserName']) table.setval(rownum, 1, user['UserId']) table.setval(rownum, 2, user['CreateDate']) else: print("No IAM users found in this page.") # Handle specific exceptions except botocore.exceptions.NoCredentialsError: print("Credentials not available") except botocore.exceptions.PartialCredentialsError: print("Incomplete credentials provided") except botocore.exceptions.SSLError: print("SSL connection could not be established. Ensure your network allows SSL connections to AWS services") except botocore.exceptions.EndpointConnectionError: print("Unable to connect to the endpoint. Check your AWS configuration and network settings") except botocore.exceptions.ClientError as e: print(f"Unexpected error occurred accessing AWS: {e}") # Handle general exceptions except Exception as e: print(f"An unhandled error occurred: {str(e)}")
      copied
      4.1
    2. 4.2

      Filter Out Old AWS IAM Access Keys

      There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

      This task identifies and isolates AWS IAM (Identity and Access Management) access keys that have surpassed a predefined age threshold. AWS IAM keys are utilized to securely control access to AWS services and resources. As a best practice for secure access management, it is recommended to regularly rotate IAM access keys and retire those that are no longer needed or have become outdated. By filtering out old access keys, administrators can ensure that access credentials are not overly permissive or unnecessarily prolonged, thereby enhancing the security posture. This task involves analyzing the creation date of each IAM access key, comparing it against the current date, and identifying keys that exceed the acceptable age limit, which are then either flagged for review to uphold stringent access control and minimize potential security risks.

      import boto3 from datetime import datetime creds = _get_creds(cred_label)['creds'] access_key = creds['username'] secret_key = creds['password'] # Initialize the IAM client iam_client = boto3.client('iam',aws_access_key_id=access_key,aws_secret_access_key=secret_key) # Define the threshold age in days #threshold_age = 55 # List to store old access key data old_keys_data = [] try: # Initialize a flag for old keys detection old_keys_found = False # Check access keys for each user for user in users: username = user['UserName'] access_keys = iam_client.list_access_keys(UserName=username)['AccessKeyMetadata'] # Check age of each access key for key in access_keys: #print(key) # for debugging key_age = (datetime.now(datetime.utcnow().astimezone().tzinfo) - key['CreateDate']).days if key_age > int(threshold_age): print(f"User: {username}, Access Key: {key['AccessKeyId']}, Age: {key_age} days, Status: {key['Status']}") old_keys_found = True # Add old key data to list old_keys_data.append({ 'username': username, 'access_key_id': key['AccessKeyId'] }) # If no old keys are found, print a message if not old_keys_found: print("No access keys older than the defined threshold were found.") else: print("Old key data: ", old_keys_data) # Pass `old_keys_data` to downstream task here except boto3.exceptions.botocore.exceptions.PartialCredentialsError as pce: print(f"Credentials error: {str(pce)}") except boto3.exceptions.botocore.exceptions.BotoCoreError as bce: print(f"BotoCore Error: {str(bce)}") except boto3.exceptions.botocore.exceptions.ClientError as ce: print(f"Client Error: {str(ce)}") except Exception as e: print(f"An unexpected error occurred: {str(e)}") context.skip_sub_tasks=True
      copied
      4.2
      1. 4.2.1

        Deactivate Old AWS IAM Access Keys

        There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

        This task involves deactivating IAM (Identity and Access Management) access keys in AWS that have surpassed a specified age or are no longer in use, as a measure to enhance security. Regularly auditing and deactivating stale or outdated access keys restrict unauthorized or inadvertent access to AWS resources and services. This task deactivates access keys that are identified as old, thereby ensuring they cannot be used to authenticate API requests. This practice is pivotal in a robust IAM policy to assure that only active and necessary access keys are in circulation, thereby safeguarding the AWS environment against potential malicious activities or inadvertent misconfigurations by reducing the attack surface and adhering to the principle of least privilege.

        import boto3 creds = _get_creds(cred_label)['creds'] access_key = creds['username'] secret_key = creds['password'] # Initialize the IAM client iam_client = boto3.client('iam',aws_access_key_id=access_key,aws_secret_access_key=secret_key) ''' # Example input data old_keys_data = [ {'username': 'xyz_other_account', 'access_key_id': 'AJHBVFNONLHGBFHAS2CM'}, # ... received from parent task ] ''' try: # Check if old_keys_data is not empty if old_keys_data: # Loop through each key data in the input for key_data in old_keys_data: username = key_data['username'] access_key_id = key_data['access_key_id'] # Deactivate the access key #iam_client.update_access_key(UserName=username, AccessKeyId=access_key_id, Status='Inactive') print(f"Deactivated access key {access_key_id} for user {username}") else: print("No old keys provided for deactivation.") except boto3.exceptions.botocore.exceptions.PartialCredentialsError as pce: print(f"Credentials error: {str(pce)}") except boto3.exceptions.botocore.exceptions.BotoCoreError as bce: print(f"BotoCore Error: {str(bce)}") except boto3.exceptions.botocore.exceptions.ClientError as ce: print(f"Client Error: {str(ce)}") except Exception as e: print(f"An unexpected error occurred: {str(e)}") context.proceed=False
        copied
        4.2.1
      2. 4.2.2

        Create AWS IAM Access Keys

        There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

        This task involves generating a new set of credentials – an access key ID and a secret access key – for an AWS Identity and Access Management (IAM) user. These credentials are vital for programmatic access to AWS services, enabling API calls to be authenticated and authorized. Within AWS, an IAM user can have a maximum of two active access keys, facilitating seamless key rotation. The procedure to create an access key includes the automatic creation of an access key ID and a secret key, which should be securely stored immediately upon creation, as AWS does not allow for the retrieval of the secret key at a later time. Implementing good practices, such as routinely rotating and responsibly managing access keys, is crucial to maintaining secure user access to AWS services.

        import boto3 creds = _get_creds(cred_label)['creds'] access_key = creds['username'] secret_key = creds['password'] # Initialize the IAM client iam_client = boto3.client('iam',aws_access_key_id=access_key,aws_secret_access_key=secret_key) if old_keys_data: # Iterate over old keys data and create new keys for the respective users for old_key in old_keys_data: try: new_key = iam_client.create_access_key(UserName=old_key['username']) print(f"New key created for {old_key['username']}:") print(new_key) except iam_client.exceptions.LimitExceededException as lee: print(f"Limit Error creating key for {old_key['username']}: {str(lee)}") except iam_client.exceptions.NoSuchEntityException as nee: print(f"No Such Entity Error for {old_key['username']}: {str(nee)}") except iam_client.exceptions.ServiceFailureException as sfe: print(f"Service Failure for {old_key['username']}: {str(sfe)}") except Exception as e: print(f"An unexpected error occurred while creating key for {old_key['username']}: {str(e)}") else: print("No old keys data was passed to this task") context.proceed=False
        copied
        4.2.2
      3. 4.2.3

        Update Old AWS IAM Access Keys

        There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

        This task pertains to managing and refreshing AWS Identity and Access Management (IAM) user credentials to uphold security best practices. IAM access keys, which consist of an access key ID and a secret access key, are used to authenticate AWS API requests. However, if these keys are compromised or simply aged, updating them becomes crucial to safeguard the account. Updating might involve changing the status of the keys (activating or deactivating them), in this case we are deactivating them. The practice of regularly updating access keys is crucial in minimizing the risk associated with long-term key usage or potential unauthorized access.

        import boto3 creds = _get_creds(cred_label)['creds'] access_key = creds['username'] secret_key = creds['password'] # Initialize the IAM client iam_client = boto3.client('iam',aws_access_key_id=access_key,aws_secret_access_key=secret_key) try: # Check if old_keys_data is not empty if old_keys_data: # Loop through each key data in the input for key_data in old_keys_data: username = key_data['username'] access_key_id = key_data['access_key_id'] # Deactivate the access key iam_client.update_access_key(UserName=username, AccessKeyId=access_key_id, Status='Inactive') print(f"Deactivated access key {access_key_id} for user {username}") else: print("No old keys provided for deactivation.") except boto3.exceptions.botocore.exceptions.PartialCredentialsError as pce: print(f"Credentials error: {str(pce)}") except boto3.exceptions.botocore.exceptions.BotoCoreError as bce: print(f"BotoCore Error: {str(bce)}") except boto3.exceptions.botocore.exceptions.ClientError as ce: print(f"Client Error: {str(ce)}") except Exception as e: print(f"An unexpected error occurred: {str(e)}") context.proceed=False
        copied
        4.2.3
      4. 4.2.4

        Delete AWS IAM Access Keys

        There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

        This task refers to the removal of an AWS Identity and Access Management (IAM) user's access keys, ensuring they can no longer be used for authentication with AWS services and resources. IAM access keys comprise an access key ID and a secret access key, which are employed to sign programmatic requests that you make to AWS. Whether it is for security compliance, a response to a security incident, or part of a key rotation policy, deleting an IAM access key is a critical operation. After deletion, any applications or users utilizing the deleted access key will lose access to AWS resources, so it is crucial to update all instances where the key is used before deletion. Additionally, AWS recommends regular access key rotation as a best practice, which involves creating a new key, updating all applications to use the new key, and then safely deleting the old key to maintain secure and functional access control.

        import boto3 creds = _get_creds(cred_label)['creds'] access_key = creds['username'] secret_key = creds['password'] # Initialize the IAM client iam_client = boto3.client('iam',aws_access_key_id=access_key,aws_secret_access_key=secret_key) # Check if there is data to process if old_keys_data: # Iterate over old keys data and try to delete each key for old_key in old_keys_data: try: iam_client.delete_access_key( UserName=old_key['username'], AccessKeyId=old_key['access_key_id'] ) print(f"Deleted access key {old_key['access_key_id']} for user {old_key['username']}.") except iam_client.exceptions.NoSuchEntityException as nee: print(f"No Such Entity Error for {old_key['username']} with key {old_key['access_key_id']}: {str(nee)}") except iam_client.exceptions.LimitExceededException as lee: print(f"Limit Error for {old_key['username']} with key {old_key['access_key_id']}: {str(lee)}") except iam_client.exceptions.ServiceFailureException as sfe: print(f"Service Failure for {old_key['username']} with key {old_key['access_key_id']}: {str(sfe)}") except Exception as e: print(f"An unexpected error occurred while deleting key for {old_key['username']} with key {old_key['access_key_id']}: {str(e)}") else: print("No old keys data was passed to this task")
        copied
        4.2.4
  5. 5

    AWS IAM Password Policy SOC2 Compliance

    There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

    This runbook involves setting stringent password rules and enforcing them for all IAM users. Key measures include complex password requirements, regular password changes, and preventing password reuse. This effort aligns with SOC2 standards for robust data security and access management in cloud environments, enhancing the overall security posture and integrity of the system.

    5
    1. 5.1

      Check the current AWS IAM password policy

      There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

      This task reviews the existing AWS IAM password policy to ensure it meets specified security standards. It involves assessing criteria like password complexity, expiration, and rotation rules for compliance with organizational or regulatory requirements.

      import boto3 from botocore.exceptions import ClientError, BotoCoreError creds = _get_creds(cred_label)['creds'] access_key = creds['username'] secret_key = creds['password'] def get_password_policy(client): """ Retrieves the current account password policy. :param client: Boto3 IAM client :return: Current password policy if exists, None otherwise """ try: return client.get_account_password_policy()['PasswordPolicy'] except client.exceptions.NoSuchEntityException: # No password policy is set for the account print("No password policy is set for the account.") return None except ClientError as e: print(f"Error retrieving password policy: {e}") return None def check_password_policy_compliance(current_policy, desired_policy): """ Checks if the current AWS IAM account password policy is compliant with the desired policy. Also, returns the non-compliant fields. :param current_policy: The current password policy :param desired_policy: The desired password policy attributes :return: Tuple (True if compliant, False otherwise, non_compliant_fields) """ non_compliant_fields = {} for key, value in desired_policy.items(): if key not in current_policy or current_policy[key] != value: non_compliant_fields[key] = { 'current_value': current_policy.get(key), 'desired_value': value } return len(non_compliant_fields) == 0, non_compliant_fields # Desired password policy parameters desired_policy = { 'MinimumPasswordLength': int(MinimumPasswordLength), 'RequireSymbols': RequireSymbols, 'RequireNumbers': RequireNumbers, 'RequireUppercaseCharacters': RequireUppercaseCharacters, 'RequireLowercaseCharacters': RequireLowercaseCharacters, 'MaxPasswordAge': int(MaxPasswordAge), # Days 'PasswordReusePrevention': int(PasswordReusePrevention), 'HardExpiry': HardExpiry } ''' # The 'HardExpiry' field in the password policy determines whether IAM users are allowed to change their own passwords. # - If 'HardExpiry' is set to True, it means IAM users cannot change their own passwords. In this case, only an administrator can reset the passwords. This setting is typically used in highly secure environments where password management needs to be strictly controlled by administrators. # - If 'HardExpiry' is set to False, IAM users are permitted to change their own passwords. This setting is more user-friendly and allows users to manage their own password changes, including regular updates or resets if needed. ''' # Create a boto3 client for IAM iam_client = boto3.client('iam',aws_access_key_id=access_key,aws_secret_access_key=secret_key) # Get the current account password policy current_policy = get_password_policy(iam_client) print("Current Policy:") for key, value in current_policy.items(): print(f" - {key}: {value}") if current_policy: # Debugging: Before checking compliance #print("Checking policy compliance...") is_compliant, non_compliant_fields = check_password_policy_compliance(current_policy, desired_policy) # Debugging: After checking compliance #print("Completed policy compliance check.") if is_compliant: print("The account password policy is compliant.") else: print("The account password policy is not compliant.") print("Non-compliant fields:") for field, values in non_compliant_fields.items(): print(f" - {field}: Current Value - {values['current_value']}, Desired Value - {values['desired_value']}") else: print("No password policy found for the account.") context.skip_sub_tasks=True #create_new_policy
      copied
      5.1
      1. 5.1.1

        Set an AWS IAM Password Policy

        There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

        This task configures rules for user passwords in your AWS account. This process includes defining requirements for password complexity, expiration, and rotation to enhance account security and manage access controls effectively.

        import boto3 from botocore.exceptions import ClientError, BotoCoreError creds = _get_creds(cred_label)['creds'] access_key = creds['username'] secret_key = creds['password'] def set_password_policy(client): """ Updates the account password policy with specified settings. :param client: Boto3 IAM client """ try: # Update the account password policy with the desired settings client.update_account_password_policy( MinimumPasswordLength=MinimumPasswordLength, RequireSymbols=RequireSymbols, RequireNumbers=RequireNumbers, RequireUppercaseCharacters=RequireUppercaseCharacters, RequireLowercaseCharacters=RequireLowercaseCharacters, MaxPasswordAge=MaxPasswordAge, PasswordReusePrevention=PasswordReusePrevention, HardExpiry=HardExpiry ) print("Password policy updated successfully.") # Handle client errors from AWS except ClientError as e: print(f"AWS client error occurred: {e}") # Handle BotoCore errors except BotoCoreError as e: print(f"Boto core error occurred: {e}") # Handle other unexpected errors except Exception as e: print(f"An unexpected error occurred: {e}") # Create a boto3 client for IAM iam_client = boto3.client('iam',aws_access_key_id=access_key,aws_secret_access_key=secret_key) # Set the password policy set_password_policy(iam_client)
        copied
        5.1.1
      2. 5.1.2

        Enforce Password Change for AWS IAM Users

        There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.

        This task makes all users to update their passwords by updating their login profiles, typically following the implementation of a new password policy. This ensures that all user passwords comply with the updated security standards, enhancing overall account security.

        import boto3 from botocore.exceptions import ClientError, BotoCoreError creds = _get_creds(cred_label)['creds'] access_key = creds['username'] secret_key = creds['password'] def enforce_password_change_for_all_users(client): """ Enforce a password change for all IAM users. :param client: Boto3 IAM client :return: None """ try: paginator = client.get_paginator('list_users') for page in paginator.paginate(): for user in page['Users']: try: client.update_login_profile( UserName=user['UserName'], PasswordResetRequired=True ) print(f"Password change enforced for user: {user['UserName']}") except ClientError as e: if e.response['Error']['Code'] == 'NoSuchEntity': print(f"User {user['UserName']} does not have a password to change.") else: print(f"Failed to enforce password change for user {user['UserName']}: {e}") except Exception as e: print(f"Unexpected error for user {user['UserName']}: {e}") except ClientError as e: print(f"Error retrieving IAM users: {e}") except BotoCoreError as e: print(f"Boto core error: {e}") except Exception as e: print(f"Unexpected error: {e}") # Create a boto3 client for IAM iam_client = boto3.client('iam',aws_access_key_id=access_key,aws_secret_access_key=secret_key) # Enforce password change for all users enforce_password_change_for_all_users(iam_client)
        copied
        5.1.2