Search code examples
amazon-web-servicesamazon-cloudwatchamazon-cloudtrail

AWS configure cloud watch/trail to monitor for 'AccessDenied' and 'UnauthorizedOperation' errors


I'd like to setup some monitoring for capturing access denied and unauthorized operation errors in my AWS account. I'd like to capture all of these events across different AWS services but have run into some issues. I've initially setup some a couple of cloud watch rules that trigger a basic lambda function but I'm not capturing the events I'm looking for. Below are a couple of the rules events that trigger a Lambda function (ideally I'd filter these down from capturing all events once I get this working).

{
  "source": ["aws.cloudtrail"],
  "detail-type": ["AWS API Call via CloudTrail"],
  "detail": {
    "eventSource": ["cloudtrail.amazonaws.com"]
  }
}
// All cloud watch
{
  "source": [
    "aws.cloudwatch"
  ]
 }

I've been testing with the AWS CLI, making calls to resources I don't have access too e.g. :

  • aws dynamodb list-tables
  • aws ec2 describe-instances
  • List item

I'm getting the correct errors in response from the CLI but I'm not seeing these events being propagated to the Lambda (I am seeing other non errors triggering the Lambda though).

Do I have to configure this more narrowly or am I missing a step for collecting these errors?

Thanks for the help


Solution

  • aws dynamodb list-tables, aws ec2 describe-instances and List item do not work because List*, Get* and Describe* API events are not supported by CloudWatch Events:

    enter image description here

    If you want to capture such events, you have to do it through CloudWatch Logs. Namely, setup your CT trail to push events to CloudWatch Logs. Then, setup a subscription filter to your lambda. This will push all API events to your lambda through CloudWatch Logs. Subsequently, you will be able to detect AccessDenied errors in the events and perform other actions you require.

    Other possibility would be to setup metric filter on the logs so that AccessDenied errors are captured to create a CloudWatch metric. Then you setup a CloudWatch Alarm based on the metric. This will trigger an alarm, but it will not pass the details of event that triggered the alarm to your function. You will only know that access denied happened, but without further details.

    Update

    create-table works as expected. I used the following rule in my tests which I hooked up to SQS for quick checks:

    {
      "detail-type": [
        "AWS API Call via CloudTrail"
      ],
      "detail": {
        "eventSource": [
          "dynamodb.amazonaws.com"
        ],
        "errorCode": [
          "AccessDenied"
        ]
      }
    }