2021-06-04
Find unused AWS IAM users - security, audit, compliance.
One of our clients have grown over years to 250+ users, all created \ deleted \ managed manually.
It became obvious that some automation is required, at least to delete users who left the company for security and compliance.
Quick googling revealed the following tools.
| Tool | Link | GitHub stars | Can find unused users | Least privileges based on usage | Generate terraform | Language | UI |
|---|---|---|---|---|---|---|---|
| AirIAM | https://github.com/bridgecrewio/AirIAM | 327 | Yes | Yes | Yes | Python | CLI tool |
| cloudtracker | https://github.com/duo-labs/cloudtracker | 683 | Yes | Yes | CLI tool | ||
| trailscraper | https://github.com/flosell/trailscraper/ | 379 | No | Yes | Yes | CLI tool | |
| aardvark | https://github.com/Netflix-Skunkworks/aardvark | 386 | No | Python | Web-based. Runs as docker-compose with db. | ||
| repokid | https://github.com/Netflix/repokid | 910 | No | Based on Aardvark above |
We heavily use aws-vault for AWS authentication, so we run AirIAM like this:
$ aws-vault exec ..... -- airiam find_unused --last-used-threshold 90 --no-cache
...
The following 64 users were found to be unused:
...
The following 12 active access keys aren’t being used:
...
The following 6 users have password access they aren’t using:
...
The following 15 roles are unused:
...
The following 8 groups are redundant:
...
The following 7 policies are redundant:
...
The following 30 policy attachments are unused:
...
Now we can go through the list of unused users and delete them one by one.
AirIAM supports automated deletion via an integration with Bridgecrew Cloud, another their offering, but we didn’t use it.
The client uses Jenkins, and so we wrapped the AirIAM run into the following Declarative job definition Jenkinsfile:
pipeline {
options {
skipDefaultCheckout true
}
agent {
docker {
image 'python:3'
alwaysPull true
args '-u root'
}
}
triggers {
cron('H H(9-16) * * 1-5')
}
stages {
stage('airiam') {
steps {
sh 'pip3 install airiam'
sh 'airiam find_unused --last-used-threshold 90 --no-cache'
}
}
}
}
It relies on the following Jenkins plugins:
See more info: https://www.jenkins.io/doc/book/pipeline/docker/
Above Jenkins example relies on AWS authentication to be already in place.
We use Jenkins agents in the same AWS account with Instance profile and Role allowing AirIAM to have access to IAM.
At least the following permissions are required for the Role:
resource "aws_iam_role_policy" "airaim" {
name = "airiam"
role = var.ci_role_id
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iam:GenerateCredentialReport",
"iam:GenerateServiceLastAccessedDetails"
],
"Resource": "*"
}
]
}
EOF
}
As next steps we are considering to implement the following: