• Riccardo, this is exactly what I was looking for! I don't have python skills (maybe in the near future), but how would I modify this for filtering by tags for users? My users aren't created with valid email addresses so changing the client's process is not likely.

  • Hi @joeyancheta, I'm glad you find this useful :-)

    You probably want to change the line filtered_users = list(filter(lambda u: u.get('PasswordLastUsed'), users))

    If you have a complex policy to check, let's create a dedicated function we invoke (I haven't tested this):

    def is_user_interesting(user):
        tags = user.get('Tags')
        for tag in tags:
            if tag['Key'] == 'Foo' and tag['Value'] == "Buzz":
                return True # We found the tag we are interested in!
        return False # If we are here, it means no tag matched, or there isn't any tag associated to the user

    Then, we provide this new function to the filter invocation:

    filtered_users = list(filter(is_user_interesting, users))
  • Thanks for the reply @rpadovani

    Unfortunately, I am still getting an error when using your new function.

    I am getting closer though. I worked with a friend and we were able to build this new function. We are getting the tags, but aren't able to get the send notifications to go out.

        for keys_for_user in interesting_keys_grouped_by_user.values():
          user_name = keys_for_user[0]['UserName']
          user_details = iam_client.get_user(UserName=user_name)
          email = None
          for tag in user_details.get('Tags', []):
            if tag['Key'] == 'Email':
              email = tag['Value']
          if email is None:
                # error, the user has no email tag
          send_notification(email, keys_for_user, context.invoked_function_arn.split(":")[4])
    Edited by joeyancheta
  • @rpadovani I just wanted to give you an update on my project. we actually need to use user_details = iam_client.list_user_tags(UserName=user_name) to get the tags.

    this is the final snippet that was added to your script.

        for keys_for_user in interesting_keys_grouped_by_user.values():
          user_name = keys_for_user[0]['UserName']
          user_details = iam_client.list_user_tags(UserName=user_name)
          email = None
          for tag in user_details.get('Tags', []):
            if tag['Key'] == 'CheckAccessKeyAge':
              email = tag['Value']
          if email is None:
                # error, the user has no email tag
          send_notification(email, keys_for_user, context.invoked_function_arn.split(":")[4])
    Edited by joeyancheta
  • Thanks for the update @joeyancheta, I am happy you were able to make it working for your use case :-)

  • Hi @rpadovani,

    I got an error when trying to run the script in my Lambda environment. Could you please tell me if it makes sense?

    Function logs:
    START RequestId: 1b0e3a07-06e9-40e9-9612-6557829f41a4 Version: $LATEST
    [ERROR]	2021-01-19T20:57:54.492Z	1b0e3a07-06e9-40e9-9612-6557829f41a4	Missing final '@domain'
    [ERROR]	2021-01-19T20:57:54.578Z	1b0e3a07-06e9-40e9-9612-6557829f41a4	Missing final '@domain'
    [ERROR]	2021-01-19T20:57:54.593Z	1b0e3a07-06e9-40e9-9612-6557829f41a4	Missing final '@domain'

    Systems setup (based off your blog post): IAM SES

  • Hi @scott178, the error seems to indicate that usernames of your users aren't actual email - thus the Missing final '@domain'. You can save your users' email in a tag, or if the domain is always the same, you can change line 59 from Destination={'ToAddresses': [email]},, to Destination={'ToAddresses': [email + "@example.com"]},.

    Let me know if this helps!

  • Hi @rpadovani,

    This is a really nice code. but, It doesn't work on my system.


    My Access key age is 2 days. Lambda function permission is Adminfullaccess. Is there anything I miss? The function runs well code 200.

    Thanks you bro!!

  • Hi @dlfp125, I'm glad you like the code. However, I haven't understood what's the problem you're facing. Does the script send the alert before the due date?

  • Oh,@rpadovan,

    Thank you for your answer. The cloudwatch event alarm runs lambda function every five minutes. There is no error and it works normally, but the email and key are not updated.

    Edited by loanshark
  • Hi @dlfp125 I am not sure if I've understood what you are trying to achieve: this script doesn't update any email nor any key: it just sends an email notification when your access key is older than N days.

    It is useful to remember people to rotate keys, when they are too old (the keys, not the people).

  • ah..! thanks you @rpadovan,

    I wasn't getting it right.

  • @rpadovani Can we get an enhanced code to automate key rotation..example create,disable and delete old key for all the user as in one script

    Edited by Sameer Goyal
  • Hi @Sameergoyal03, I am not sure if I understood what kind of script you are looking for. A good starting point would be https://aws.amazon.com/blogs/security/how-to-rotate-access-keys-for-iam-users/

  • Hi Riccardo,

    This is really cool, thanks for taking time to come up with this solution.

    Pls, I am getting this error when I run the function;

    { "errorMessage": "send_notification() missing 1 required positional argument: 'account_id'", "errorType": "TypeError", "stackTrace": [ " File "/var/runtime/bootstrap.py", line 127, in handle_event_request\n response = request_handler(event, lambda_context)\n" ] }

    Let me know what's I am doing wrong.


  • Hi @dozieaji1, have you changed the code? It seems that here: send_notification(user[0]['UserName'], user, context.invoked_function_arn.split(":")[4]) you are not passing the account id...

  • Hi @rpadovani,

    I have read the full code I want to know if I want to fetch the email id from tags what would be the name of tag we need to add in IAM user and what changes we need in the code and where.

    TBH, I don't have much knowledge of Coding.

    I was trying to run this code but cannot do that. getting error "Missing final '@domaiN'"

    Can you please help this is a bit urgent!!!!


    Edited by Abhishek Madan
  • Hello @iamabhishek2706, the tag name is up to you, I don't know how you manage your IAM users.

    Tags are then inside the Tags key in the user object, so instead of user[0]['UserName'] you can do something like user[0]['Tags'].get('YourTagKey')

  • Hi @rpadovani,

    Thanks for your update.

    I totally understand what you said but I want to send notification to those emails which is in tags how to fetch the email from tags and send email to them. This is because in my environment the username is not the email I created a custom Tag "Email : test@test.com". How to send notifications to the email which is in the tags. I just wanted to set the destination email is fetched from tags.

    But I need some more help from you can you please provide the full instructions to setup this code I am not be able to setup the above code can you please instruct me with the full steps its will be a great and big help for me.

    Steps what I did: Created the IAM role. Attached that role to lambda function.

    During above steps while setting up SES I am not be able to set that can you please guide me to setup SES for the above lambda function.

    Its will be a great help for me, Thanks please respond ASAP. It's little bit urgent!

    Edited by Abhishek Madan
  • Hi @iamabhishek2706,

    If you already have the tag in your IAM users, then it should as easy as replacing send_notification(user[0]['UserName'], user, context.invoked_function_arn.split(":")[4]) with send_notification(user[0]['Tags'].get('Email'), user, context.invoked_function_arn.split(":")[4]).

  • Hi @rpadovani,

    Thanks for the update,


    I have attached the code which I have customized according to your instructions when I am running this there is no error but emails are not sending can you please have a look and review it.

    Your help is really appreciable, Thanks.

  • Hello @iamabhishek2706, I've taken a quick look at the script, and there isn't anything that makes me think it should fail.

    There are different possible issues:

    • There isn't any key that is older than one day
    • Your email is not authorized to send SES emails
    • The tag with the emails isn't actually called Email
    • Some IAM permissions, perhaps?

    You need somebody with proper access to the account to debug it.

Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment