AWS IAM

+
+

Table of Contents

+

Release Notes

@@ -440,24 +495,34 @@

Release Notes -

v1.0.2

-
    -
  • Update payloads in workflow comments

  • -
-

-
-

v1.0.1

-
    -
  • Support added for App Host.

  • -
-
-
-

v1.0.0

-
    -
  • Initial Release

  • -
-
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +

Version

Date

Notes

1.0.3

06/2024

Converted to Python3

1.0.2

-

Update payloads in workflow comments

1.0.1

-

Support added for App Host.

1.0.0

-

Initial Release

+

@@ -466,9 +531,14 @@

Overview Provide a high-level description of the function itself and its remote software or application. The text below is parsed from the "description" and "long_description" attributes in the setup.py file --> -

Amazon AWS IAM Integration for Resilient

+

Amazon AWS IAM Integration for SOAR

Amazon Web Services Identity and Access Management (AWS IAM) allows management of access to AWS services and resources securely. You can use IAM to create and manage AWS users and groups, and use permissions to allow or deny access to AWS resources. The AWS IAM integration with the SOAR platform allows you to query and update users or access keys for an AWS account.

+
+

Key Features

+

You can execute the following types of queries:

+

The integration contains the following functions: screenshot: functions screenshot: functions_2

+

Requirements

    -
  • SOAR platform >= v48.2.16

  • +
  • SOAR platform >= 51.0.0.0.9340

  • An Integration Server running:

    • resilient_circuits>=35.0.0

    • @@ -544,10 +616,89 @@

      Requirements -
      -

      Installation - App Host

      +

      This app supports the IBM Security QRadar SOAR Platform and the IBM Security QRadar SOAR for IBM Cloud Pak for Security.

      +
      +

      SOAR platform

      +

      The SOAR platform supports two app deployment mechanisms, Edge Gateway (also known as App Host) and integration server.

      +

      If deploying to a SOAR platform with an App Host, the requirements are:

      +
        +
      • SOAR platform >= 51.0.0.0.9340.

      • +
      • The app is in a container-based format (available from the AppExchange as a zip file).

      • +
      +

      If deploying to a SOAR platform with an integration server, the requirements are:

      +
        +
      • SOAR platform >= 51.0.0.0.9340.

      • +
      • The app is in the older integration format (available from the AppExchange as a zip file which contains a tar.gz file).

      • +
      • Integration server is running resilient_circuits>=35.0.0.

      • +
      • If using an API key account, make sure the account provides the following minimum permissions:

        +
        + + + + + + + + + + + + + + +

        Name

        Permissions

        Org Data

        Read

        Function

        Read

        +
        +
      • +
      +

      The following SOAR platform guides provide additional information:

      +
        +
      • Edge Gateway Deployment Guide or App Host Deployment Guide: provides installation, configuration, and troubleshooting information, including proxy server settings.

      • +
      • Integration Server Guide: provides installation, configuration, and troubleshooting information, including proxy server settings.

      • +
      • System Administrator Guide: provides the procedure to install, configure and deploy apps.

      • +
      +

      The above guides are available on the IBM Documentation website at ibm.biz/soar-docs. On this web page, select your SOAR platform version. On the follow-on page, you can find the Edge Gateway Deployment Guide, App Host Deployment Guide, or Integration Server Guide by expanding Apps in the Table of Contents pane. The System Administrator Guide is available by expanding System Administrator.

      +
      +
      +

      Cloud Pak for Security

      +

      If you are deploying to IBM Cloud Pak for Security, the requirements are:

      +
        +
      • IBM Cloud Pak for Security >= 1.10.15.

      • +
      • Cloud Pak is configured with an Edge Gateway.

      • +
      • The app is in a container-based format (available from the AppExchange as a zip file).

      • +
      +

      The following Cloud Pak guides provide additional information:

      +
        +
      • Edge Gateway Deployment Guide or App Host Deployment Guide: provides installation, configuration, and troubleshooting information, including proxy server settings. From the Table of Contents, select Case Management and Orchestration & Automation > Orchestration and Automation Apps.

      • +
      • System Administrator Guide: provides information to install, configure, and deploy apps. From the IBM Cloud Pak for Security IBM Documentation table of contents, select Case Management and Orchestration & Automation > System administrator.

      • +
      +

      These guides are available on the IBM Documentation website at ibm.biz/cp4s-docs. From this web page, select your IBM Cloud Pak for Security version. From the version-specific IBM Documentation page, select Case Management and Orchestration & Automation.

      +
      +
      +

      Proxy Server

      +

      The app does support a proxy server.

      +
      +
      +

      Python Environment

      +

      Python 3.9, 3.11, and 3.12 are officially supported. When deployed as an app, the app runs on Python 3.11. +Additional package dependencies may exist for each of these packages:

      +
        +
      • boto3>=1.10.6

      • +
      • resilient_circuits>=35.0.0

      • +
      • resilient_lib>=35.0.0

      • +
      +
      +

      Prerequisites

      +
        +
      • An Amazon AWS account with access key id and access key.

      • +
      +
      +
      +
      +
      +

      Installation

      +
      +

      on AppHost

      All the components for running this integration in a container already exist when using the App Host app.

      -
      [fn_aws_iam]
      -aws_iam_access_key_id=<AWS_IAM_ACCESS_KEY_ID>
      -aws_iam_secret_access_key=<AWS_IAM_SECRET_ACCESS_KEY>
      -# Optional settings for access to AWS IAM via a proxy.
      -#http_proxy=http://proxy:80
      -#https_proxy=http://proxy:80
      -
      -
      -
        -
      • [Optional]: Test the configuration.

      • -
      • Deploy the app.

      • -
      -
      -

      Installation - Integration server

      +
      +

      on Integration Server

      • Download the app app-fn_aws_iam-x.x.x.zip.

      • Copy the .zip to your Integration Server and SSH into it.

      • @@ -593,10 +732,11 @@

        Installation - Integration server
        $ nano ~/.resilient/app.config
        -
        - +

      +
      +
      +

      App Configuration

      +

      The following table provides the settings you need to configure the app. These settings are made in the app.config file. See the documentation discussed in the Requirements section for the procedure.

      @@ -630,123 +770,3353 @@

      Installation - Integration server +
      +

      Function - AWS IAM: List Users

      +

      The function can perform a get of IAM user or users in the AWS account. Users can be filtered by user name, group, policy or access key. If the user name is specified, the function can perform a get of information for this user only. Parameter aws_iam_user_name is an IAM user name. Parameters aws_iam_user_filter, aws_aim_group_filter and aws_aim_policy_filter param (all optional) are filters used to refine the user data returned. Parameter aws_iam_query_type (optional) is used to determine the type of query to perform on users.

      +

      Example workflows that use this Resilient function include Example: AWS IAM: List Users, Example: AWS IAM: List Access Keys, Example: AWS IAM: Refresh User, Example: AWS IAM: Delete Access Key For Artifact, Example: AWS IAM: Delete Login Profile, Example: AWS IAM: Delete User, Example: AWS IAM: Delete User For Artifact, Example: AWS IAM: Get Access Key For Artifact and Example: AWS IAM: Get User For Artifact.

      +

      The workflow, Example: AWS IAM: List Users, sets the following input fields for the function:

      +
        +
      • aws_iam_user_filter (optional) is mapped to an activity field input. Note: Input should be a valid regular expression.

      • +
      • aws_iam_group_filter (optional) is mapped to an activity field input. Note: Input should be a valid regular expression.

      • +
      • aws_iam_policy_filter (optional) is mapped to an activity field input. Note: Input should be a valid regular expression.

      • +
      • aws_iam_access_key_filter (optional) is mapped to an activity field input. Note: Input should be a valid regular expression.

      • +
      • aws_iam_query_type is set to value users.

      • +
      +

      The workflow is initiated by the incident rule, Example: AWS IAM: List Users.

      +
        +
      1. Open an incident and select Example: AWS IAM: List Users from Actions.

        +

        screenshot: fn-aws-iam-list-users-action

        +
      2. +
      3. The user is presented with a list of input fields which can be used to filter users using regular expressions. Set any desired filters.

        +

        screenshot: fn-aws-iam-list-users-action_2

      4. -
      5. Save and Close the app.config file.

      6. -
      7. [Optional]: Run selftest to test the Integration you configured:

        -
        $ resilient-circuits selftest -l fn-aws-iam
        +
      8. Press Execute to invoke the Example: AWS IAM: List Users workflow, which calls the AWS IAM: List Users function.

      9. +
      +

      On successful completion of the workflow, the data table AWS IAM Users is updated in the Resilient platform with the users’ properties for the selected AWS account.

      +

      screenshot: fn-aws-iam-list-users-datatable

      +

      Note: If all unfiltered users are listed, the default user for the integration is indicated by “Yes” in the “Default user” field.

      +
      Inputs: +

      +

      +

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

      Name

      Type

      Required

      Example

      Tooltip

      aws_iam_access_key_filter

      text

      No

      -

      Filter users or access keys based on access keys applied to user. Filter by access key ID. Can be a string or regular expression.

      aws_iam_group_filter

      text

      No

      -

      Filter users based on group membership. Filter by group name. Can be a string or regular expression.

      aws_iam_policy_filter

      text

      No

      -

      Filter users based on policies applied to user. Filter by policy name. Can be a string or regular expression.

      aws_iam_query_type

      select

      No

      -

      Type of query to perform for list_users, can be one of ‘users’ or ‘access_keys’. Optional parameter.

      aws_iam_user_filter

      text

      No

      -

      Filter users or access keys based on user name. Can be a string or regular expression.

      aws_iam_user_name

      text

      No

      AWS IAM user name

      AWS IAM user name.

      +
      +

      + +
      Outputs: +

      +

      results = {
      +            'version': '1.0', 'success': True, 'reason': None,
      +            'content': [{'Path': '/', 'UserName': 'iam_test_User', 'UserId': 'ABCDEFGH',
      +                         'Arn': 'arn:aws:iam::123456789123:user/iam_test_User', 'CreateDate': '2019-11-05 15:54:43'},
      +                        {'Path': '/', 'UserName': 'iam_test_User_2', 'UserId': 'ABCDEFGH',
      +                         'Arn': 'arn:aws:iam::123456789123:user/iam_test_User_2',
      +                         'CreateDate': '2019-10-31 16:23:07', 'PasswordLastUsed': '2019-11-12 10:55:42'}
      +                       ],
      +            'raw': '[{"Path": "/", "UserName": "iam_test_User", "UserId": "ABCDEFGH", "Arn": "arn:aws:iam::123456789123:user/iam_test_User", "CreateDate": "2019-11-05 15:54:43"}, {"Path": "/", "UserName": "iam_test_User_2", "UserId": "ABCDEFGH", "Arn": "arn:aws:iam::123456789123:user/iam_test_User_2", "CreateDate": "2019-10-31 16:23:07"}]',
      +            'inputs': {},
      +            'metrics': {'version': '1.0', 'package': 'fn-aws-iam', 'package_version': '1.0.0',
      +                        'host': 'myhost.ibm.com', 'execution_time_ms': 7951,
      +                        'timestamp': '2019-11-14 13:48:30'
      +                       }
      +}
       
      - -
    • Run resilient-circuits or restart the Service on Windows/Linux:

      -
      $ resilient-circuits run
      +

      +
    • +
      Example Pre-Process Script: +

      +

      import re
      +
      +# Get a list of all enabled filters.
      +ENABLED_FILTERS = [f for f in [rule.properties.aws_iam_user_filter, rule.properties.aws_iam_group_filter, 
      +                               rule.properties.aws_iam_policy_filter, rule.properties.aws_iam_access_key_filter] 
      +                   if f is not None]
      +
      +
      +def is_regex(regex_str):
      +    """"Test if sting is a correctly formed regular expression.
      +
      +    :param regex_str: Regular expression string.
      +    :return: Boolean.
      +    """
      +    try:
      +        re.compile(regex_str)
      +        return True
      +    except re.error:
      +        return False
      +
      +
      +def main():
      +    # Test any enabled filters to ensure they are valid regular expressions.
      +    for ef in (ENABLED_FILTERS):
      +        if not is_regex(ef):
      +            raise ValueError("The query filter '{}' is not a valid regular expression.".format(unicode(ef)))
      +
      +    inputs.aws_iam_user_filter = rule.properties.aws_iam_user_filter
      +    inputs.aws_iam_group_filter = rule.properties.aws_iam_group_filter
      +    inputs.aws_iam_policy_filter = rule.properties.aws_iam_policy_filter
      +    inputs.aws_iam_access_key_filter = rule.properties.aws_iam_access_key_filter
      +    inputs.aws_iam_query_type = "users"
      +
      +
      +if __name__ == "__main__":
      +    main()
       
      - -

    -
    -

    Custom Layouts

    - +

    + +
    Example Post-Process Script: +

    +

    ##  AWS IAM - fn_aws_iam_list_users script ##
    +#  Globals
    +import re
    +# List of fields in datatable fn_aws_iam_list_users script
    +DATA_TBL_FIELDS = ["query_execution_time", "UserName", "Arn", "DefaultUser", "CreateDate", "LoginProfileExists", 
    +                   "AccessKeyIds", "Policies", "Tags", "Groups"]
    +FN_NAME = "fn_aws_iam_list_users"
    +WF_NAME = "List Users"
    +# Processing
    +CONTENT = results.content
    +INPUTS = results.inputs
    +QUERY_EXECUTION_DATE = results["metrics"]["timestamp"]
    +note_text = ''
    +
    +def check_add_quotes(tag_name):
    +    # Using regex
    +    # If spaces in tag name add quotes
    +    if re.search(r"\s", tag_name):
    +        return "'"+tag_name+"'"
    +    else:
    +        return tag_name
    +
    +def process_access_key_ids(access_key_id_list, row):
    +    access_key_ids = []
    +    for ak_id in access_key_id_list:
    +        if ak_id["AccessKeyId"] is not None:
    +            access_key_ids.append(ak_id["AccessKeyId"])
    +    row.AccessKeyIds = ','.join(access_key_ids)
    +
    +def process_policies(policy_list, row):
    +    policies = []
    +    for pol in policy_list:
    +        if pol["PolicyName"] is not None:
    +            policies.append(pol["PolicyName"])
    +    row.Policies = ','.join(policies)
    +
    +def process_groups(group_list, row):
    +    groups = []
    +    for grp in group_list:
    +        if grp["GroupName"] is not None:
    +            groups.append(grp["GroupName"])
    +    row.Groups = ",".join(groups)
    +
    +def process_tags(tag_list, row):
    +    tags = []
    +    for tag in tag_list:
    +        if tag["Key"] is not None:
    +            tags.append(tag["Key"])
    +    row.Tags = ','.join(check_add_quotes(t) for t in tags)
    +
    +def main():
    +    note_text = u''
    +    filters = [f for f in [INPUTS["aws_iam_user_filter"], INPUTS["aws_iam_group_filter"],  
    +                           INPUTS["aws_iam_policy_filter"], INPUTS["aws_iam_access_key_filter"]] 
    +               if f is not None]
    +    if CONTENT:
    +        note_text = "AWS IAM Integration: Workflow <b>{0}</b>: There were <b>{1}</b> user(s) returned for Resilient function " \
    +                   "<b>{2}</b>.".format(WF_NAME, len(CONTENT), FN_NAME)
    +        note_text += "<br>Adding new row(s) to data table <b>{0}</b> for <b>{1}</b> user(s).</br>".format("AWS IAM Users", len(CONTENT))
    +        for u in CONTENT:
    +            newrow = incident.addRow("aws_iam_users")
    +            newrow.query_execution_date = QUERY_EXECUTION_DATE
    +            for f in DATA_TBL_FIELDS:
    +                newrow.Status = "Active"
    +                if u[f] is not None:
    +                    if isinstance(u[f], unicode) or isinstance(u[f], int) \
    +                            or isinstance(u[f], long) or len(u[f]) == 0:
    +                        if f == "DefaultUser" and not u[f]:
    +                            pass
    +                        else:
    +                          newrow[f] = u[f]
    +                    else:
    +                        if f == "AccessKeyIds" and len(u[f]) > 0:
    +                            process_access_key_ids(u[f], newrow)
    +                        elif f == "Policies" and len(u[f]) > 0:
    +                            process_policies(u[f], newrow)
    +                        elif f == "Groups" and len(u[f]) > 0:
    +                            process_groups(u[f], newrow)
    +                        elif f == "Tags" and len(u[f]) > 0:
    +                            process_tags(u[f], newrow)
    +                        else:
    +                            newrow[f] = ','.join(u[f])
    +    else:
    +        note_text += "AWS IAM Integration: Workflow <b>{0}</b>: There were <b>no</b> results returned for Resilient function <b>{1}</b>."\
    +            .format(WF_NAME, FN_NAME)
    +    if filters:
    +        note_text += "<br>Query Filters:</br>"
    +        if INPUTS.get("aws_iam_user_filter"): 
    +            note_text += u"<br>aws_iam_user_filter: <b>{0}</b></br>".format(INPUTS["aws_iam_user_filter"])
    +        if INPUTS.get("aws_iam_group_filter"): 
    +            note_text += u"<br>aws_iam_group_filter: <b>{0}</b></br>".format(INPUTS["aws_iam_group_filter"])
    +        if INPUTS.get("aws_iam_policy_filter"): 
    +            note_text += u"<br>aws_iam_policy_filter: <b>{0}</b></br>".format(INPUTS["aws_iam_policy_filter"])
    +        if INPUTS.get("aws_iam_access_key_filter"):   
    +            note_text += u"<br>aws_iam_access_key_filter: <b>{0}</b></br>".format(INPUTS["aws_iam_access_key_filter"])
    +    incident.addNote(helper.createRichText(note_text))
    +if __name__ == "__main__":
    +    main()
    +
    +
    +

    +
    +

    The workflow, Example: AWS IAM: List Access keys, sets the following input fields for the function:

      -
    • To use the functions, the SOAR playbook designer should create a new Incident tab containing the data tables. Drag the AWS IAM data tables on to the layout and click Save as shown in the screenshot below: -screenshot: custom_layouts

    • +
    • aws_iam_user_filter (optional) is mapped to an activity field input. Note: Input should be a valid regular expression.

    • +
    • aws_iam_access_key_filter (optional) is mapped to an activity field input. Note: Input should be a valid regular expression.

    • +
    • aws_iam_query_type is set to value access_keys.

    -
    -
