Getting a List of "AccessDenied" Events with Users and Source IP Addresses

Tracking "AccessDenied" errors in your AWS account is a useful way to identify security threats and optimize your IAM permissions. In this guide, we'll show you how to get a list of these recent events.

Patrick Londa
Sep 30, 2022
 min read
Share this post

As most security professionals will advise, and the Security Pillar of the AWS Well-Architected Framework recommends, your organization should adhere to the principle of least-privilege permissions. In other words, you should default to providing as little permission as is absolutely necessary.

Any event in your AWS account that attempts to act beyond the limits of authorized permissions will trigger an AccessDenied error.

You can track these types of unauthorized actions, whether they are innocent or intentional, by running a query on your events log in CloudTrail.

In this guide, we’ll explain a bit more about when AccessDenied errors show up and how you can run a query to get a list of these errors during a certain time frame.

Blink Automation: Find "AccessDenied" Events and Send Report to Slack Channel
AWS + Slack
Try This Automation

When do “AccessDenied” events happen?

Identify and Access Management (IAM) roles and policies are the main method for managing permissions for users and resources across your AWS account.

When an activity takes place in your AWS account that attempts to act beyond the designated permissions of their role, it will result in an AccessDenied error. 

For example, If a user doesn’t have permission to AssumeRole in your development account, the user will encounter the below error:

An error occurred (AccessDenied) when calling the AssumeRole operation: 
User: arn:aws:iam:::user is not authorized to perform: sts:AssumeRole on
resource: arn:aws:iam::user:role/role.

This error might also pop up if a trust relationship in your development account hasn't been configured properly.

A third reason includes a failed list bucket operation on the Amazon S3. For this AccessDenied event, the bucket using a command line encounters the following error:

An error occurred (AccessDenied) when calling the ListBuckets operation: 
Access Denied.

This occurs when the user attempts to list the bucket contents on an Amazon S3 bucket using the command line interface. Because explicit access was not provided, the user cannot perform this action.

Whatever the reason, AccessDenied events provide you with an indicator for how well your IAM permissions are working. They might be a sign that the right policies and roles are in place to support a least-privilege approach. On the other hand, they might be a warning of malicious or unauthorized activity that’s worth investigating.

Getting a List of Users and Source IPs for AccessDenied Events

Before you try either method, using the AWS console or CLI, it’s a prerequisite that you have already had CloudTrail enabled and logging to CloudWatch Logs. CloudTrail is enabled by default but if for some reason it is disabled, there won’t be any logs to query for the methods below.

Using the AWS Console

  1. Open your Amazon CloudWatch console and specify a region.
  2. On the left hand menu, select Insights under Logs.
  3. Select your CloudTrail Logs group from the dropdown near the top.
  4. On the right, choose a relative time frame to search.
  5. Enter the following command into the query input, and click Run query:
filter errorCode like /Unauthorized|Denied|Forbidden/ | fields awsRegion,
userIdentity.arn, eventSource, eventName, sourceIPAddress, userAgent

From the output of this query, you’ll be able to review details about each event and determine if action should be taken.

Using the AWS CLI

If you want to filter event logs for a certain time period to only show events with an “AccessDenied” error code, you can use the “filter-log-events” command.

Here’s an example that filters to only show AccessDenied events:

aws logs filter-log-events --region us-east-1 --start-time 1656633601000
--log-group-name CloudTrail/DefaultLogGroup --filter-pattern AccessDenied
--output json --query 'events[*].message'| jq -r '.[] | fromjson | .userIdentity,
.sourceIPAddress, .responseElements'

To input the --start-time parameter, you need to use the UNIX epoch time format. You can use this calculator to convert a date into this format.

You’ll also need to specify a --region (“us-east-1” in the example above), and a --log-group-name (“CloudTrail/DefaultLogGroup”).

Once you run this command, you’ll be able to see all the events with AccessDenied errors. From there, you can review the identity and source IP address to assess the threat level.

You may want to block the user or IP address if the action looks suspect. If the activity should have been allowed, then you may need to adjust roles and permissions accordingly.

Automating Event Log Queries with Blink

If you want to track AccessDenied events for analysis or compliance, going back and running these steps each time requires context-switching and is hard to make routine.

With Blink, you can run this automation to generate and share reports via email or Slack on a regular basis.

Blink Automation: Find AccessDenied Events and Send Report to Slack Channel
Blink Automation: Find AccessDenied Events and Send Report to Slack Channel

When you run this automation from the Blink library, it executes the following steps:

  1. Formats the start time to epoch time.
  2. Get "AccessDenied" events and format the logs.
  3. Send report to a Slack channel.

You can run this automation on a schedule to aggregate these events seamlessly. No context-switching required.

If you have audit or compliance requirements, Blink automations can enable you to consistently gather information and format it in whatever way you need. With Blink, you also have access to over 5K automations from the Blink library to make it easier than ever to turn best practices and common tasks into managed workflows.

Get started with Blink today and see for yourself how easy automation can be.

Automate your security operations everywhere.

Blink is secure, decentralized, and cloud-native. 
Get modern cloud and security operations today.

Get a Demo