2

I'm reviewing IAM policies and roles that haven't been used in the last N number of days.

In the console I can easily view recent usage under Access Advisor.

I'd like to get the same in an automated way, but I can't find any documentation on getting this using CLI or SDK.

Is this possible?

maafk
  • 6,176
  • 5
  • 35
  • 58

4 Answers4

3

Netflix has a tool called Aardvark to scrape the Access Advisor data from the console. You may want to take a look at that.

https://medium.com/netflix-techblog/introducing-aardvark-and-repokid-53b081bf3a7e

robmon
  • 49
  • 5
1

It is now available, check the link below

https://aws.amazon.com/about-aws/whats-new/2018/12/iam_access_advisor_apis/

Canela
  • 160
  • 1
  • 1
  • 11
0

As far as I'm aware of, no. You might get lucky finding a way around using Selenium to automate the process, but that's a lengthy workaround.

No such luck using CloudTrail either. The closest thing I could find was when policies are last updated.

Hopefully, Amazon will take this into consideration. I've contacted them about this.

Mangohero1
  • 1,832
  • 2
  • 12
  • 20
0

This is possible using AWS SDKs.

Versions:

  • aws-cli/2.0.61

  • go1.15.3 linux/amd64


Let's do this in Golang with the right imports.

 import (
     "fmt"
     "github.com/aws/aws-sdk-go/aws"
     "context"
     "github.com/aws/aws-sdk-go-v2/config"
     "github.com/aws/aws-sdk-go-v2/service/iam"
)

First, you want to init a session and a client:

cfg, err := config.LoadDefaultConfig() 
svc := iam.NewFromConfig(cfg)

Then you want to get a list of roles, to iterate through all role names. You can also use a specific role name because that's the only thing you will need to get the LastUsedDate:

roles_iam, err := svc.ListRoles(context.Background(), &iam.ListRolesInput{
PathPrefix: aws.String("/")})
if err != nil {
    fmt.Println("Error", err)
    return  
}

/** For simplicity and less dereferencing: more execution speed **/
roles_list := roles_iam.Roles    

Finally, iterate through a loop if you need to get LastUsedDate for all roles. Just set input with the right GetRoleInput arguments then call svc.GetRole to get a structure with your info.

/** Declare slice 'unused_roles' containing string unused role names **/
var unused_roles []string 

for i := range roles_list {
    role_name := *roles_list[i].RoleName
    input := &iam.GetRoleInput{
        RoleName: aws.String(*roles_list[i].RoleName),
    }
    role_info, err := svc.GetRole(context.Background(), input)
    if err != nil {
        fmt.Println("Error", err)
    }    
      
/** Check if role has never been used **/           
    if (role_info.Role.RoleLastUsed.LastUsedDate) == nil {
        fmt.Printf("Role %s has never been used\n", role_name)
        unused_roles = append(unused_roles, role_name)
        continue
    }
    last_used_date := *role_info.Role.RoleLastUsed.LastUsedDate
}

More info:

https://docs.aws.amazon.com/IAM/latest/APIReference/API_Role.html

https://docs.aws.amazon.com/IAM/latest/APIReference/API_RoleLastUsed.html

aboitier
  • 180
  • 11