-
-
-

Uninstall

-
    -
  • SSH into your Integration Server.

  • -
  • Uninstall the package:

    -
    $ pip uninstall fn-aws-iam
    +

    The workflow is initiated by the incident rule, Example: AWS IAM: List Access keys.

    +
      +
    1. Open an incident and select Example: AWS IAM: List Access keys from Actions.

      +

      screenshot: fn-aws-iam-list-keys-action

      +
    2. +
    3. The user is presented with a list of input fields which can be used to filter users using regular expressions. Set any desired filters.

      +

      screenshot: fn-aws-iam-list-keys-action_2

      +
    4. +
    5. Press Execute to invoke the Example: AWS IAM: List Access keys workflow, which calls the AWS IAM: List Users function.

    6. +
    +

    On successful completion of the workflow, the data table AWS IAM Access Keys is updated in the Resilient platform with the users’ properties for the selected AWS account.

    +

    screenshot: fn-aws-iam-list-keys-datatable

    +

    Note: If all unfiltered access keys are listed, the key for the default user for the integration is indicated by “Yes” in the “Default key” field.

    +
    Inputs: +

    +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    Name

    Type

    Required

    Example

    Tooltip

    aws_iam_access_key_filter

    text

    No

    -

    Filter users or access keys based on access keys applied to user. Filter by access key ID. Can be a string or regular expression.

    aws_iam_group_filter

    text

    No

    -

    Filter users based on group membership. Filter by group name. Can be a string or regular expression.

    aws_iam_policy_filter

    text

    No

    -

    Filter users based on policies applied to user. Filter by policy name. Can be a string or regular expression.

    aws_iam_query_type

    select

    No

    -

    Type of query to perform for list_users, can be one of ‘users’ or ‘access_keys’. Optional parameter.

    aws_iam_user_filter

    text

    No

    -

    Filter users or access keys based on user name. Can be a string or regular expression.

    aws_iam_user_name

    text

    No

    AWS IAM user name

    AWS IAM user name.

    +
    +

    +
    +
    Outputs: +

    +

    results =  {
    +            'version': '1.0', 'success': True, 'reason': None,
    +            'content': [{'Path': '/', 'UserName': 'iam_test_User', 'UserId': 'ABCDEFGH',
    +                         'Arn': 'arn:aws:iam::123456789123:user/iam_test_User', 'CreateDate': '2019-11-05 15:54:43'},
    +                        {'Path': '/', 'UserName': 'iam_test_User_2', 'UserId': 'ABCDEFGH',
    +                         'Arn': 'arn:aws:iam::123456789123:user/iam_test_User_2',
    +                         'CreateDate': '2019-10-31 16:23:07', 'PasswordLastUsed': '2019-11-12 10:55:42'}
    +                       ],
    +            'raw': '[{"Path": "/", "UserName": "iam_test_User", "UserId": "ABCDEFGH", "Arn": "arn:aws:iam::123456789123:user/iam_test_User", "CreateDate": "2019-11-05 15:54:43"}, {"Path": "/", "UserName": "iam_test_User_2", "UserId": "ABCDEFGH", "Arn": "arn:aws:iam::123456789123:user/iam_test_User_2", "CreateDate": "2019-10-31 16:23:07"}]',
    +            'inputs': {},
    +            'metrics': {'version': '1.0', 'package': 'fn-aws-iam', 'package_version': '1.0.0',
    +                        'host': 'myhost.ibm.com', 'execution_time_ms': 7951,
    +                        'timestamp': '2019-11-14 13:48:30'
    +                       }
    +}
     
    -
  • -
  • Open the config file, scroll to the [fn_aws_iam] section and remove the section or prefix # to comment out the section.

  • -
  • Save and Close the app.config file.

  • -
