Can you run an AWS command from Slack, without any AWS credentials? Let’s find out!

AJ - Oct 3 - - Dev Community

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.

AWS Chatbot

Next, click "Configure new client" and choose "Slack" from the dropdown menu.

Configure new client

This will redirect you to connect AWS to Slack. Click on "Allow".

AWS ChatBot to slack

Next, when this is complete, select "Configure new channel"

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")

Image description

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:

Image description

(This is the sample trust relationship)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "chatbot.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode
  • Channel Guardrail policies: Straight outta AWS doc:

Image description

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"
}
Enter fullscreen mode Exit fullscreen mode

So, let's go ahead and add user role:

Image description

Image description

Image description

Now, on the slack channel ("#general" channel in this example) you should see a message:

Image description

Now, from the Slack side. On the slack channel, add an App:

Image description

Browse apps and search "AWS Chatbot" and add it.

Image description

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.

Image description

Now, you may be thinking, how can I block AWS Chatbot in your Organization? Luckily, AWS Organizations now supports something called "Chatbot policy".

Image description

Click "Enable Policy" → & then "Create Policy" and create one using sample below:

Image description

{
  "chatbot": {
    "platforms": {
      "chime": {
        "client": {
          "@@assign": "disabled"
        }
      },
      "slack": {
        "client": {
          "@@assign": "disabled"
        }
      },
      "microsoft_teams": {
        "client": {
          "@@assign": "disabled"
        }
      }
    },
    "default": {
      "client": {
        "@@assign": "disabled"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

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.

Image description

Well, does this actually work? Let's give it a shot.

Image description

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!
Enter fullscreen mode Exit fullscreen mode
  • 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.

Image description

{
    "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"
}
Enter fullscreen mode Exit fullscreen mode
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .