A step function to maintain LDAP users via slack.
This project deploys a collection of lambda functions, an api gateway endpoint, and a step function implemented with the callback pattern that will automate disabling LDAP users via an interactive slack message.
- API Gateway: An API endpoint that responds asynchronously to slack events and triggers the Slack Listener lambda function
- LDAP Query: Lambda function used to perform actions against a target ldap database
- Slack Listener: Lambda function that responds to slack events via an asynchronously executed lambda function
- Slack Notifier: Lambda function that sends status updates to slack and a target step function
- Slack Bot: API Gateway endpoint and Lambda function that responds to slash commands from slack
-
Retrieve the LDAPS endpoint of your target AD deployment.
Note: This can be accomplished via SimpleAD by creating an ALB that listens via TLS on port 636 and forwards requests to your SimpleAD A record. See the associated AWS blog post or the tests of this project for a reference architecture.
-
Within your LDAP directory create a user that will be used by the lambda function. This user will need read permissions to query LDAP, and write permissions to user objects for the properties
userAccountControl
anddescription
.Note: Refer to the following article to scope this permission to a single user: Delegate the Enable/Disable Accounts Permission in Active Directory
-
Populate an encrypted ssm parameter with this new user's password and use the key value as the input for
svc_user_pwd_ssm_key
variable. -
Register a new slack application at https://api.slack.com and capture the "Slack Signing Secret" from the "Basic Information" section of the app's Settings
Note: For each instance of this module, you will almost certainly need a new Slack app. This is because the API Gateway endpoints must be configured within the Slack app's settings, and only a single Interactivity Request URL can be specified per Slack app. Each instance of this module will have a different Interactivity Request URL.
-
Grant Scopes to the app, and capture the OAuth Token:
- Navigate to Features > OAuth & Permissions
- Under Scopes, select
command
- Select "Install app" to your workspace
- Save off the "Bot User OAuth Token" and use it and the "Slack Signing Secret" in the next step
-
Configure your
terraform.tfvars
with the required inputs. -
Run
terraform init/apply
-
Enable Interactivity and a Slash Command your slack integration:
- Go to https://api.slack.com
- Find your app
- Navigate to Features > Interactivity & Shortcuts > Interactivity
- Enter the output value
slack_event_listener_endpoint
from the terraform apply for the Request URL - Navigate to Features > Slash Commands
- Create a new command called
/ldap
- Use the output value
slack_bot_listener_endpoint
for the Request URL
-
Test the integration from slack by calling
/ldap run
or manually by triggering the LDAP maintenance step function with the following payload:{"action": "query" }
- The AD Schema
- Bobbie Couhbor's awesome blogpost on using python-ldap via lambda
- Rigel Di Scala's blog post Write a serverless Slack chat bot using AWS
No requirements.
Name | Version |
---|---|
aws | n/a |
random | n/a |
Name | Type |
---|---|
aws_iam_policy_document.cwe | data source |
aws_iam_policy_document.cwe_trust | data source |
aws_iam_policy_document.sfn | data source |
aws_iam_policy_document.trust | data source |
Name | Description | Type | Default | Required |
---|---|---|---|---|
domain_base_dn | Distinguished name of the domain | string |
n/a | yes |
dynamodb_table_arn | ARN of the dynamodb to take actions against | string |
n/a | yes |
dynamodb_table_name | Name of the dynamodb to take actions against | string |
n/a | yes |
ldaps_url | LDAPS URL of the target domain | string |
n/a | yes |
slack_api_token | API token used by the slack client. Located under the slack application Settings > Install App > Bot User OAuth Access Token | string |
n/a | yes |
slack_channel_id | Channel that the slack notifier will post to | string |
n/a | yes |
slack_signing_secret | The slack application's signing secret. Located under the slack application Settings > Basic Information | string |
n/a | yes |
svc_user_dn | Distinguished name of the LDAP Maintenance service account used to manage simpleAD | string |
n/a | yes |
svc_user_pwd_ssm_key | SSM parameter key that contains the LDAP Maintenance service account password | string |
n/a | yes |
vpc_id | ID of the VPC hosting the target Simple AD instance | string |
n/a | yes |
additional_cleanup_tasks | (Optional) List of step function tasks to execute in parallel once the cleanup action has been approved. | string |
"" |
no |
days_since_pwdlastset | Number of days since the pwdLastSet ldap attribute has been updated. This metric is used to disable the target ldap object. | number |
120 |
no |
enable_dynamodb_cleanup | Controls wether to enable the dynamodb cleanup resources. The lambda function and supporting resources will still be deployed. | bool |
true |
no |
hands_off_accounts | (Optional) List of user names to filter out of the user search results | list(string) |
[] |
no |
log_level | (Optional) Log level of the lambda output, one of: Debug, Info, Warning, Error, or Critical | string |
"Info" |
no |
maintenance_schedule | Periodicity at which to trigger the ldap maintenance step function | string |
"cron(0 8 1 * ? *)" |
no |
manual_approval_timeout | Timeout in seconds for the manual approval step. | number |
3600 |
no |
project_name | Name of the project | string |
"ldap-maintainer" |
no |
tags | Map of tags to assign to this module's resources | map(string) |
{} |
no |
Name | Description |
---|---|
python_ldap_layer_arn | ARN of the python-ldap layer |
slack_bot_listener_endpoint | Endpoint to use for the slack app's Slash Command Request URL |
slack_event_listener_endpoint | Endpoint to use for the slack app's Interactivity Request URL |