+

+ +
Example Pre-Process Script: +

+

inputs.aws_iam_access_key_filter = rule.properties.aws_iam_access_key_filter
+inputs.aws_iam_user_filter = rule.properties.aws_iam_user_filter
+inputs.aws_iam_query_type = "access_keys"
+
+
+

+
+
Example Post-Process Script: +

+

##  AWS IAM - fn_aws_iam_list_users script ##
+#  Globals
+import re
+# List of fields in datatable fn_aws_iam_list_users script main
+DATA_TBL_FIELDS = ["query_execution_time", "UserName", "AccessKeyId", "CreateDate", "Status", "DefaultKey"]
+# List of fields in datatable fn_aws_iam_list_users script last used access keys.
+DATA_TBL_FIELDS_LUAK = ["LastUsedDate", "ServiceName", "Region"]
+FN_NAME = "fn_aws_iam_list_users"
+WF_NAME = "List Access Keys"
+# Processing
+CONTENT = results.content
+INPUTS = results.inputs
+QUERY_EXECUTION_DATE = results["metrics"]["timestamp"]
+
+def process_access_keys(access_key_id_list, user_name):
+    access_key_ids = []
+    for ak_id in access_key_id_list:
+        newrow = incident.addRow("aws_iam_access_keys")
+        newrow.query_execution_date = QUERY_EXECUTION_DATE
+        newrow.UserName = user_name
+        for f in DATA_TBL_FIELDS[2:]:
+            if ak_id[f] is not None:
+                newrow[f] = ak_id[f]
+        # Add key last used data if it exists.
+        if ak_id["key_last_used"] is not None:
+            luak = ak_id["key_last_used"]
+            for l in DATA_TBL_FIELDS_LUAK:
+                if luak[l] is not None:
+                    newrow[l] = luak[l]
+def main():
+    note_text = u''
+    filters = [f for f in [INPUTS["aws_iam_user_filter"], INPUTS["aws_iam_group_filter"],
+                           INPUTS["aws_iam_policy_filter"], INPUTS["aws_iam_access_key_filter"]]
+               if f is not None]
+    if CONTENT:
+        key_count = 0
+        for u in CONTENT:
+           if u["AccessKeyIds"]:
+                for k in  u["AccessKeyIds"]:
+                    key_count += 1
+        note_text = "AWS IAM Integration: Workflow <b>{0}</b>: There were <b>{1}</b> access keys(s) returned for Resilient function " \
+                   "<b>{2}</b>.".format(WF_NAME, key_count, FN_NAME)
+        note_text += "<br>Adding new rows to data table <b>{0}</b> for <b>{1}</b> access keys(s).</br>".format("AWS IAM Access Keys", key_count)
+        for u in CONTENT:
+           if u["AccessKeyIds"]:
+                user_name = u["UserName"]
+                process_access_keys(u["AccessKeyIds"], user_name)
+
+    else:
+        note_text += "AWS IAM Integration: Workflow <b>{0}</b>: There were <b>no</b> results returned for Resilient function <b>{1}</b>."\
+            .format(WF_NAME, FN_NAME)
+
+    if filters:
+        note_text += "<br>Query Filters:</br>"
+        if INPUTS.get("aws_iam_user_filter"):
+            note_text += u"<br>aws_iam_user_filter: <b>{0}</b></br>".format(INPUTS["aws_iam_user_filter"])
+        if INPUTS.get("aws_iam_access_key_filter"):
+            note_text += u"<br>aws_iam_access_key_filter: <b>{0}</b></br>".format(INPUTS["aws_iam_access_key_filter"])
+    incident.addNote(helper.createRichText(note_text))
+if __name__ == "__main__":
+    main()
+
+
+

