First of all, let's know what the "AWS Chatbot" service is. It is an AWS service that was designed to use messaging apps (only supports Amazon Chime, Microsoft Teams, and Slack currently) to monitor and respond to events in AWS Cloud. If configured correctly (or, misconfigured !!) you can run an AWS command from Slack. Let's try it.
First thing first, go to "AWS Chatbot" in your AWS console. We will assume you have access to configure AWS Chatbot as well as Slack.
Next, click "Configure new client" and choose "Slack" from the dropdown menu.
This will redirect you to connect AWS to Slack. Click on "Allow".
Next, when this is complete, select "Configure new channel"
Fill up the fields. The important piece is the "Channel guardrail policies". This is the control over what actions the slack channel members can take. By default it is "ReadOnlyAccess". (Please note for a step later, the channel name we selected is "#general")
The notification is optional but go ahead set of some SNS topic if you want to send a "Test" message. Next, on the configuration, note two policies:
- Channel role: Straight outta AWS Doc:
(This is the sample trust relationship)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "chatbot.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
- Channel Guardrail policies: Straight outta AWS doc:
for operations in the following JSON policy:
{
"Statement": [
{
"Action": [
"appsync:ListApiKeys",
"chatbot:*",
"codecommit:GetFile",
"codecommit:GetCommit",
"codecommit:GetDifferences",
"cognito-idp:*",
"cognito-identity:*",
"connect:GetFederationToken",
"dynamodb:BatchGetItem",
"dynamodb:GetItem",
"ec2:GetPasswordData",
"ecr:GetAuthorizationToken",
"ecr:GetLogin",
"gamelift:RequestUploadCredentials",
"gamelift:GetInstanceAccess",
"identitystore:*",
"lightsail:DownloadDefaultKeyPair",
"lightsail:GetInstanceAccessDetail",
"lightsail:GetKeyPair",
"lightsail:GetKeyPairs",
"lightsail:UpdateRelationalDatabase",
"iam:*",
"kms:*",
"redshift:GetClusterCredentials",
"sdb:*",
"secretsmanager:*",
"sso:*",
"sso-admin:*",
"sso-oidc:*",
"storagegateway:DescribeChapCredentials",
"sts:*",
"s3:GetObject",
"s3:HeadObject",
"s3:PutObject",
"s3:GetBucketPolicy",
"snowball:GetJobUnlockCode"
],
"Effect": "Deny",
"Resource": "*"
}
],
"Version": "2012-10-17"
}
So, let's go ahead and add user role:
Now, on the slack channel ("#general" channel in this example) you should see a message:
Now, from the Slack side. On the slack channel, add an App:
Browse apps and search "AWS Chatbot" and add it.
And, now the moment of truth, let's run a command below: (Note: You may need to add the @aws app to the slack channel)
@aws aws s3 ls --region us-east-1
And boom! It will even guide you various options.
Now, you may be thinking, how can I block AWS Chatbot in your Organization? Luckily, AWS Organizations now supports something called "Chatbot policy".
Click "Enable Policy" → & then "Create Policy" and create one using sample below:
{
"chatbot": {
"platforms": {
"chime": {
"client": {
"@@assign": "disabled"
}
},
"slack": {
"client": {
"@@assign": "disabled"
}
},
"microsoft_teams": {
"client": {
"@@assign": "disabled"
}
}
},
"default": {
"client": {
"@@assign": "disabled"
}
}
}
}
On the Target, add your desired AWS Account or OU. I prefer adding it to "Root". This policy is generally safe and doesn't have impacts on any other services.
Well, does this actually work? Let's give it a shot.
And, it does work! That's it.
Logging & Detections:
- Cloudwatch logs: It's advised that you enable Cloudwatch logs when you configure the slack channel and select "All events". Sample log:
Sending message to Slack (Workspace: <XXX>, Channel: general) with title:
User <XXX> approved command 'lambda list-functions' with the role '<hidden>' in slack://xxx/xxx at 2024-10-02T13:19:22.868Z.
For Chatbot SCP blocks:
2024-10-02T02:08:33.000Z
Encountered error while sending message to channel: This action is not permitted by your AWS Organizations Chatbot Policy!
- Cloudtrail: Please note that Chatbot is a global service so any service level APIs will be recorded as "eventSource": "chatbot.amazonaws.com" in Cloudtrail. I did observe that the Cloudtrails were recorded in us-east-2 (Ohio). For "assumed" roles, the APIs will be recorded in respective service API made. For example, I perfoemed list-lambda functions API & the sample Cloudtrail is below.
{
"eventVersion": "1.08",
"userIdentity": {
"type": "AssumedRole",
"principalId": "xxx:chatbot-session-slack-xxx",
"arn": "arn:aws:sts::xx:assumed-role/xxx/chatbot-session-slack-xxx",
"accountId": "xxx",
"accessKeyId": "xxx",
"sessionContext": {
"sessionIssuer": {
"type": "Role",
"principalId": "xxx",
"arn": "arn:aws:iam::xxx:role/xxx",
"accountId": "xxx",
"userName": "xxx"
},
"webIdFederationData": {},
"attributes": {
"creationDate": "2024-10-02T13:19:23Z",
"mfaAuthenticated": "false"
}
},
"invokedBy": "chatbot.amazonaws.com"
},
"eventTime": "2024-10-02T13:19:23Z",
"eventSource": "lambda.amazonaws.com",
"eventName": "ListFunctions20150331",
"awsRegion": "us-east-1",
"sourceIPAddress": "chatbot.amazonaws.com",
"userAgent": "chatbot.amazonaws.com",
"requestParameters": {
"maxItems": 5
},
"responseElements": null,
"requestID": "cd7ebc18-efe9-xxx",
"eventID": "b6dd305b-8ee4-xxx",
"readOnly": true,
"eventType": "AwsApiCall",
"managementEvent": true,
"recipientAccountId": "xxxx",
"eventCategory": "Management"
}