Start Free Trial

5 AWS security checks you can run right now

Andy Burgess

Andy Burgess writes about AWS security for bearhug, the AWS security platform from Mistral Data.

Last updated 24 September 2026 · 8-minute read

You do not need a security tool to find the most serious AWS problems. These five checks take under 30 minutes in total, need nothing more than the AWS console or the AWS CLI, and cover the issues attackers look for first. Run them in every AWS account you own.

Before you start

You need read access to IAM, S3, EC2 and CloudTrail. The AWS managed SecurityAudit policy covers everything below. If you use the CLI, make sure it is pointing at the right account first:

aws sts get-caller-identity

Replace 111122223333 in the examples with your own account ID.

1. Root account MFA and no root access keys

Why it matters. The root user can do anything in your account, and IAM policies cannot restrict it. If its password or an access key leaks, an attacker has complete control, including over billing and account closure.

Console. Sign in and open IAM. The dashboard’s security recommendations show whether the root user has MFA and whether it has any active access keys.

CLI. Run the command below for a quick view. AccountMFAEnabled should show that MFA is on (1) and AccountAccessKeysPresent that no root keys exist (0). For the definitive answer, check the <root_account> row of the credential report in check 5: mfa_active should be true, and both access_key_1_active and access_key_2_active should be false.

aws iam get-account-summary --query "SummaryMap.[AccountMFAEnabled,AccountAccessKeysPresent]"

Fix. Add MFA to the root user, delete any root access keys, and use IAM roles or IAM Identity Center for day-to-day work.

2. S3 Block Public Access

Why it matters. A single bucket policy or ACL change can make files readable by anyone on the internet. Account-level Block Public Access stops that happening, whatever individual buckets say.

Console. Open Amazon S3 and choose Block Public Access settings for this account. All four settings should normally be on.

CLI. All four values in the output should be true. The command returns the effective account-level setting, which may be inherited from an AWS Organizations policy. An error saying there is no public access block configuration means none has been set.

aws s3control get-public-access-block --account-id 111122223333

Fix. Turn on all four settings, after checking that no application relies on a public bucket. Our S3 bucket security page explains how to serve public content safely through CloudFront.

3. Security groups open to the internet on SSH or RDP

Why it matters. SSH (port 22) and RDP (port 3389) open to 0.0.0.0/0 or ::/0 are found by automated scanners within hours, and are a common route to a compromised instance.

Console. Open EC2, choose Security Groups and review the inbound rules. Look for any rule with a source of 0.0.0.0/0 or ::/0 that covers port 22 or 3389.

CLI. These commands list groups with at least one inbound rule open to the whole internet, over IPv4 and IPv6. Review each group’s rules for any that cover port 22 or 3389, including wide port ranges such as 0–65535 and rules that allow all traffic. Filtering on the port as well is unreliable, because AWS returns groups where the conditions match different rules. Security groups belong to a Region, so run both commands in every Region you use, for example by adding --region eu-west-2.

aws ec2 describe-security-groups --filters Name=ip-permission.cidr,Values=0.0.0.0/0 --query "SecurityGroups[].[GroupId,GroupName]" --output table
aws ec2 describe-security-groups --filters Name=ip-permission.ipv6-cidr,Values=::/0 --query "SecurityGroups[].[GroupId,GroupName]" --output table

Fix. Remove the open rules. Use AWS Systems Manager Session Manager instead of SSH, or restrict access to known IP addresses.

4. CloudTrail enabled in all regions

Why it matters. CloudTrail records who did what in your account. Without a trail covering every region, activity in a region you do not normally use can go unrecorded, and an incident becomes very hard to investigate.

Console. Open CloudTrail and choose Trails. You want at least one trail that is multi-region and has logging turned on.

CLI. List your multi-region trails, check that each one is logging, and confirm that it records management events. Run all three in the Region where the trail was created. The second command should return true, but it only reports status for one Region. To check another Region you rely on, run it there with the trail’s ARN instead of its name, because the copy in that Region is a shadow trail, for example --region eu-west-1 --name arn:aws:cloudtrail:eu-west-2:111122223333:trail/example-trail. In the output of the third command, basic event selectors should show "IncludeManagementEvents": true, "ReadWriteType": "All" and an empty ExcludeManagementEventSources list. If the trail uses advanced event selectors, check every field of the selector for the Management event category: it should have no readOnly filter and no eventSource filters that leave out services you need.

aws cloudtrail describe-trails --query "trailList[?IsMultiRegionTrail].Name"
aws cloudtrail get-trail-status --name example-trail --query IsLogging
aws cloudtrail get-event-selectors --trail-name example-trail

Fix. Create a multi-region trail that logs management events to an S3 bucket, and keep that bucket private and encrypted.

5. IAM access keys older than 90 days

Why it matters. Long-lived access keys end up in laptops, scripts and old repositories. The older a key is, the more places it has been, and the more likely it is to have leaked.

Console. Open IAM and choose Users. The list shows the age of each user’s active access keys.

CLI. Generate the credential report, and run the first command again until it returns "State": "COMPLETE". Then download and decode it, and check the access_key_1_last_rotated and access_key_2_last_rotated columns. A value of N/A means the user has no active key in that slot. AWS generates a new report at most once every four hours.

aws iam generate-credential-report
aws iam get-credential-report --query Content --output text | base64 --decode > credential-report.csv

Fix. Rotate or delete old keys. Better still, replace long-lived keys with IAM roles or IAM Identity Center wherever you can.

What to do with the results

Fix anything that failed, starting with the root account and anything open to the internet. Then put a reminder in the calendar, because each of these can change the next time someone deploys.

Or run all of these and 200+ more automatically with bearhug. It checks your accounts continuously, explains every finding in plain English and fixes common issues in one click. See the most common problems on our AWS misconfiguration scanner page.