+

-
-

Troubleshooting

-

There are several ways to verify the successful operation of a function.

-
-

SOAR Action Status

-
    -
  • When viewing an incident, use the Actions menu to view Action Status.

  • -
  • By default, pending and errors are displayed.

  • -
  • Modify the filter for actions to also show Completed actions.

  • -
  • Clicking on an action displays additional information on the progress made or what error occurred.

  • -
-
-
-

SOAR Scripting Log

+
+

Function - AWS IAM: Delete User

+

Delete the specified IAM user. Parameter aws_iam_user_name is an IAM user name.

+

When deleting an IAM user programmatically, the workflow deletes or removes the following items attached to the user:

+
Password
+Access keys
+Inline policies
+Attached managed policies
+Group memberships
+Signing certificates
+SSH public keys
+Service specific credentials
+Deactivate Multi-factor authentication (MFA) devices
+Delete virtual MFA Devices
+
+
+

Example workflows that use this Resilient function include Example: AWS IAM: Delete User or Example: AWS IAM: Delete User For Artifact.

+

Both of the example workflows are multi-step functions and will attempt to remove or delete the items referenced above if associated with the user, +and then attempt to delete the user.

+

If any of the items mentioned above exist for the user, the workflow will fail.

+

The workflow, Example: AWS IAM: Delete User, sets the following input field for the function:

    -
  • A separate log file is available to review scripting errors.

  • -
  • This is useful when issues occur in the pre-processing or post-processing scripts.

  • -
  • The default location for this log file is: /var/log/resilient-scripting/resilient-scripting.log.

  • +
  • aws_iam_user_name is mapped to a user name from the selected data table row Example: AWS IAM: Delete User or artifact.

