AWS IAM¶
Table of Contents¶
Release Notes¶
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 |
Overview¶
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:
Get a list of users and associated items (login profile, access keys, groups, policies).
Get a list of access keys.
List objects associated with a user:
Access keys.
Groups.
Policies.
SSH public keys.
Service-specific credentials.
Signing certificates.
Active MFA devices (Virtual devices flagged).
You can also use the integration to make the following changes to an AWS IAM environment:
Delete a user and delete or remove items associated with the user.
Attach a user policy.
Detach all policies for a user.
Add a user to a group.
Remove a user from all groups.
Change a user profile password.
Delete an access key.
Delete all access keys for a user.
Delete the login profile for a user.
Delete all SSH Public Keys for a user.
Delete all service-specific credentials for a user.
Delete all signing certificates for a user.
De-activate all active MFA devices for a user.
Delete all active MFA virtual devices for a user.
The integration contains the following functions: ¶
Requirements¶
SOAR platform >=
51.0.0.0.9340
An Integration Server running:
resilient_circuits>=35.0.0
resilient_lib>=35.0.0
The minimum set of SOAR API permissions for this integration if using an API key account:
Edit Org Data
Incidents.Edit.Fields
Functions.Read
Functions.Edit
Layouts.Read
Other.ReadIncidentsActionInvocations
Scripts.Create
Scripts.Edit
Workflows.Create
Workflow.Edit
To set up an Integration Server see: ibm.biz/res-int-server-guide
An AWS IAM user dedicated for this integration with the following configuration:
User account is not the AWS IAM root account user.
User is added to an “Administrators” group to which is attached the
AdministratorAccess
policy.An access key created for the user. The user access key ID and secret access key are used by the integration.
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 atar.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.
Download the app
app-fn_aws_iam-x.x.x.zip
.Navigate to Administrative Settings and then the Apps tab.
Click the Install button and select the downloaded file: app-fn_aws_iam-x.x.x.zip.
Go to the Configuration tab and edit the app.config file, editing the access key values for Amazon AWS IAM and add a proxy setting if required.
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.Unzip the app:
$ unzip app-fn_aws_iam-x.x.x.zip
Install the package:
$ pip install fn_aws_iam-x.x.x.tar.gz
Import the configurations into your app.config file:
$ resilient-circuits config -u
Import the fn_aws_iam customizations into the SOAR platform:
$ resilient-circuits customize -y -l fn-aws-iam
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.
Config |
Required |
Example |
Description |
---|---|---|---|
aws_iam_access_key_id |
Yes |
|
AWS access key id of user with programmatic (API) access to AWS IAM services for an AWS account. Note: User must have sufficent permissions to be able to manage IAM resources for the AWS account. |
aws_iam_secret_access_key |
Yes |
|
AWS secret access key used for programmatic (API) access to AWS services. |
http_proxy |
No |
|
Optional setting for an http proxy if required. |
https_proxy |
No |
|
Optional setting for an http proxy if required. |
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
.
Open an incident and select
Example: AWS IAM: List Users
from Actions.The user is presented with a list of input fields which can be used to filter users using regular expressions. Set any desired filters.
Press Execute to invoke the
Example: AWS IAM: List Users
workflow, which calls theAWS IAM: List Users
function.
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.
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 |
---|---|---|---|---|
|
|
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. |
|
|
No |
|
Filter users based on group membership. Filter by group name. Can be a string or regular expression. |
|
|
No |
|
Filter users based on policies applied to user. Filter by policy name. Can be a string or regular expression. |
|
|
No |
|
Type of query to perform for list_users, can be one of ‘users’ or ‘access_keys’. Optional parameter. |
|
|
No |
|
Filter users or access keys based on user name. Can be a string or regular expression. |
|
|
No |
|
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'
}
}
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()
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:
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
.
The workflow is initiated by the incident rule, Example: AWS IAM: List Access keys
.
Open an incident and select
Example: AWS IAM: List Access keys
from Actions.The user is presented with a list of input fields which can be used to filter users using regular expressions. Set any desired filters.
Press Execute to invoke the
Example: AWS IAM: List Access keys
workflow, which calls theAWS IAM: List Users
function.
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.
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 |
---|---|---|---|---|
|
|
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. |
|
|
No |
|
Filter users based on group membership. Filter by group name. Can be a string or regular expression. |
|
|
No |
|
Filter users based on policies applied to user. Filter by policy name. Can be a string or regular expression. |
|
|
No |
|
Type of query to perform for list_users, can be one of ‘users’ or ‘access_keys’. Optional parameter. |
|
|
No |
|
Filter users or access keys based on user name. Can be a string or regular expression. |
|
|
No |
|
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'
}
}
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()
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:
aws_iam_user_name is mapped to a user name from the selected data table row
Example: AWS IAM: Delete User
or artifact.
The workflow is initiated by the data table rule, Example: AWS IAM: Delete User
.
Open an incident and select the row of data table
AWS IAM Users
corresponding to the user whose access keys are to be deleted.From the selected row’s actions menu, select
Example: AWS IAM: Delete User
.
The user is presented with a warning and an option to Execute or Cancel.
Press Execute to invoke the
Example: AWS IAM: Delete User
workflow, which calls theAWS IAM: Delete User
function.
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
.
The workflow, Example: AWS IAM: Delete User For Artifact
, sets the following input fields for the function:
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
.
Open an incident and select the ‘Artifacts’ tab.
For a Resilient artifact of type, ‘AWS IAM User Name’, click Action->
Example: AWS IAM: Delete User For Artifact
.
The user is presented with a warning and an option to Execute or Cancel.
Press Execute to invoke the
Example: AWS IAM: Delete User For Artifact
workflow, which calls theAWS IAM: Delete User
function.
On successful completion of the workflow, the artifact description is updated with details of the user deletion.
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
Yes |
|
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()
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:
aws_iam_user_name is mapped to a user name from the selected data table row.
The workflow is initiated by the data table rule, Example: AWS IAM: Refresh User
.
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.From the selected row’s actions menu, select
Example: AWS IAM: Refresh User
.Press Execute to invoke the
Example: AWS IAM: Refresh User
workflow, which calls theAWS IAM: List User Access Key IDs
function.
On successful completion of the workflow, the Access key ids
field of the AWS IAM Users
data table is updated for the selected user.
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
Yes |
|
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 = ''
def main():
if CONTENT:
access_key_ids = []
for ak_id in CONTENT:
if ak_id["AccessKeyId"] is not None:
access_key_ids.append(ak_id["AccessKeyId"])
row.AccessKeyIds = ",".join(access_key_ids)
else:
row.AccessKeyIds = ""
if __name__ == "__main__":
main()
Function - AWS IAM: Update Access Key¶
Change the status of an access key from Active to Inactive, or vice versa. Parameter aws_iam_user_name is an IAM user name. Parameter aws_iam_access_key_id is an IAM user access key id. Parameter aws_iam_status is be set to “Active” or “Inactive” to change the status of the access key.
Example workflows that use this Resilient function include Example: AWS IAM: Deactivate Access Key
.
The workflow, Example: AWS IAM: Deactivate Access Key
, sets the following input field for the function:
aws_iam_user_name is mapped to a user name from the selected data table row.
aws_iam_access_key_id = is mapped to an access key ID from the selected data table row.
aws_iam_status = is set to the value “Inactive”.
The workflow is initiated by the data table rule, Example: AWS IAM: Deactivate Access Key
.
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.From the selected row’s actions menu, select
Example: AWS IAM: Deactivate Access Key
.
The user is presented with a warning and an option to Execute or Cancel.
Press Execute to invoke the
Example: AWS IAM: Deactivate Access Key
workflow, which calls theAWS IAM: Update Access Key
function.
On successful completion of the workflow, the Status
field of the AWS IAM Access Keys
data table is transitioned to Inactive
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
No |
|
- |
|
|
No |
|
- |
|
|
No |
|
AWS IAM user name. |
Outputs:
results = {'inputs': {'aws_iam_user_name': 'iam_test_user', 'aws_iam_access_key_id': 'ABCDEFGH',
'aws_iam_status': 'Inactive'},
'metrics': {'package': 'fn-aws-iam', 'timestamp': '2020-02-19 12:53:48', 'package_version': '1.0.0',
'host': 'myhost.ibm.com', 'version': '1.0', 'execution_time_ms': 3023},
'success': True,
'content': 'OK',
'raw': '"OK"',
'reason': None,
'version': '1.0'
}
Example Pre-Process Script:
inputs.aws_iam_access_key_id = row.AccessKeyId
inputs.aws_iam_user_name = row.UserName
inputs.aws_iam_status = "Inactive"
Example Post-Process Script:
# Globals
# List of fields in datatable for fn_aws_iam_delete_access_keys script
DATA_TBL_FIELDS = ["AccessKeyIds"]
FN_NAME = "fn_aws_iam_update_access_key"
WF_NAME = "Deactivate Access Key"
# Processing
CONTENT = results.content
INPUTS = results.inputs
def main():
note_text = u''
if CONTENT:
if CONTENT == "OK":
note_text = u"AWS IAM Integration: Workflow <b>{0}</b>: The Access Key Id <b>{1}</b> was deactivated " \
u"for user <b>{2}</b> for Resilient function <b>{3}</b>."\
.format(WF_NAME, INPUTS["aws_iam_access_key_id"], INPUTS["aws_iam_user_name"], FN_NAME)
row.Status = "Inactive"
elif CONTENT == u"NoSuchEntity":
note_text = u"AWS IAM Integration: Workflow <b>{0}</b>: The Access Key Id <b>{1}</b> Not found " \
u"for user <b>{2}</b> for Resilient function <b>{3}</b>."\
.format(WF_NAME, INPUTS["aws_iam_access_key_id"], INPUTS["aws_iam_user_name"], FN_NAME)
row.Status = "NoSuchEntity"
else:
note_text += u"AWS IAM Integration: Workflow <b>{0}</b>: There were no results returned for " \
u"access key id <b>{1}</b> access key Resilient function <b>{2}</b>."\
.format(WF_NAME, INPUTS["aws_iam_access_keys"], FN_NAME)
incident.addNote(helper.createRichText(note_text))
if __name__ == "__main__":
main()
Function - AWS IAM: Delete Access Keys¶
Delete the access key pairs associated with the specified IAM user. Parameter aws_iam_user_name is an IAM user name. Parameter aws_iam_access_keys is a comma-separated list of IAM access key IDs.
Example workflows that use this Resilient function include Example: AWS IAM: Delete Access Keys
, Example: AWS IAM: Delete Access Key
, Example: AWS IAM: Delete Access Key For Artifact
, Example: AWS IAM: Delete User
or Example: AWS IAM: Delete User For Artifact
.
The workflow, Example: AWS IAM: Delete Access Keys
, sets the following input fields for the function:
aws_iam_user_name is mapped to a user name from the selected row of data table
AWS IAM Users
.aws_iam_access_keys is mapped to all access keys for the user from the selected row of data table
AWS IAM Users
.
The workflow is initiated by the data table rule, Example: AWS IAM: Delete Access Keys
.
Open an incident and select the row of data table
AWS IAM Users
corresponding to the user whose access keys are to be deleted.From the selected row’s actions menu, select
Example: AWS IAM: Delete Access Keys
.
The user is presented with a warning and an option to Execute or Cancel.
Press Execute to invoke the
Example: AWS IAM: Delete Access Keys
workflow, which calls theAWS IAM: Delete Access Keys
function.
On successful completion of the workflow, the Access key ids
field of the AWS IAM Users
data table is updated for the selected user.
The workflow, Example: AWS IAM: Delete Access Key
, sets the following input fields for the function:
aws_iam_user_name is mapped to a user name from the selected row of data table
AWS IAM Access Keys
.aws_iam_access_keys is mapped to the access key ID from the selected row of data table
AWS IAM Access Keys
.
The workflow is initiated by the data table rule, Example: AWS IAM: Delete Access Key
.
Open an incident and select the row of data table
AWS IAM Access Keys
corresponding to the access key to be deleted.From the selected row’s actions menu, select
Example: AWS IAM: Delete Access Key
.
The user is presented with a warning and an option to Execute or Cancel.
Press Execute to invoke the
Example: AWS IAM: Delete Access Key
workflow, which calls theAWS IAM: Delete Access Keys
function.
On successful completion of the workflow, the Status
field of the AWS IAM Access Keys
data table is transitioned to Deleted
.
The workflow, Example: AWS IAM: Delete Access Key For Artifact
, sets the following input fields for the function:
aws_iam_user_name is mapped to a user name computed from a previous step in the workflow.
aws_iam_access_keys is mapped to an artifact value for artifact of type
AWS IAM Access Key ID
.
The workflow is initiated by the artifact rule, Example: AWS IAM: Delete Access Key For Artifact
.
Open an incident and select the ‘Artifacts’ tab.
For a Resilient artifact of type
AWS IAM Access Key ID
, click Action->Example: AWS IAM: Delete Access Key For Artifact
.
The user is presented with a warning and an option to Execute or Cancel.
Press Execute to invoke the
Example: AWS IAM: Delete Access Key For Artifact
workflow, which calls theAWS IAM: Delete Access Keys
function.
On successful completion of the workflow, the artifact description is updated with details of access key deletion.
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
Yes |
|
Comma-seperated list of AWS IAM access key names. |
|
|
Yes |
|
AWS IAM user name. |
Outputs:
results = {'version': '1.0', 'success': True, 'reason': None,
'content': [{'AccessKeyId': 'ABCDEFGH', 'Status': 'OK'}],
'raw': '[{"AccessKeyId": "ABCDEFGH", "Status": "OK"}]',
'inputs': {'aws_iam_user_name': 'iam_test_User_1', 'aws_iam_access_keys': 'ABCDEFGH'},
'metrics': {'version': '1.0', 'package': 'fn-aws-iam', 'package_version': '1.0.0',
'host': 'myhost.ibm.com', 'execution_time_ms': 752, 'timestamp': '2020-01-16 13:47:07'
}
}
Example Pre-Process Script:
inputs.aws_iam_user_name = row.UserName
inputs.aws_iam_access_keys = row.AccessKeyIds
Example Post-Process Script:
## AWS IAM - fn_aws_iam_delete_access_keys script ##
# Globals
# List of fields in datatable for fn_aws_iam_delete_access_keys script
DATA_TBL_FIELDS = ["AccessKeyIds"]
FN_NAME = "fn_aws_iam_delete_access_keys"
WF_NAME = "Delete Access Key"
# Processing
CONTENT = results.content
INPUTS = results.inputs
EXECUTION_DATE = results["metrics"]["timestamp"]
def main():
note_text = ''
deleted = 0
no_such_entity = 0
deleted_keys = []
no_such_entity_keys = []
if CONTENT:
for ak_stat in CONTENT:
if ak_stat["Status"] == "OK":
deleted += 1
deleted_keys.append(ak_stat["AccessKeyId"])
else:
no_such_entity += 1
no_such_entity_keys.append(ak_stat["AccessKeyId"])
if deleted_keys:
note_text = "AWS IAM Integration: Workflow <b>{0}</b>: The Access Key Id <b>{1}</b> was deleted " \
"for user <b>{2}</b> for Resilient function <b>{3}</b>."\
.format(WF_NAME, ','.join(deleted_keys), INPUTS["aws_iam_user_name"], FN_NAME)
if no_such_entity:
note_text = "AWS IAM Integration: : Workflow <b>{0}</b>: Access keyId id <b>{1}</b> does not exist " \
"for user <b>{2}</b> for Resilient function <b>{3}</b>."\
.format(WF_NAME, ','.join(no_such_entity_keys), INPUTS["aws_iam_user_name"], FN_NAME)
row.Status = "Deleted"
row.query_execution_date = EXECUTION_DATE
else:
note_text += "AWS IAM Integration: Workflow <b>{0}</b>: There were no results returned for " \
"access key id <b>{1}</b> access key Resilient function <b>{2}</b>."\
.format(WF_NAME, INPUTS["aws_iam_access_keys"], FN_NAME)
incident.addNote(helper.createRichText(note_text))
if __name__ == "__main__":
main()
Function - AWS IAM: List User Groups¶
Gets the IAM groups that include 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: Refresh User
, Example: AWS IAM: Add User To Group
, Example: AWS IAM: Remove User From All Groups
, Example: AWS IAM: Delete User
or , Example: AWS IAM: Delete User For Artifact
.
The workflow, Example: AWS IAM: Refresh User
, sets the following input fields for the function:
aws_iam_user_name is mapped to a user name from the selected row of data table
AWS IAM Users
.
The workflow is initiated by the data table rule, Example: AWS IAM: Refresh User
.
Open an incident and select the row of data table
AWS IAM Users
corresponding to the user who needs to be added to a group.From the selected row’s actions menu, select
Example: AWS IAM: Refresh User
.
This invokes the Example: AWS IAM: Refresh User
workflow, which calls the AWS IAM: List User Groups
function.
On successful completion of the workflow, the Groups
field of the AWS IAM Users
data table is updated for the selected user.
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
Yes |
|
AWS IAM user name. |
Outputs:
results = {'version': '1.0', 'success': True, 'reason': None,
'content': [{'Path': '/', 'GroupName': 'null_group', 'GroupId': 'ABCDEFGH',
'Arn': 'arn:aws:iam::123456789123:group/null_group', 'CreateDate': '2019-12-04 12:31:47'},
{'Path': '/', 'GroupName': 'denyall_group', 'GroupId': 'ABCDEFGH',
'Arn': 'arn:aws:iam::123456789123:group/denyall_group', 'CreateDate': '2019-11-29 15:49:34'},
{'Path': '/', 'GroupName': 'myS3group', 'GroupId': 'ABCDEFGH',
'Arn': 'arn:aws:iam::123456789123:group/myS3group', 'CreateDate': '2017-05-29 20:41:50'}],
'raw': '[{"Path": "/", "GroupName": "null_group", "GroupId": "ABCDEFGH",' \
'"Arn": "arn:aws:iam::123456789123:group/null_group", "CreateDate": "2019-12-04 12:31:47"},' \
'"Path": "/", "GroupName": "denyall_group", "GroupId": "ABCDEFGH",' \
'"Arn": "arn:aws:iam::123456789123:group/denyall_group", "CreateDate": "2019-11-29 15:49:34"},' \
'{"Path": "/", "GroupName": "myS3group", "GroupId": "ABCDEFGH",' \
'"Arn": "arn:aws:iam::123456789123:group/myS3group", "CreateDate": "2017-05-29 20:41:50"}]' ,
'inputs': {'aws_iam_user_name': 'iam_test_user_1'},
'metrics': {'version': '1.0', 'package': 'fn-aws-iam', 'package_version': '1.0.0', 'host': 'myhost.ie.ibm.com',
'execution_time_ms': 944, 'timestamp': '2020-03-16 15:43:21'
}
}
Example Pre-Process Script:
inputs.aws_iam_user_name = row.UserName
Example Post-Process Script:
## AWS IAM - fn_aws_iam_list_user_groups script ##
# Globals
# List of fields in datatable fn_aws_iam_list_user_groups script
DATA_TBL_FIELDS = ["Groups"]
FN_NAME = "fn_aws_iam_list_user_groups"
WF_NAME = "Refresh User"
# Processing
CONTENT = results.content
INPUTS = results.inputs
QUERY_EXECUTION_DATE = results["metrics"]["timestamp"]
note_text = ''
def main():
if CONTENT:
groups = []
for grp in CONTENT:
if grp["GroupName"] is not None:
groups.append(grp["GroupName"])
row.Groups = ",".join(groups)
else:
row.Groups = ""
if __name__ == "__main__":
main()
Function - AWS IAM: Add User To Groups¶
Adds the specified IAM user to the specified groups. Parameter aws_iam_user_name is an IAM user name. Parameter aws_iam_group_names is a comma-separated list of IAM group names.
Example workflows that use this Resilient function include Example: AWS IAM: Add User To Group
.
The workflow, Example: AWS IAM: Add User To Group
, sets the following input fields for the function:
aws_iam_user_name is mapped to a user name from the selected row of data table
AWS IAM Users
.aws_iam_group_names is mapped to an activity field, which is a drop-down list of group names.
The workflow is initiated by the data table rule, Example: AWS IAM: Add User To Group
.
Open an incident and select the row of data table
AWS IAM Users
corresponding to the user who needs to be added to a group.From the selected row’s actions menu, select
Example: AWS IAM: Add User To Group
.From the drop-down list of user defined groups names, select a group and click Execute.
This invokes the Example: AWS IAM: Add User To Group
workflow, which calls the AWS IAM: Add User To Groups
function.
On successful completion of the workflow, the Groups
field of the AWS IAM Users
data table is updated for the selected user.
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
Yes |
|
Comma-separated list of AWS IAM group names. |
|
|
Yes |
|
AWS IAM user name. |
Outputs:
{'version': '1.0', 'success': True, 'reason': None,
'content': [{'GroupName': 'denyall_group', 'Status': 'OK'}],
'raw': '[{"GroupName": "denyall_group", "Status": "OK"}]',
'inputs': {'aws_iam_user_name': 'iam_test_user_1', 'aws_iam_group_names': 'denyall_group'},
'metrics': {'version': '1.0', 'package': 'fn-aws-iam', 'package_version': '1.0.0',
'host': 'myhost.ibm.com', 'execution_time_ms': 4303, 'timestamp': '2020-03-16 15:43:17'
}
}
Example Pre-Process Script:
inputs.aws_iam_user_name = row.UserName
inputs.aws_iam_group_names = rule.properties.aws_iam_group
Example Post-Process Script:
## AWS IAM - fn_aws_iam_add_user_to_groups script ##
# Globals
# List of fields in datatable for fn_aws_iam_add_user_to_groups script
DATA_TBL_FIELDS = ["Groups"]
FN_NAME = "fn_aws_iam_add_user_to_groups"
WF_NAME = "Add User To Group"
# Processing
CONTENT = results.content
INPUTS = results.inputs
QUERY_EXECUTION_DATE = results["metrics"]["timestamp"]
note_text = ''
def main():
note_text = ''
added = 0
no_such_entity = 0
added_groups = []
no_such_entity_groups = []
if CONTENT:
for grp_stat in CONTENT:
if grp_stat["Status"] == "OK":
added += 1
added_groups.append(grp_stat["GroupName"])
else:
no_such_entity += 1
no_such_entity_groups.append(grp_stat["GroupName"])
if added_groups:
note_text = "AWS IAM Integration: Workflow <b>{0}</b>: User <b>{1}</b> added to group <b>{2}</b> " \
"for Resilient function <b>{3}</b>."\
.format(WF_NAME, INPUTS["aws_iam_user_name"], ", ".join(str(i) for i in added_groups), FN_NAME)
note_text += "<br>Refreshing data table <b>{0}</b> row for user <b>{1}</b> with updated group data."\
.format("AWS IAM Users", INPUTS["aws_iam_user_name"])
if no_such_entity:
note_text = "AWS IAM Integration: : Workflow <b>{0}</b>: The group(s) <b>{1}</b> " \
"did not exist for user <b>{2}</b> for Resilient function <b>{3}</b>."\
.format(WF_NAME, ", ".join(str(i) for i in no_such_entity_groups), 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()
Function - AWS IAM: Remove User From Groups¶
Removes the specified IAM user from the specified groups. Group names is a comma-separated string of group names. Parameter aws_iam_user_name is an IAM user name. Parameter aws_iam_group_names is a comma-separated list of IAM group names.
Example workflows that use this Resilient function include Example: AWS IAM: Remove User From All Groups
, Example: AWS IAM: Delete User
or Example: AWS IAM: Delete User For Artifact
.
The workflow, Example: AWS IAM: Remove User From All Groups
, sets the following input fields for the function:
aws_iam_user_name is mapped to a user name from the selected row of data table
AWS IAM Users
.aws_iam_group_names is mapped to all group names from the selected row of data table
AWS IAM Users
.
The workflow is initiated by the data table rule, Example: AWS IAM: Remove User From All Groups
.
Open an incident and select the row of data table
AWS IAM Users
corresponding to the user who needs to be removed from all groups.From the selected row’s actions menu, select
Example: AWS IAM: Remove User From All Groups
.
The user is presented with a warning and an option to Execute or Cancel.
Press Execute to invoke the
Example: AWS IAM: Remove User From All Groups
workflow, which calls theAWS IAM: Remove User From Groups
function.
On successful completion of the workflow, the Groups
field of the AWS IAM Users
data table is updated to an empty value for the selected user.
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
Yes |
|
Comma-separated list of AWS IAM group names. |
|
|
Yes |
|
AWS IAM user name. |
Outputs:
results = {
'version': '1.0', 'success': True, 'reason': None,
'content': [{'PolicyArn': 'arn:aws:iam::aws:policy/AWSDenyAll', 'Status': 'OK'},
{'PolicyArn': 'arn:aws:iam::aws:policy/AWSDenyAll_2', 'Status': 'OK'}],
'raw': '[{"PolicyArn": "arn:aws:iam::aws:policy/AWSDenyAll", "Status": "OK"},' \
'{"PolicyArn": "arn:aws:iam::aws:policy/AWSDenyAll_2", "Status": "OK"}]',
'inputs': {'aws_iam_arns': 'arn:aws:iam::aws:policy/AWSDenyAll', 'aws_iam_user_name': 'iam_test_User_1'},
'metrics': {'version': '1.0', 'package': 'fn-aws-iam', 'package_version': '1.0.0', 'host': 'myhost.ibm.com',
'execution_time_ms': 790, 'timestamp': '2019-11-29 12:18:30'
}
}
Example Pre-Process Script:
inputs.aws_iam_user_name = row.UserName
inputs.aws_iam_group_names = row.Groups
Example Post-Process Script:
## AWS IAM - fn_aws_iam_detach_user_policies script ##
# Globals
# List of fields in datatable for fn_aws_iam_detach_user_policies script
DATA_TBL_FIELDS = ["Policies"]
FN_NAME = "fn_aws_iam_remove_user_from_groups"
WF_NAME = "Remove User From All Groups"
# Processing
CONTENT = results.content
INPUTS = results.inputs
QUERY_EXECUTION_DATE = results["metrics"]["timestamp"]
note_text = ''
def main():
note_text = ''
added = 0
no_such_entity = 0
added_groups = []
no_such_entity_groups = []
if CONTENT:
for pol_stat in CONTENT:
if pol_stat["Status"] == "OK":
added += 1
added_groups.append(pol_stat["GroupName"])
else:
no_such_entity += 1
no_such_entity_groups.append(pol_stat["GroupName"])
if added_groups:
note_text = "AWS IAM Integration: Workflow <b>{0}</b>: The user <b>{1}</b> was removed from the " \
"following groups <b>{2}</b> for Resilient function <b>{3}</b>."\
.format(WF_NAME, INPUTS["aws_iam_user_name"], ", ".join(str(i) for i in added_groups), FN_NAME)
if no_such_entity:
note_text = "AWS IAM Integration: : Workflow <b>{0}</b>: There were <b>{1}</b> Groups <b>{2}</b> " \
"which did not exist for user <b>{3}</b> for Resilient function <b>{4}</b>."\
.format(WF_NAME, len(no_such_entity_groups), ", ".join(str(i) for i in no_such_entity_groups), 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()
Function - AWS IAM: List User Policies¶
Gets all managed policies and in-line policies that are attached to 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: Refresh User
, Example: AWS IAM: Attach User Policy
, Example: AWS IAM: Get User For Artifact
, Example: AWS IAM: Detach All User Policies
, Example: AWS IAM: Delete User
and Example: AWS IAM: Delete User For Artifact
.
The workflow, Example: AWS IAM: Refresh User
, sets the following input fields for the function:
aws_iam_user_name is mapped to a user name from the selected row of data table
AWS IAM Users
.
The workflow is initiated by the data table rule, Example: AWS IAM: Refresh User
.
Open an incident and select the row of data table
AWS IAM Users
corresponding to the user who needs to have a policy attached.From the selected rows action menu, select
Example: AWS IAM: Refresh User
.
This invokes the Example: AWS IAM: Refresh User
workflow, which calls the AWS IAM: List User Policies
function.
On successful completion of the workflow, the Policies
field of the AWS IAM Users
data table is updated for the selected user.
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
Yes |
|
AWS IAM user name. |
Outputs:
results = {
'version': '1.0', 'success': True, 'reason': None,
'content': [{'PolicyName': 'test_pol'},
{'PolicyName': 'test_pol_2',
'PolicyArn': 'arn:aws:iam::123456789123:policy/test_pol_2'},
{'PolicyName': 'AmazonRoute53ReadOnlyAccess',
'PolicyArn': 'arn:aws:iam::aws:policy/AmazonRoute53ReadOnlyAccess'}],
'raw': '[{"PolicyName": "test_pol"}, {"PolicyName": "test_pol_2", "PolicyArn":'\
'"arn:aws:iam::123456789123:policy/test_pol_2"}, {"PolicyName": '\
'"AmazonRoute53ReadOnlyAccess", "PolicyArn": "arn:aws:iam::aws:policy/AmazonRoute53ReadOnlyAccess"}]',
'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': 87423, 'timestamp': '2019-11-21 11:55:29'
}
}
Example Pre-Process Script:
inputs.aws_iam_user_name = row.UserName
Example Post-Process Script:
## AWS IAM - fn_aws_iam_list_user_policies script ##
# Globals
# List of fields in datatable fn_aws_iam_list_user_groups script
DATA_TBL_FIELDS = ["Policies"]
FN_NAME = "fn_aws_iam_list_user_policies"
WF_NAME = "Refresh User"
# Processing
CONTENT = results.content
INPUTS = results.inputs
note_text = ''
def main():
note_text = ''
if CONTENT:
policy_names = []
for pol in CONTENT:
if pol["PolicyName"] is not None:
policy_names.append( pol["PolicyName"])
row.Policies = ",".join(policy_names)
else:
row.Policies = ""
if __name__ == "__main__":
main()
Function - AWS IAM: Attach User policies¶
Attaches the specified managed policies to the specified IAM user. Parameter aws_iam_user_name is an IAM user name. Parameter aws_iam_policy_names (optional) is a comma-separated list of IAM policy names. Parameter (optional) aws_iam_arns is a comma-separated list of IAM policy arns.
Note: One of parameters, aws_iam_policy_names or aws_iam_arns, is required to be set.
Example workflows that use this Resilient function include Example: AWS IAM: Attach User Policy
The workflow, Example: AWS IAM: Attach User Policy
, sets the following input fields for the function:
aws_iam_user_name is mapped to a user name from the selected row of data table
AWS IAM Users
.aws_iam_policy_names is mapped to activity field
aws_iam_policy_name
which should be a drop-down list of policy names.
The workflow is initiated by the data table rule, Example: AWS IAM: Attach User Policy
.
Open an incident and select the row of data table
AWS IAM Users
corresponding to the user who needs to have a policy attached.From the selected row’s actions menu, select
Example: AWS IAM: Attach User Policy
.From the drop-down list of user defined policy names, select a policy and click Execute.
This invokes the Example: AWS IAM: Attach User Policy
workflow, which calls the AWS IAM: Attach User policies
function.
On successful completion of the workflow, the Policies
field of the AWS IAM Users
data table is updated for the selected user.
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
No |
|
Comma-separated list of AWS IAM Amazon Resource Names (ARNs). |
|
|
No |
|
Comma-separated list of AWS IAM policy names. |
|
|
Yes |
|
AWS IAM user name. |
Note: At least One of the parameters aws_iam_arns
or aws_iam_user_name
must be set.
Outputs:
results = {
'version': '1.0', 'success': True, 'reason': None,
'content': [{'PolicyArn': 'arn:aws:iam::aws:policy/AWSDenyAll', 'Status': 'OK'},
{'PolicyArn': 'arn:aws:iam::aws:policy/AWSDenyAll_2', 'Status': 'NoSuchEntity'}],
'raw': '[{"PolicyArn": "arn:aws:iam::aws:policy/AWSDenyAll", "Status": "OK"}, '\
'{"PolicyArn": "arn:aws:iam::aws:policy/AWSDenyAll_2", "Status": "NoSuchEntity"}]',
'inputs': {'aws_iam_arns': 'arn:aws:iam::aws:policy/AWSDenyAll', 'aws_iam_user_name': 'iam_test_User_1'},
'metrics': {'version': '1.0', 'package': 'fn-aws-iam', 'package_version': '1.0.0', 'host': 'myhost.ibm.com',
'execution_time_ms': 790, 'timestamp': '2019-11-29 12:18:30'
}
}
Example Pre-Process Script:
inputs.aws_iam_user_name = row.UserName
inputs.aws_iam_policy_names = rule.properties.aws_iam_policy_name
Example Post-Process Script:
## AWS IAM - fn_aws_iam_attach_user_policies script ##
# Globals
# List of fields in datatable for fn_aws_iam_attach_user_policies script
DATA_TBL_FIELDS = ["Policies"]
FN_NAME = "fn_aws_iam_attach_user_policies"
WF_NAME = "Attach User Policy"
# Processing
CONTENT = results.content
INPUTS = results.inputs
QUERY_EXECUTION_DATE = results["metrics"]["timestamp"]
note_text = ''
def main():
note_text = ''
added = 0
no_such_entity = 0
added_policies = []
no_such_entity_policies = []
if CONTENT:
for pol_stat in CONTENT:
if pol_stat["Status"] == "OK":
added += 1
added_policies.append(pol_stat["PolicyName"])
else:
no_such_entity += 1
no_such_entity_policies.append(pol_stat["PolicyName"])
if added_policies:
note_text = "AWS IAM Integration: Workflow <b>{0}</b>: The Policy <b>{1}</b> was attached to user " \
"<b>{2}</b> for Resilient function <b>{3}</b>."\
.format(WF_NAME, ", ".join(str(i) for i in added_policies), INPUTS["aws_iam_user_name"], FN_NAME)
note_text += "<br>Refreshing data table <b>{0}</b> row for user <b>{1}</b> with updated policy data."\
.format("AWS IAM Users", INPUTS["aws_iam_user_name"])
if no_such_entity:
note_text = "AWS IAM Integration: : Workflow <b>{0}</b>: There were <b>{1}</b> Policies <b>{2}</b> " \
"which did not exist for user <b>{3}</b> for Resilient function <b>{4}</b>."\
.format(WF_NAME, len(no_such_entity_policies), ", ".join(str(i) for i in no_such_entity_policies), 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()
Function - AWS IAM: Detach User policies¶
Removes the specified managed policy from the specified IAM user. Parameter aws_iam_user_name is an IAM user name. Parameter aws_iam_policy_names (optional) is a comma-separated list of IAM policy names. Parameter (optional) aws_iam_arns is a comma-separated list of IAM policy arns.
Note: A user can have embedded inline policies, which the function also deletes. One of the parameters, aws_iam_policy_names or aws_iam_arns, is required to be set.
Example workflows that use this Resilient function include Example: AWS IAM: Detach All User Policies
, Example: AWS IAM: Delete User For Artifact
or Example: AWS IAM: Delete User
.
The workflow, Example: AWS IAM: Detach All User Policies
, sets the following input fields for the function:
aws_iam_user_name is mapped to a user name from the selected row of data table
AWS IAM Users
.aws_iam_policy_names is mapped to all policy names for the user from the selected row of data table
AWS IAM Users
.
The workflow is initiated by the data table rule, Example: AWS IAM: Detach All User Policies
.
Open an incident and select the row of data table
AWS IAM Users
corresponding to the user who needs to have all polices removed or deleted.From the selected row’s actions menu, select
Example: AWS IAM: Detach All User Policies
.
The user is presented with a warning and an option to Execute or Cancel.
Press Execute to invoke the
Example: AWS IAM: Detach All User Policies
workflow, which calls theAWS IAM: Detach User policies
function.
On successful completion of the workflow, the Policies
field of the AWS IAM Users
data table is updated to an empty value for the selected user.
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
No |
|
Comma-separated list of AWS IAM Amazon Resource Names (ARNs). |
|
|
No |
|
Comma-separated list of AWS IAM policy names. |
|
|
Yes |
|
AWS IAM user name. |
Note: At least One of the parameters aws_iam_arns
or aws_iam_user_name
must be set.
Outputs:
results = {
'version': '1.0', 'success': True, 'reason': None,
'content': [{'PolicyName': 'AWSDenyAll', 'Status': 'OK'},
{'PolicyName': 'AWSDenyAll_2', 'Status': 'NoSuchEntity'}],
'raw': '[{"PolicyName": "AWSDenyAll", "Status": "OK"},{"PolicyName": "AWSDenyAll_2", "Status": "NoSuchEntity"}]',
'inputs': {'aws_iam_arns': 'arn:aws:iam::aws:policy/AWSDenyAll', 'aws_iam_user_name': 'iam_test_User_1'},
'metrics': {'version': '1.0', 'package': 'fn-aws-iam', 'package_version': '1.0.0', 'host': 'myhost.ibm.com',
'execution_time_ms': 790, 'timestamp': '2019-11-29 12:18:30'
}
}
Example Pre-Process Script:
inputs.aws_iam_user_name = row.UserName
inputs.aws_iam_policy_names = row.Policies
Example Post-Process Script:
## AWS IAM - fn_aws_iam_detach_user_policies script ##
# Globals
# List of fields in datatable for fn_aws_iam_detach_user_policies script
DATA_TBL_FIELDS = ["Policies"]
FN_NAME = "fn_aws_iam_detach_user_policies"
WF_NAME = "Detach All User Policies"
# Processing
CONTENT = results.content
INPUTS = results.inputs
QUERY_EXECUTION_DATE = results["metrics"]["timestamp"]
note_text = ''
def main():
note_text = ''
added = 0
no_such_entity = 0
detached_policies = []
no_such_entity_policies = []
if CONTENT:
for pol_stat in CONTENT:
if pol_stat["Status"] == "OK":
added += 1
detached_policies.append(pol_stat["PolicyName"])
else:
no_such_entity += 1
no_such_entity_policies.append(pol_stat["PolicyName"])
if detached_policies:
note_text = "AWS IAM Integration: Workflow <b>{0}</b>: The Policies <b>{1}</b> were detached and/or deleted " \
"for user <b>{2}</b> for Resilient function <b>{3}</b>."\
.format(WF_NAME, ", ".join(str(i) for i in detached_policies), INPUTS["aws_iam_user_name"], FN_NAME)
if no_such_entity:
note_text = "AWS IAM Integration: : Workflow <b>{0}</b>: There were <b>{1}</b> Policies <b>{2}</b> " \
"which did not exist for user <b>{3}</b> for Resilient function <b>{4}</b>."\
.format(WF_NAME, len(no_such_entity_policies), ", ".join(str(i) for i in no_such_entity_policies), 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()
Function - AWS IAM: List SSH Public Keys¶
List the SSH public keys associated with an IAM user. Parameter aws_iam_user_name is an IAM user name.
Example workflows that use this Resilient function include Example: AWS IAM: Delete User
or Example: AWS IAM: Delete User For Artifact
.
The workflow, Example: AWS IAM: Delete User
, sets the following input field for the function:
aws_iam_user_name is mapped to a user name from the selected row of data table
AWS IAM Users
.
The workflow is initiated by the data table rule, Example: AWS IAM: Delete User
.
For more information on this workflow, reference section Function - AWS IAM: Delete User
The workflow, Example: AWS IAM: Delete User For Artifact
, sets the following input field for the function:
aws_iam_user_name is mapped to an artifact value for artifact of type
AWS IAM User Name
.
The workflow is initiated by the data table rule, Example: AWS IAM: Delete User For Artifact
.
For more information on this workflow, reference section Function - AWS IAM: Delete User
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
No |
|
AWS IAM user name. |
Outputs:
results = {
'version': '1.0', 'success': True, 'reason': None,
'content': [{'UserName': 'iam_test_user', 'SSHPublicKeyId': 'ABCDEFGH',
'Status': 'Active', 'UploadDate': '2020-02-25 11:05:17'
}
],
'raw': '[{"UserName": "iam_test_user_10", "SSHPublicKeyId": "ABCDEFGH", '\
'"Status": "Active", "UploadDate": "2020-02-25 11:05:17"}]',
'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': 657, 'timestamp': '2020-02-25 16:11:28'
}
}
Example Pre-Process Script:
inputs.aws_iam_user_name = row.UserName
Example Post-Process Script:
## AWS IAM - fn_aws_iam_list_ssh_public_keys script ##
# Globals
# List of fields in datatable fn_aws_iam_list_ssh_public_keys script
DATA_TBL_FIELDS = ["SSHPublicKeyIds"]
FN_NAME = "fn_aws_iam_list_ssh_public_keys"
WF_NAME = "Delete User"
# Processing
CONTENT = results.content
INPUTS = results.inputs
DEBUG_SCRIPT=False
def main():
note_text = ''
if CONTENT:
note_text = "AWS IAM Integration: Workflow <b>{0}</b>: There were <b>{1}</b> 'SSH Public keys' returned for user " \
"<b>{2}</b> for Resilient function <b>{3}</b>."\
.format(WF_NAME, len(CONTENT), INPUTS["aws_iam_user_name"], FN_NAME)
access_key_ids = []
for sshk_id in CONTENT:
if sshk_id["SSHPublicKeyId"] is not None:
workflow.addProperty("has_ssh_public_keys", {})
break
else:
note_text = "AWS IAM Integration: Workflow <b>{0}</b>: There was <b>no</b> 'SSH Public keys' result(s) returned for " \
"user <b>{1}</b> for Resilient function <b>{2}</b>."\
.format(WF_NAME, INPUTS["aws_iam_user_name"], FN_NAME)
if DEBUG_SCRIPT:
incident.addNote(helper.createRichText(note_text))
if __name__ == "__main__":
main()
Function - AWS IAM: Delete SSH Public Keys¶
Delete Secure Shell (SSH) public keys associated with the specified IAM user. Parameter aws_iam_user_name is an IAM user name. Parameter aws_iam_ssh_key_ids is a comma-separated list of SSH public key IDs.
Example workflows that use this Resilient function include Example: AWS IAM: Delete User
or Example: AWS IAM: Delete User For Artifact
.
The workflow, Example: AWS IAM: Delete User
, sets the following input field for the function:
aws_iam_user_name is mapped to a user name from the selected row of data table
AWS IAM Users
.aws_iam_ssh_key_ids is mapped to SSH key IDs retrieved from the previous step (c.f.
AWS IAM: List SSH Public Keys
) in the workflow.
The workflow is initiated by the data table rule, Example: AWS IAM: Delete User
.
For more information on this workflow, reference section Function - AWS IAM: Delete User
The workflow, Example: AWS IAM: Delete User For Artifact
, sets the following input field for the function:
aws_iam_user_name is mapped to an artifact value for artifact of type
AWS IAM User Name
.aws_iam_ssh_key_ids is mapped to SSH key IDs retrieved from the previous step (c.f.
AWS IAM: List SSH Public Keys
) in the workflow.
The workflow is initiated by the data table rule, Example: AWS IAM: Delete User For Artifact
.
For more information on this workflow, reference section Function - AWS IAM: Delete User
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
No |
|
- |
|
|
No |
|
AWS IAM user name. |
Outputs:
results = {
'version': '1.0', 'success': True, 'reason': None,
'content': [{'SSHPublicKeyId': 'ABCDEFGH', 'Status': 'OK'}
{'SSHPublicKeyId': 'ABCDEFGH', 'Status': 'NoSuchEntity'}],
'raw': '[{"SSHPublicKeyId": "ABCDEFGH", "Status": "OK"},'\
'{"SSHPublicKeyId": "ABCDEFGH", "Status": "NoSuchEntity"}]',
'inputs': {'aws_iam_ssh_keys_ids': 'ABCDEFGH', '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': 790, 'timestamp': '2019-11-29 12:18:30'
}
}
Example Pre-Process Script:
inputs.aws_iam_user_name = row.UserName
content = workflow.properties.list_ssh_keys_results.content
ssh_key_ids = []
for ssh_key_id in content:
if ssh_key_id["SSHPublicKeyId"] is not None:
ssh_key_ids.append(ssh_key_id["SSHPublicKeyId"])
inputs.aws_iam_ssh_key_ids = ",".join(ssh_key_ids)
Example Post-Process Script:
## AWS IAM - fn_aws_iam_delete_ssh_keys script ##
# Globals
# List of fields in datatable for fn_aws_iam_delete_ssh_keys script
DATA_TBL_FIELDS = ["Policies"]
FN_NAME = "fn_aws_iam_delete_ssh_keys"
WF_NAME = "Delete User"
# Processing
CONTENT = results.content
INPUTS = results.inputs
QUERY_EXECUTION_DATE = results["metrics"]["timestamp"]
DEBUG_SCRIPT = False
def main():
note_text = ''
deleted = 0
no_such_entity = 0
deleted_keys = []
no_such_entity_keys = []
if CONTENT:
for grp_stat in CONTENT:
if grp_stat["Status"] == "OK":
deleted += 1
deleted_keys.append(grp_stat["GroupName"])
else:
no_such_entity += 1
no_such_entity_keys.append(grp_stat["GroupName"])
if deleted_keys:
note_text = "AWS IAM Integration: Workflow <b>{0}</b>: There were <b>{1}</b> 'SSH Public keys' <b>{2}</b> removed " \
"for user <b>{3}</b> for Resilient function <b>{4}</b>."\
.format(WF_NAME, len(deleted_keys), ", ".join(str(i) for i in deleted_keys), INPUTS["aws_iam_user_name"], FN_NAME)
if no_such_entity:
note_text = "AWS IAM Integration: : Workflow <b>{0}</b>: There were <b>{1}</b> 'SSH Public keys' <b>{2}</b> " \
"which did not exist for user <b>{3}</b> for Resilient function <b>{4}</b>."\
.format(WF_NAME, len(no_such_entity_keys), ", ".join(str(i) for i in no_such_entity_keys), 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)
if DEBUG_SCRIPT:
incident.addNote(helper.createRichText(note_text))
if __name__ == "__main__":
main()
Function - AWS IAM: List Service Specific Credentials¶
List the service-specific credentials associated with an IAM user. Parameter aws_iam_user_name is an IAM user name.
Example workflows that use this Resilient function include Example: AWS IAM: Delete User
or Example: AWS IAM: Delete User For Artifact
.
The workflow, Example: AWS IAM: Delete User
, sets the following input field for the function:
aws_iam_user_name is mapped to a user name from the selected row of data table
AWS IAM Users
.
The workflow is initiated by the data table rule, Example: AWS IAM: Delete User
.
For more information on this workflow, reference section Function - AWS IAM: Delete User
The workflow, Example: AWS IAM: Delete User For Artifact
, sets the following input field for the function:
aws_iam_user_name is mapped to an artifact value for artifact of type
AWS IAM User Name
.
The workflow is initiated by the data table rule, Example: AWS IAM: Delete User For Artifact
.
For more information on this workflow, reference section Function - AWS IAM: Delete User
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
No |
|
AWS IAM user name. |
Outputs:
results = {'version': '1.0', 'success': True, 'reason': None,
'content': [{'UserName': 'iam_test_user', 'Status': 'Active', 'ServiceUserName': 'iam_test_user-at-123456789123',
'CreateDate': '2020-02-25 10:43:24', 'ServiceSpecificCredentialId': 'ABCDEFGH',
'ServiceName': 'codecommit.amazonaws.com'
},
{'UserName': 'iam_test_user', 'Status': 'Active', 'ServiceUserName': 'iam_test_user_10-at-123456789123',
'CreateDate': '2020-02-26 11:50:52', 'ServiceSpecificCredentialId': 'ABCDEFGH',
'ServiceName': 'cassandra.amazonaws.com'}],
'raw': '[{"UserName": "iam_test_user", "Status": "Active", "ServiceUserName": "iam_test_user_10-at-123456789123",'\
'"CreateDate": "2020-02-25 10:43:24", "ServiceSpecificCredentialId": "ABCDEFGH", '\
'"ServiceName": "codecommit.amazonaws.com"},{"UserName": "iam_test_user_10", "Status": "Active", '\
'"ServiceUserName": "iam_test_user_10-at-123456789123", "CreateDate": "2020-02-26 11:50:52", '\
'"ServiceSpecificCredentialId": "ABCDEFGH", "ServiceName": "cassandra.amazonaws.com"}]',
'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': 982, 'timestamp': '2020-02-26 11:56:51'
}
}
Example Pre-Process Script:
inputs.aws_iam_user_name = row.UserName
Example Post-Process Script:
## AWS IAM - fn_aws_iam_list_service_specific_credentials script ##
# Globals
# List of fields in datatable fn_aws_iam_list_service_specific_credentials script
DATA_TBL_FIELDS = ["ServiceSpecificCredentialIds"]
FN_NAME = "fn_aws_iam_list_service_specific_credentials"
WF_NAME = "Delete User"
# Processing
CONTENT = results.content
INPUTS = results.inputs
DEBUG_SCRIPT = False
def main():
note_text = ''
if CONTENT:
note_text = "AWS IAM Integration: Workflow <b>{0}</b>: There were <b>{1}</b> 'Service specific credentials' returned for user " \
"<b>{2}</b> for Resilient function <b>{3}</b>."\
.format(WF_NAME, len(CONTENT), INPUTS["aws_iam_user_name"], FN_NAME)
for ssc_id in CONTENT:
if ssc_id["ServiceSpecificCredentialId"] is not None:
workflow.addProperty("has_srv_creds", {})
break
else:
note_text = "AWS IAM Integration: Workflow <b>{0}</b>: There was <b>no</b> 'Service specific credentials' result(s) returned for " \
"user <b>{1}</b> for Resilient function <b>{2}</b>."\
.format(WF_NAME, INPUTS["aws_iam_user_name"], FN_NAME)
if DEBUG_SCRIPT:
incident.addNote(helper.createRichText(note_text))
if __name__ == "__main__":
main()
Function - AWS IAM: Delete Service Specific Credentials¶
Delete service-specific credentials associated with the specified IAM user. Parameter aws_iam_user_name is an IAM user name. Parameter aws_iam_ssc_ids is a comma-separated list of service-specific credential ids.
Example workflows that use this Resilient function include Example: AWS IAM: Delete User
or Example: AWS IAM: Delete User For Artifact
.
The workflow, Example: AWS IAM: Delete User
, sets the following input field for the function:
aws_iam_user_name is mapped to a user name from the selected row of data table
AWS IAM Users
.aws_iam_ssc_ids is mapped to service specific credential IDs retrieved from the previous step (c.f.
AWS IAM: List Service Specific Credentials
) in the workflow.
The workflow is initiated by the data table rule, Example: AWS IAM: Delete User
.
For more information on this workflow reference section Function - AWS IAM: Delete User
The workflow, Example: AWS IAM: Delete User For Artifact
, sets the following input field for the function:
aws_iam_user_name is mapped to an artifact value for artifact of type
AWS IAM User Name
.aws_iam_ssc_ids is mapped to service specific credential IDs retrieved from the previous step (c.f.
AWS IAM: List Service Specific Credentials
) in the workflow.
The workflow is initiated by the data table rule, Example: AWS IAM: Delete User For Artifact
.
For more information on this workflow reference section Function - AWS IAM: Delete User
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
No |
|
- |
|
|
No |
|
AWS IAM user name. |
Outputs:
results = {
'version': '1.0', 'success': True, 'reason': None,
'content': [{'ServiceSpecificCredentialId': 'ABCDEFGH', 'Status': 'OK'}
{'ServiceSpecificCredentialId': 'ABCDEFGH', 'Status': 'NoSuchEntity'}],
'raw': '[{"ServiceSpecificCredentialId: "ABCDEFGH", "Status": "OK"},'\
'{"ServiceSpecificCredentialId": "ABCDEFGH", "Status": "NoSuchEntity"}]',
'inputs': {'aws_iam_ssc_ids': 'ABCDEFGH', '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': 790, 'timestamp': '2019-11-29 12:18:30'
}
}
Example Pre-Process Script:
inputs.aws_iam_user_name = row.UserName
content = workflow.properties.list_srv_specific_creds_results.content
srv_specific_cred_ids = []
for ssc_id in content:
if ssc_id["ServiceSpecificCredentialId"] is not None:
srv_specific_cred_ids.append(ssc_id["ServiceSpecificCredentialId"])
inputs.aws_iam_ssc_ids = ",".join(srv_specific_cred_ids)
Example Post-Process Script:
## AWS IAM - fn_aws_iam_delete_ss_creds script ##
# Globals
# List of fields in datatable for fn_aws_iam_delete_ss_creds script
DATA_TBL_FIELDS = ["Policies"]
FN_NAME = "fn_aws_iam_delete_ss_creds"
WF_NAME = "Delete User"
# Processing
CONTENT = results.content
INPUTS = results.inputs
QUERY_EXECUTION_DATE = results["metrics"]["timestamp"]
DEBUG_SCRIPT = False
def main():
note_text = ''
deleted = 0
no_such_entity = 0
deleted_creds = []
no_such_entity_creds = []
if CONTENT:
for grp_stat in CONTENT:
if grp_stat["Status"] == "OK":
deleted += 1
deleted_creds.append(grp_stat["GroupName"])
else:
no_such_entity += 1
no_such_entity_creds.append(grp_stat["GroupName"])
if deleted_creds:
note_text = "AWS IAM Integration: Workflow <b>{0}</b>: There were <b>{1}</b> 'Service specific credentials' <b>{2}</b> removed " \
"for user <b>{3}</b> for Resilient function <b>{4}</b>."\
.format(WF_NAME, len(deleted_creds), ", ".join(str(i) for i in deleted_creds), INPUTS["aws_iam_user_name"], FN_NAME)
if no_such_entity:
note_text = "AWS IAM Integration: : Workflow <b>{0}</b>: There were <b>{1}</b> 'Service specific credentials' <b>{2}</b> " \
"which did not exist for user <b>{3}</b> for Resilient function <b>{4}</b>."\
.format(WF_NAME, len(no_such_entity_creds), ", ".join(str(i) for i in no_such_entity_creds), 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)
if DEBUG_SCRIPT:
incident.addNote(helper.createRichText(note_text))
if __name__ == "__main__":
main()
Function - AWS IAM: List Signing Certificates¶
List the signing certificates associated with an IAM user. Parameter aws_iam_user_name is an IAM user name.
Example workflows that use this Resilient function include Example: AWS IAM: Delete User
or Example: AWS IAM: Delete User For Artifact
.
The workflow, Example: AWS IAM: Delete User
, sets the following input field for the function:
aws_iam_user_name is mapped to a user name from the selected row of data table
AWS IAM Users
.
The workflow is initiated by the data table rule, Example: AWS IAM: Delete User
.
For more information on this workflow reference section Function - AWS IAM: Delete User
The workflow, Example: AWS IAM: Delete User For Artifact
, sets the following input field for the function:
aws_iam_user_name is mapped to an artifact value for artifact of type
AWS IAM User Name
.
The workflow is initiated by the data table rule, Example: AWS IAM: Delete User For Artifact
.
For more information on this workflow reference section Function - AWS IAM: Delete User
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
No |
|
AWS IAM user name. |
Outputs:
results = {'version': '1.0', 'success': True, 'reason': None,
'content': [{'UserName': 'iam_test_user', 'CertificateId': 'ABCDEFGH',
'CertificateBody': '-----BEGIN CERTIFICATE-----\nMIID...Apg=\n-----END CERTIFICATE-----',
'Status': 'Active', 'UploadDate': '2020-02-26 12:25:27'}],
'raw': '[{"UserName": "iam_test_user", "CertificateId": "ABCDEFGH", "CertificateBody":'
'"-----BEGIN CERTIFICATE-----\\nMIID...Apg=\\n-----END CERTIFICATE-----", "Status": "Active",'
'"UploadDate": "2020-02-26 12:25:27"}]',
'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': 729, 'timestamp': '2020-02-26 12:33:57'
}
}
Example Pre-Process Script:
inputs.aws_iam_user_name = row.UserName
Example Post-Process Script:
## AWS IAM - fn_aws_iam_list_signing_certificates script ##
# Example result:
"""
Result: {'version': '1.0', 'success': True, 'reason': None,
'content': [{'UserName': 'iam_test_user', 'CertificateId': 'ABCDEFGH',
'CertificateBody': '-----BEGIN CERTIFICATE-----\nMIID...Apg=\n-----END CERTIFICATE-----',
'Status': 'Active', 'UploadDate': '2020-02-26 12:25:27'}],
'raw': '[{"UserName": "iam_test_user", "CertificateId": "ABCDEFGH", "CertificateBody":
"-----BEGIN CERTIFICATE-----\\nMIID...Apg=\\n-----END CERTIFICATE-----", "Status": "Active", "UploadDate": "2020-02-26 12:25:27"}]',
'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': 729, 'timestamp': '2020-02-26 12:33:57'
}
}
"""
# Globals
# List of fields in datatable fn_aws_iam_list_signing_certificates script
DATA_TBL_FIELDS = ["CertificateIds"]
FN_NAME = "fn_aws_iam_list_signing_certificates"
WF_NAME = "Delete User"
# Processing
CONTENT = results.content
INPUTS = results.inputs
DEBUG_SCRIPT=False
def main():
note_text = ''
if CONTENT:
note_text = "AWS IAM Integration: Workflow <b>{0}</b>: There were <b>{1}</b> 'Signing Certificates' returned for user " \
"<b>{2}</b> for Resilient function <b>{3}</b>."\
.format(WF_NAME, len(CONTENT), INPUTS["aws_iam_user_name"], FN_NAME)
for scert_id in CONTENT:
if scert_id["CertificateId"] is not None:
workflow.addProperty("has_sign_certs", {})
break
else:
note_text = "AWS IAM Integration: Workflow <b>{0}</b>: There was <b>no</b> 'Signing Certificates' result(s) returned for " \
"user <b>{1}</b> for Resilient function <b>{2}</b>."\
.format(WF_NAME, INPUTS["aws_iam_user_name"], FN_NAME)
if DEBUG_SCRIPT:
incident.addNote(helper.createRichText(note_text))
if __name__ == "__main__":
main()
Function - AWS IAM: Delete Signing Certificates¶
Delete signing certificates associated with the specified IAM user. Parameter aws_iam_user_name is an IAM user name. Parameter aws_iam_sign_cert_ids is a comma-separated list of signing certificate ids.
Example workflows that use this Resilient function include Example: AWS IAM: Delete User
or Example: AWS IAM: Delete User For Artifact
.
The workflow, Example: AWS IAM: Delete User
, sets the following input field for the function:
aws_iam_user_name is mapped to a user name from the selected row of data table
AWS IAM Users
.aws_iam_sign_cert_ids is mapped to signing certificate IDs retrieved from the previous step (c.f.
AWS IAM: List Signing Certificates
) in the workflow.
The workflow is initiated by the data table rule, Example: AWS IAM: Delete User
.
For more information on this workflow, reference section Function - AWS IAM: Delete User
The workflow, Example: AWS IAM: Delete User For Artifact
, sets the following input field for the function:
aws_iam_user_name is mapped to an artifact value for artifact of type
AWS IAM User Name
.aws_iam_sign_cert_ids is mapped to signing certificate IDs retrieved from the previous step (c.f.
AWS IAM: List Signing Certificates
) in the workflow.
The workflow is initiated by the data table rule, Example: AWS IAM: Delete User For Artifact
.
For more information on this workflow, reference section Function - AWS IAM: Delete User
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
No |
|
- |
|
|
No |
|
AWS IAM user name. |
Outputs:
results = {
'version': '1.0', 'success': True, 'reason': None,
'content': [{'CertificateId': 'ABCDEFGH', 'Status': 'OK'},
{'CertificateId': 'ABCDEFGH', 'Status': 'NoSuchEntity'}],
'raw': '[{'CertificateId': "ABCDEFGH", "Status": "OK"},'
'{'CertificateId': 'ABCDEFGH', 'Status': 'NoSuchEntity'}]',
'inputs': {'aws_iam_sign_cert_ids': 'ABCDEFGH', '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': 790, 'timestamp': '2019-11-29 12:18:30'
}
}
Example Pre-Process Script:
inputs.aws_iam_user_name = row.UserName
content = workflow.properties.list_signing_certs_results.content
sign_cert_ids = []
for scert_id in content:
if scert_id["CertificateId"] is not None:
sign_cert_ids.append(scert_id["CertificateId"])
inputs.aws_iam_sign_cert_ids = ",".join(sign_cert_ids)
Example Post-Process Script:
## AWS IAM - fn_aws_iam_list_signing_certs script ##
# Globals
# List of fields in datatable for fn_aws_iam_list_signing_certs script
DATA_TBL_FIELDS = ["Policies"]
FN_NAME = "fn_aws_iam_list_signing_certs"
WF_NAME = "Delete User"
# Processing
CONTENT = results.content
INPUTS = results.inputs
QUERY_EXECUTION_DATE = results["metrics"]["timestamp"]
DEBUG_SCRIPT = False
def main():
note_text = ''
deleted = 0
no_such_entity = 0
deleted_certs = []
no_such_entity_certs = []
if CONTENT:
for grp_stat in CONTENT:
if grp_stat["Status"] == "OK":
deleted += 1
deleted_certs.append(grp_stat["GroupName"])
else:
no_such_entity += 1
no_such_entity_certs.append(grp_stat["GroupName"])
if deleted_certs:
note_text = "AWS IAM Integration: Workflow <b>{0}</b>: There were <b>{1}</b> 'Signing Certificates' <b>{2}</b> removed " \
"for user <b>{3}</b> for Resilient function <b>{4}</b>."\
.format(WF_NAME, len(deleted_certs), ", ".join(str(i) for i in deleted_certs), INPUTS["aws_iam_user_name"], FN_NAME)
if no_such_entity:
note_text = "AWS IAM Integration: Workflow <b>{0}</b>: There were <b>{1}</b> 'Signing Certificates' <b>{2}</b> " \
"which did not exist for user <b>{3}</b> for Resilient function <b>{4}</b>."\
.format(WF_NAME, len(no_such_entity_certs), ", ".join(str(i) for i in no_such_entity_certs), 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)
if DEBUG_SCRIPT:
incident.addNote(helper.createRichText(note_text))
if __name__ == "__main__":
main()
Function - AWS IAM: List MFA Devices¶
List the MFA devices associated with an IAM user. Also determine which of the associated MFA devices is a virtual device. Parameter aws_iam_user_name is an IAM user name.
Example workflows that use this Resilient function include Example: AWS IAM: Delete User
or Example: AWS IAM: Delete User For Artifact
.
The workflow, Example: AWS IAM: Delete User
, sets the following input field for the function:
aws_iam_user_name is mapped to a user name from the selected row of data table
AWS IAM Users
.
The workflow is initiated by the data table rule, Example: AWS IAM: Delete User
.
For more information on this workflow, reference section Function - AWS IAM: Delete User
The workflow, Example: AWS IAM: Delete User For Artifact
, sets the following input field for the function:
aws_iam_user_name is mapped to an artifact value for artifact of type
AWS IAM User Name
.
The workflow is initiated by the data table rule, Example: AWS IAM: Delete User For Artifact
.
For more information on this workflow, reference section Function - AWS IAM: Delete User
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
No |
|
AWS IAM user name. |
Outputs:
results = {'version': '1.0', 'success': True, 'reason': None,
'content': [{'UserName': 'iam_test_user', 'SerialNumber': 'arn:aws:iam::123456789123:mfa/iam_test_user',
'EnableDate': '2020-02-26 16:55:05', 'is_virtual': True}],
'raw': '[{"UserName": "iam_test_user_10", "SerialNumber": "arn:aws:iam::123456789123:mfa/iam_test_user_10",'
'"EnableDate": "2020-02-26 16:55:05", 'is_virtual': True}]',
'inputs': {'aws_iam_user_name': 'iam_test_user_10'},
'metrics': {'version': '1.0', 'package': 'fn-aws-iam', 'package_version': '1.0.0', 'host': 'myhost.ie.ibm.com',
'execution_time_ms': 5644, 'timestamp': '2020-02-26 17:37:48'
}
}
Example Pre-Process Script:
inputs.aws_iam_user_name = row.UserName
Example Post-Process Script:
## AWS IAM - fn_aws_iam_list_mfa_devices script ##
# Globals
# List of fields in datatable fn_aws_iam_list_mfa_devices script
DATA_TBL_FIELDS = ["SerialNumbers"]
FN_NAME = "fn_aws_iam_list_mfa_devices"
WF_NAME = "Delete User"
# Processing
CONTENT = results.content
INPUTS = results.inputs
DEBUG_SCRIPT=False
def main():
note_text = ''
if CONTENT:
note_text = "AWS IAM Integration: Workflow <b>{0}</b>: There were <b>{1}</b> 'Active NFA devices' returned for user " \
"<b>{2}</b> for Resilient function <b>{3}</b>."\
.format(WF_NAME, len(CONTENT), INPUTS["aws_iam_user_name"], FN_NAME)
for mfa_ser_num in CONTENT:
if mfa_ser_num["SerialNumber"] is not None:
workflow.addProperty("has_active_mfa", {})
if mfa_ser_num.get("is_virtual", None):
workflow.addProperty("is_virtual_mfa", {})
else:
note_text = "AWS IAM Integration: Workflow <b>{0}</b>: There was <b>no</b> 'Active NFA devices' result(s) returned for " \
"user <b>{1}</b> for Resilient function <b>{2}</b>."\
.format(WF_NAME, INPUTS["aws_iam_user_name"], FN_NAME)
if DEBUG_SCRIPT:
incident.addNote(helper.createRichText(note_text))
if __name__ == "__main__":
main()
Function - AWS IAM: Deactivate MFA Devices¶
Deactivate MFA devices and remove it from association with the user name for which it was originally enabled. Parameter aws_iam_user_name is an IAM user name. Parameter aws_iam_mfa_serial_numbers is a comma-separated list of IAM MFA serial numbers or arns.
Example workflows that use this Resilient function include Example: AWS IAM: Delete User
or Example: AWS IAM: Delete User For Artifact
.
The workflow, Example: AWS IAM: Delete User
, sets the following input field for the function:
aws_iam_user_name is mapped to a user name from the selected row of data table
AWS IAM Users
.aws_iam_mfa_serial_numbers is mapped to MFA serial numbers retrieved from the previous step (c.f.
AWS IAM: List MFA Devices
) in the workflow.
The workflow is initiated by the data table rule, Example: AWS IAM: Delete User
.
For more information on this workflow, reference section Function - AWS IAM: Delete User
The workflow, Example: AWS IAM: Delete User For Artifact
, sets the following input field for the function:
aws_iam_user_name is mapped to an artifact value for artifact of type
AWS IAM User Name
.aws_iam_mfa_serial_numbers is mapped to MFA serial numbers retrieved from the previous step (c.f.
AWS IAM: List MFA Devices
) in the workflow.
The workflow is initiated by the data table rule, Example: AWS IAM: Delete User For Artifact
.
For more information on this workflow, reference section Function - AWS IAM: Delete User
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
No |
|
- |
|
|
No |
|
AWS IAM user name. |
Outputs:
results = {
'version': '1.0', 'success': True, 'reason': None,
'content': [{'SerialNumber': 'arn:aws:iam::123456789123:mfa/iam_test_user', 'Status': 'OK'}],
'raw': '[{"SerialNumber": "arn:aws:iam::123456789123:mfa/iam_test_user", "Status": "OK"}]',
'inputs': {'aws_iam_mfa_serial_nums': 'arn:aws:iam::123456789123:mfa/iam_test_user',
'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': 790, 'timestamp': '2019-11-29 12:18:30'
}
}
Example Pre-Process Script:
inputs.aws_iam_user_name = row.UserName
content = workflow.properties.list_mfa_devices_results.content
mfa_serial_nums = []
for mfa_ser_num in content:
if mfa_ser_num["SerialNumber"] is not None:
mfa_serial_nums.append(mfa_ser_num["SerialNumber"])
inputs.aws_iam_mfa_serial_nums = ",".join(mfa_serial_nums)
Example Post-Process Script:
## AWS IAM - fn_aws_iam_deactivate_mfa_devices script ##
# Globals
# List of fields in datatable for fn_aws_iam_deactivate_mfa_devices script
DATA_TBL_FIELDS = ["Policies"]
FN_NAME = "fn_aws_iam_deactivate_mfa_devices"
WF_NAME = "Delete User"
# Processing
CONTENT = results.content
INPUTS = results.inputs
QUERY_EXECUTION_DATE = results["metrics"]["timestamp"]
DEBUG_SCRIPT = False
def main():
note_text = ''
deactivated = 0
no_such_entity = 0
deactivated_mfas = []
no_such_entity_mfas = []
if CONTENT:
for grp_stat in CONTENT:
if grp_stat["Status"] == "OK":
deactivated += 1
deactivated_mfas.append(grp_stat["GroupName"])
else:
no_such_entity += 1
no_such_entity_mfas.append(grp_stat["GroupName"])
if deactivated_mfas:
note_text = "AWS IAM Integration: Workflow <b>{0}</b>: There were <b>{1}</b> 'MFA devices' <b>{2}</b> de-activated " \
"for user <b>{3}</b> for Resilient function <b>{4}</b>."\
.format(WF_NAME, len(deactivated_mfas), ", ".join(str(i) for i in deactivated_mfas), INPUTS["aws_iam_user_name"], FN_NAME)
if no_such_entity:
note_text = "AWS IAM Integration: : Workflow <b>{0}</b>: There were <b>{1}</b> 'MFA devices' <b>{2}</b> " \
"which did not exist for user <b>{3}</b> for Resilient function <b>{4}</b>."\
.format(WF_NAME, len(no_such_entity_mfas), ", ".join(str(i) for i in no_such_entity_mfas), 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)
if DEBUG_SCRIPT:
incident.addNote(helper.createRichText(note_text))
if __name__ == "__main__":
main()
Function - AWS IAM: Delete Virtual MFA Devices¶
Delete a virtual MFA device. Parameter aws_iam_mfa_serial_numbers is a comma-separated list of IAM MFA serial numbers or arns.
Note: You must deactivate a user’s virtual MFA device before you can delete it.
Example workflows that use this Resilient function include Example: AWS IAM: Delete User
or Example: AWS IAM: Delete User For Artifact
.
The workflow, Example: AWS IAM: Delete User
, sets the following input field for the function:
aws_iam_mfa_serial_numbers is mapped to MFA serial numbers retrieved a previous step (c.f.
AWS IAM: List MFA Devices
) in the workflow.
The workflow is initiated by the data table rule, Example: AWS IAM: Delete User
.
For more information on this workflow, reference section Function - AWS IAM: Delete User
The workflow, Example: AWS IAM: Delete User For Artifact
, sets the following input field for the function:
aws_iam_mfa_serial_numbers is mapped to MFA serial numbers retrieved a previous step (c.f.
AWS IAM: List MFA Devices
) in the workflow.
The workflow is initiated by the data table rule, Example: AWS IAM: Delete User For Artifact
.
For more information on this workflow, reference section Function - AWS IAM: Delete User
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
No |
|
- |
Outputs:
results = {
'version': '1.0', 'success': True, 'reason': None,
'content': [{'SerialNumber': 'arn:aws:iam::123456789123:mfa/iam_test_user', 'Status': 'OK'}],
'raw': '[{'SerialNumber': "arn:aws:iam::123456789123:mfa/iam_test_user", "Status": "OK"}]',
'inputs': {'aws_iam_mfa_serial_nums': 'arn:aws:iam::123456789123:mfa/iam_test_user',
'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': 790, 'timestamp': '2019-11-29 12:18:30'
}
}
Example Pre-Process Script:
content = workflow.properties.list_mfa_devices_results.content
mfa_serial_nums = []
for mfa_ser_num in content:
if mfa_ser_num["SerialNumber"] is not None and mfa_ser_num.get("is_virtual", None):
mfa_serial_nums.append(mfa_ser_num["SerialNumber"])
inputs.aws_iam_mfa_serial_nums = ",".join(mfa_serial_nums)
Example Post-Process Script:
## AWS IAM - fn_aws_iam_delete_mfa_devices script ##
# Example result:
# Globals
# List of fields in datatable for fn_aws_iam_delete_mfa_devices script
DATA_TBL_FIELDS = ["Policies"]
FN_NAME = "fn_aws_iam_delete_mfa_devices"
WF_NAME = "Delete User"
# Processing
CONTENT = results.content
INPUTS = results.inputs
QUERY_EXECUTION_DATE = results["metrics"]["timestamp"]
DEBUG_SCRIPT = False
def main():
note_text = ''
deleted = 0
no_such_entity = 0
deleted_mfas = []
no_such_entity_mfas = []
if CONTENT:
for grp_stat in CONTENT:
if grp_stat["Status"] == "OK":
deleted += 1
deleted_mfas.append(grp_stat["GroupName"])
else:
no_such_entity += 1
no_such_entity_mfas.append(grp_stat["GroupName"])
if deleted_mfas:
note_text = "AWS IAM Integration: Workflow <b>{0}</b>: There were <b>{1}</b> 'MFA devices' <b>{2}</b> deleted" \
"for user <b>{3}</b> for Resilient function <b>{4}</b>."\
.format(WF_NAME, len(deleted_mfas), ", ".join(str(i) for i in deleted_mfas), INPUTS["aws_iam_user_name"], FN_NAME)
if no_such_entity:
note_text = "AWS IAM Integration: : Workflow <b>{0}</b>: There were <b>{1}</b> 'MFA devices' <b>{2}</b> " \
"which did not exist for user <b>{3}</b> for Resilient function <b>{4}</b>."\
.format(WF_NAME, len(no_such_entity_mfas), ", ".join(str(i) for i in no_such_entity_mfas), 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)
if DEBUG_SCRIPT:
incident.addNote(helper.createRichText(note_text))
if __name__ == "__main__":
main()
Function - AWS IAM: Update Login Profile¶
Changes the password for the specified IAM user. Parameter aws_iam_user_name is an IAM user name. Parameter aws_iam_password is a new password value for an IAM user. Parameter aws_iam_password_reset_required is a boolean value to determine whether a password reset should be required on change.
Example workflows that use this Resilient function include Example: AWS IAM: Change Profile Password
The workflow, Example: AWS IAM: Change Profile Password
, sets the following input fields for the function:
aws_iam_user_name is mapped to a user name from the selected row of data table
AWS IAM Users
.aws_iam_password is mapped to an activity field input.
aws_iam_password_reset_required is mapped to a boolean from an activity field drop-down list.
The workflow is initiated by the data table rule, Example: AWS IAM: Change Profile Password
.
Open an incident and select the row of data table
AWS IAM Users
corresponding to the user who needs to have a profile password updated.From the selected row’s actions menu, select
Example: AWS IAM: Change Profile Password
.The user is presented with 2 activity fields for a new password a password confirmation and a boolean to indicate if password reset is needed. Set the appropriate values for the fields and click Execute.
Note: The minimum reqirements for a new password is at > 8 characters, at least 1 uppercase and 1 lowercase ascii character.
This invokes the Example: AWS IAM: Change Profile Password
workflow, which calls the AWS IAM: Update Login Profile
function.
On successful completion of the workflow, a note is created indicting the status of the action.
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
Yes |
|
AWS IAM password for user login profile. |
|
|
Yes |
|
A password reset required on password change. |
|
|
Yes |
|
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_1', 'aws_iam_password': '***',
'aws_iam_password_reset_required': False},
'metrics': {'version': '1.0', 'package': 'fn-aws-iam', 'package_version': '1.0.0',
'host': 'myhost.ibm.com',
'execution_time_ms': 4300, 'timestamp': '2020-03-13 17:35:48'
}
}
Example Pre-Process Script:
inputs.aws_iam_user_name = row.UserName
# Test password to see it complies with basic password policy.
err_msg_validation = "The new password needs be minimum 8 characters in length and have at least 1 uppercase and 1 lowercase character."
err_msg_ascii = "The new password must contain only printable ASCII characters."
if len(rule.properties.aws_iam_password) < 8:
raise ValueError(err_msg_validation)
if not any(c.isupper() for c in rule.properties.aws_iam_password):
raise ValueError(err_msg_validation)
if not any(c.islower() for c in rule.properties.aws_iam_password):
raise ValueError(err_msg_validation)
try:
rule.properties.aws_iam_password.decode('ascii')
except:
raise ValueError(err_msg_ascii)
inputs.aws_iam_password = rule.properties.aws_iam_password
inputs.aws_iam_password_reset_required = False
if rule.properties.aws_iam_password_reset_required.lower() == "yes":
inputs.aws_iam_password_reset_required = True
Example Post-Process Script:
## AWS IAM - fn_aws_iam_delete_login_profile script ##
# Globals
# List of fields in datatable fn_aws_iam_update_login_profile script
FN_NAME = "fn_aws_iam_update_login_profile"
WF_NAME = "Change Profile Password"
# Processing
CONTENT = results.content
INPUTS = results.inputs
QUERY_EXECUTION_DATE = results["metrics"]["timestamp"]
note_text = ''
def main():
note_text = ''
if CONTENT:
if CONTENT == "OK":
note_text = "AWS IAM Integration: Workflow <b>{0}</b>: Login profile password was updated for user <b>{1}</b> for " \
"Resilient function <b>{2}</b>.".format(WF_NAME, INPUTS["aws_iam_user_name"], FN_NAME)
elif CONTENT == "PasswordPolicyViolation":
note_text = "AWS IAM Integration: : Workflow <b>{0}</b>: Login profile password got policy violation ERROR updating user <b>{1}</b> for " \
"Resilient function <b>{2}</b>.".format(WF_NAME, INPUTS["aws_iam_user_name"], FN_NAME)
elif CONTENT == "ValidationError":
note_text = "AWS IAM Integration: : Workflow <b>{0}</b>: Login profile password got validation ERROR updating user <b>{1}</b> for " \
"Resilient function <b>{2}</b>.".format(WF_NAME, INPUTS["aws_iam_user_name"], FN_NAME)
else:
note_text = "AWS IAM Integration: : Workflow <b>{0}</b>: Login profile password got unexpected ERROR updating user <b>{1}</b> for " \
"Resilient function <b>{2}</b>.".format(WF_NAME, 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()
Function - AWS IAM: Delete Login Profile¶
Deletes the password for the specified IAM user, which terminates the user’s ability to access AWS services through the AWS Management Console. Parameter aws_iam_user_name is an IAM user name.
Example workflows that use this Resilient function include Example: AWS IAM: Delete Login Profile
, Example: AWS IAM: Delete User
and Example: AWS IAM: Delete User For Artifact
.
The workflow, Example: AWS IAM: Delete Login Profile
, sets the following input field for the function:
aws_iam_user_name is mapped to a user name from the selected row of data table
AWS IAM Users
.
The workflow is initiated by the data table rule, Example: AWS IAM: Delete Login Profile
.
Open an incident and select the row of data table
AWS IAM Users
corresponding to the user whose login profile is to be deleted.From the selected row’s actions menu, select
Example: AWS IAM: Delete Login Profile
.
The user is presented with a warning and an option to Execute or Cancel.
Press Execute to invoke the
Example: AWS IAM: Delete Login Profile
workflow, which calls theAWS IAM: Delete Login Profile
function.
On successful completion of the workflow, the Login Profile exists
field of the AWS IAM Users
data table is updated to “No” for the selected user.
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
Yes |
|
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.ie.ibm.com', 'execution_time_ms': 9170, 'timestamp': '2019-11-18 16:24:17'
}
}
Example Pre-Process Script:
inputs.aws_iam_user_name = row.UserName
Example Post-Process Script:
## AWS IAM - fn_aws_iam_delete_login_profile script ##
# Globals
# List of fields in datatable fn_aws_iam_delete_login_profile script
DATA_TBL_FIELDS = ["Groups"]
FN_NAME = "fn_aws_iam_delete_login_profile"
WF_NAME = "Delete Login Profile"
# Processing
CONTENT = results.content
INPUTS = results.inputs
QUERY_EXECUTION_DATE = results["metrics"]["timestamp"]
note_text = ''
def main():
note_text = ''
if CONTENT:
if CONTENT == "OK":
note_text = "AWS IAM Integration: Workflow <b>{0}</b>: Login profile deleted for user <b>{1}</b> for " \
"Resilient function <b>{2}</b>.".format(WF_NAME, INPUTS["aws_iam_user_name"], FN_NAME)
row.LoginProfileExists = "No"
elif CONTENT == "NoSuchEntity":
note_text = "AWS IAM Integration: : Workflow <b>{0}</b>: Login profile does not exist for user <b>{1}</b> for " \
"Resilient function <b>{2}</b>.".format(WF_NAME, INPUTS["aws_iam_user_name"], FN_NAME)
row.LoginProfileExists = "No"
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()
Data Table - AWS IAM Access Keys¶
API Name:¶
aws_iam_access_keys
Columns:¶
Column Name |
API Access Name |
Type |
Tooltip |
---|---|---|---|
Access key id |
|
|
- |
Create date |
|
|
- |
Default key |
|
|
- |
Last used date |
|
|
- |
Query execution date |
|
|
- |
Region |
|
|
- |
Service name |
|
|
- |
Status |
|
|
- |
User name |
|
|
- |
Data Table - AWS IAM Users¶
API Name:¶
aws_iam_users
Columns:¶
Column Name |
API Access Name |
Type |
Tooltip |
---|---|---|---|
Access key ids |
|
|
- |
Create date |
|
|
- |
Default user |
|
|
- |
Groups |
|
|
- |
Login Profile exists |
|
|
- |
Policies |
|
|
- |
Query execution date |
|
|
- |
Status |
|
|
- |
Tags |
|
|
- |
User Arn |
|
|
- |
User name |
|
|
- |
Custom Artifact Types¶
Display Name |
API Access Name |
Description |
---|---|---|
AWS IAM Access Key ID |
|
Amazon Web Services (AWS) IAM access key id. |
AWS IAM User Name |
|
Amazon Web Services (AWS) IAM user name. |
Rules¶
Rule Name |
Object |
Workflow Triggered |
Condition |
---|---|---|---|
Example: AWS IAM: Add Access Key As Artifact |
aws_iam_access_keys |
|
|
Example: AWS IAM: Add User As Artifact |
aws_iam_users |
|
|
Example: AWS IAM: Add User To Group |
aws_iam_users |
|
|
Example: AWS IAM: Attach User Policy |
aws_iam_users |
|
|
Example: AWS IAM: Change Profile Password |
aws_iam_users |
|
|
Example: AWS IAM: Deactivate Access Key |
aws_iam_access_keys |
|
|
Example: AWS IAM: Delete Access Key |
aws_iam_access_keys |
|
|
Example: AWS IAM: Delete Access Key For Artifact |
artifact |
|
|
Example: AWS IAM: Delete Access Keys |
aws_iam_users |
|
|
Example: AWS IAM: Delete Login Profile |
aws_iam_users |
|
|
Example: AWS IAM: Delete User |
aws_iam_users |
|
|
Example: AWS IAM: Delete User For Artifact |
artifact |
|
|
Example: AWS IAM: Detach All User Policies |
aws_iam_users |
|
|
Example: AWS IAM: Get access Key For Artifact |
artifact |
|
|
Example: AWS IAM: Get Access Keys |
aws_iam_users |
|
|
Example: AWS IAM: Get User |
aws_iam_access_keys |
|
|
Example: AWS IAM: Get User For Artifact |
artifact |
|
|
Example: AWS IAM: List Access Keys |
incident |
|
|
Example: AWS IAM: List Users |
incident |
|
|
Example: AWS IAM: Refresh Access Key |
aws_iam_access_keys |
|
|
Example: AWS IAM: Refresh User |
aws_iam_users |
|
|
Example: AWS IAM: Remove User From All Groups |
aws_iam_users |
|
|
Troubleshooting & Support¶
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¶
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
.
SOAR Logs¶
By default, SOAR logs are retained at
/usr/share/co3/logs
.The
client.log
may contain additional information regarding the execution of functions.
Resilient-Circuits¶
The log is controlled in the
.resilient/app.config
file under the section [resilient] and the propertylogdir
.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.
For Support¶
This is an IBM supported app. Please search ibm.com/mysupport for assistance.