-
-
-

SOAR Logs

+

The workflow is initiated by the data table rule, Example: AWS IAM: Delete User.

+
    +
  1. Open an incident and select the row of data table AWS IAM Users corresponding to the user whose access keys are to be deleted.

  2. +
  3. From the selected row’s actions menu, select Example: AWS IAM: Delete User.

    +

    screenshot: fn-aws-iam-delete-user-action

    +
  4. +
+

The user is presented with a warning and an option to Execute or Cancel.

+

screenshot: fn-aws-iam-delete-user-action_2

+
    +
  1. Press Execute to invoke the Example: AWS IAM: Delete User workflow, which calls the AWS IAM: Delete User function.

  2. +
+

On successful completion of the workflow, the data table AWS IAM Users is refreshed in the Resilient platform with the updated access key details for the selected user. The Status field of the data table transitions to Deleted.

+

screenshot: fn-aws-iam-delete-user-datatable

+

The workflow, Example: AWS IAM: Delete User For Artifact, sets the following input fields for the function:

    -
  • By default, SOAR logs are retained at /usr/share/co3/logs.

  • -
  • The client.log may contain additional information regarding the execution of functions.

  • +
  • aws_iam_user_name is mapped to an artifact value for artifact of type AWS IAM User Name.

+

The workflow is initiated by the artifact rule, Example: AWS IAM: Delete User For Artifact.

+
    +
  1. Open an incident and select the ‘Artifacts’ tab.

  2. +
  3. For a Resilient artifact of type, ‘AWS IAM User Name’, click Action-> Example: AWS IAM: Delete User For Artifact.

    +

    screenshot: fn-aws-iam-delete-user-artifact-action

    +
  4. +
+

The user is presented with a warning and an option to Execute or Cancel.

+

screenshot: fn-aws-iam-delete-user-artifact-action_2

+
    +
  1. Press Execute to invoke the Example: AWS IAM: Delete User For Artifact workflow, which calls the AWS IAM: Delete User function.

  2. +
+

On successful completion of the workflow, the artifact description is updated with details of the user deletion.

+

screenshot: fn-aws-iam-delete-user-artifact

+
Inputs: +

+

+ + + + + + + + + + + + + + + + + +

Name

Type

Required

Example

Tooltip

aws_iam_user_name

text

Yes

AWS IAM user name

AWS IAM user name.

+
+

+
+
Outputs: +

+

results = { 'version': '1.0', 'success': True, 'reason': None,
+            'content': 'OK', 
+            'raw': '"OK"', 
+            'inputs': {'aws_iam_user_name': 'iam_test_user'}, 
+            'metrics': {'version': '1.0', 'package': 'fn-aws-iam', 'package_version': '1.0.0', 'host': 'myhost.ibm.com', 
+                        'execution_time_ms': 689, 'timestamp': '2020-01-15 10:27:48'
+                       }
+}
+
+
+

+
+
Example Pre-Process Script: +

+

inputs.aws_iam_user_name = row.UserName
+
+
+

+
+
Example Post-Process Script: +

+

##  AWS IAM - fn_aws_iam_delete_access_keys script ##
+#  Globals
+# List of fields in datatable for fn_aws_iam_delete_user  script
+DATA_TBL_FIELDS = ["Status"]
+FN_NAME = "fn_aws_iam_delete_user"
+WF_NAME = "Delete User"
+# Processing
+CONTENT = results.content
+INPUTS = results.inputs
+
+def main():
+    note_text = ''
+    if CONTENT:
+        if CONTENT == "OK":
+            note_text = "AWS IAM Integration: : Workflow <b>{0}</b>: User <b>{1}</b> was successfully deleted for " \
+                        "Resilient function <b>{2}</b>.".format(WF_NAME, INPUTS["aws_iam_user_name"], FN_NAME)
+            row.Status = "Deleted"
+            row.Tags = ''
+        else:
+            note_text = "AWS IAM Integration: : Workflow <b>{0}</b>: Unexpected delete status <b>{1}</b> for delete" \
+                        " user operation <b>{2}</b> for Resilient function <b>{3}</b>."\
+                .format(WF_NAME, CONTENT, INPUTS["aws_iam_user_name"], FN_NAME)
+    else:
+        note_text += "AWS IAM Integration: Workflow <b>{0}</b>: There was no result returned for Resilient function <b>{0}</b>."\
+            .format(WF_NAME, FN_NAME)
+
+    incident.addNote(helper.createRichText(note_text))
+if __name__ == "__main__":
+    main()
+
+
+

+
-
-

Resilient-Circuits

+
+
+

Function - AWS IAM: List User Access Key IDs

+

Gets information about the access key IDs associated with the specified IAM user. Parameter aws_iam_user_name is an IAM user name.

+

Example workflows that use this Resilient function include Example: AWS IAM: Delete Access Keys, Example: AWS IAM: Refresh User, Example: AWS IAM: Get User For Artifact, Example: AWS IAM: Delete User or Example: AWS IAM: Delete User For Artifact.

+

The workflow, Example: AWS IAM: Refresh User, sets the following input field for the function:

    -
  • The log is controlled in the .resilient/app.config file under the section [resilient] and the property logdir.

  • -
  • The default file name is app.log.

  • -
  • Each function will create progress information.

  • -
  • Failures will show up as errors and may contain python trace statements.

  • +
  • aws_iam_user_name is mapped to a user name from the selected data table row.

-
-
-
-
-

Support

+

The workflow is initiated by the data table rule, Example: AWS IAM: Refresh User.

+
    +
  1. Open an incident and select the row of data table AWS IAM Users corresponding to the user which is to have its properties refreshed for the data table.

  2. +
  3. From the selected row’s actions menu, select Example: AWS IAM: Refresh User.

    +

    screenshot: fn-aws-iam-list-user-access-key-ids-action

    +
  4. +
  5. Press Execute to invoke the Example: AWS IAM: Refresh User workflow, which calls the AWS IAM: List User Access Key IDs function.

  6. +
+

On successful completion of the workflow, the Access key ids field of the AWS IAM Users data table is updated for the selected user.

+

screenshot: fn-aws-iam-list-user-access-key-ids-datatable

+
Inputs: +

- - - + + + + - - - - + + + + +

Name

Version

Author

Support URL

Type

Required

Example

Tooltip

fn_aws_iam

1.0.2

IBM SOAR Support

https://ibm.com/mysupport

aws_iam_user_name

text

Yes

AWS IAM user name

AWS IAM user name.

-
-
+

+ +
Outputs: +

+

results = {
+          'version': '1.0', 'success': True, 'reason': None,
+          'content': [{'UserName': 'iam_test_User', 'AccessKeyId': 'ABCDEFGH',
+                       'Status': 'Active', 'CreateDate': '2019-11-12 11:09:38'
+                      }
+                     ],
+          'raw': '[{"UserName": "iam_test_User", "AccessKeyId": "ABCDEFGH", "Status": "Active", "CreateDate": "2019-11-12 11:09:38"}]',
+          'inputs': {'aws_iam_user_name': 'iam_test_User'},
+          'metrics': {'version': '1.0', 'package': 'fn-aws-iam', 'package_version': '1.0.0',
+                      'host': 'myhost.ibm.com', 'execution_time_ms': 5365, 'timestamp': '2019-11-21 10:41:22'}
+}
+
+
+

+
+
Example Pre-Process Script: +

+

inputs.aws_iam_user_name = row.UserName
+
+
+

+
+
Example Post-Process Script: +

+

##  AWS IAM - fn_aws_iam_list_user_access_keys script ##
+#  Globals
+# List of fields in datatable fn_aws_iam_list_user_access_keys script
+DATA_TBL_FIELDS = ["AccessKeyIds"]
+FN_NAME = "fn_aws_iam_list_user_access_keys"
+WF_NAME = "Refresh User"
+# Processing
+CONTENT = results.content
+INPUTS = results.inputs
+note_text = ''
 
-