IAM Credentials Rotation Automation with Step Functions

IAM Credentials Rotation Automation with Step Functions

Jones Zachariah Noel N's photo
Jones Zachariah Noel N
·Mar 3, 2022·

4 min read

Subscribe to our newsletter and never miss any upcoming articles

Play this article

Table of contents

  • Understanding the workflow
  • Workflow execution
  • Conclusion

The best practices of using IAM credentials is to have them rotated frequently (eg. every 90 days, every 6 months). This is because if IAM credentials are compromised, you can ensure that the existing credentials are deleted, and a new credential is issued. Another best practice includes having the credentials stored securely on Secrets Manager, so that the IAM credentials are never hard-coded on the application end.

In this blog, we will see how Step Functions helps in orchestrating a workflow which implements the rotation of IAM credentials (creating a new programmatic access credentials and deleting existing programmatic access credentials), updates the secret stored on Secrets Manager, and notifies the admin that a new credential is generated and has updated the secret as well.

Alternatively, Secrets Manager natively supports the feature of secrets rotation. However, in that case, based on the CRON expression, a specific Lambda Function is executed. This blog-post is to demonstrate Step Functions' SDK integration capabilities to orchestrate the same flow.

Understanding the workflow

The Step Functions workflows integrates with the services for the respective SDK APIs

  • IAM - iam:listAccessKeys, iam:deleteAccessKey and iam:createAccessKey
  • Secrets Manager - secretsmanager:updateSecret
  • SES - ses:sendEmail

Note : The IAM role created by Step Functions would also require the above mentioned fine grained access to the specific actions of the respective resources.

Step Functions workflow with different states of SDK integration
ListAccessKeys state
State definition for ListAccessKeys

In this state, the IAM SDK API iam:listAccessKeys is used to list the available active IAM credentials of the user specified.

DeleteAccessKey state
State definition for DeleteAccessKey

In this state, the IAM SDK API iam:deleteAccessKey is used to delete the available active credential of the user specified with the access key ID.

CreateAccessKey state
State definition for CreateAccessKey

In this state, the IAM SDK API iam:createAccessKey is used to create a new access key and secret key for the specified user.

UpdateSecret state
State definition for UpdateSecret

In this state, the Secret Manager SDK API secretsmanager:updateSecret is used to update the credential stored on Secret Manager.

SendEmail state
State definition for SendEmail

In this state, the Simple Email Service (SES) SDK API ses:sendEmail is used to notify the users via email that a new IAM credential has been updated on the Secret Manager. Alternatively, ses:sendTemplatedEmail is also used to send a formatted email, but that would require a creation of template prior to this workflow execution. The email body is designed to be a general HTML text to ensure that no other specific IAM credentials is revealed over emails.

The complete JSON of State Machine is -

{
  "Comment": "A description of my state machine",
  "StartAt": "ListAccessKeys",
  "States": {
    "ListAccessKeys": {
      "Type": "Task",
      "Parameters": {
        "UserName.$": "$.userName"
      },
      "Resource": "arn:aws:states:::aws-sdk:iam:listAccessKeys",
      "Next": "DeleteAccessKey",
      "ResultPath": "$.listAccessKey"
    },
    "DeleteAccessKey": {
      "Type": "Task",
      "Next": "CreateAccessKey",
      "Parameters": {
        "AccessKeyId.$": "$.listAccessKey.AccessKeyMetadata[0].AccessKeyId",
        "UserName.$": "$.userName"
      },
      "Resource": "arn:aws:states:::aws-sdk:iam:deleteAccessKey",
      "ResultPath": "$.deleteAccessKey"
    },
    "CreateAccessKey": {
      "Type": "Task",
      "Parameters": {
        "UserName.$": "$.userName"
      },
      "Resource": "arn:aws:states:::aws-sdk:iam:createAccessKey",
      "Next": "UpdateSecret",
      "ResultPath": "$.createAccessKey"
    },
    "UpdateSecret": {
      "Type": "Task",
      "Parameters": {
        "SecretId.$": "$.secretName",
        "SecretString.$": "States.JsonToString($.createAccessKey.AccessKey)"
      },
      "Resource": "arn:aws:states:::aws-sdk:secretsmanager:updateSecret",
      "Next": "SendEmail",
      "ResultPath": "$.updateSecret"
    },
    "SendEmail": {
      "Type": "Task",
      "End": true,
      "Parameters": {
        "Destination": {
          "ToAddresses": [
            "zachjonesnoel@mailinator.com"
          ]
        },
        "Message": {
          "Body": {
            "Html": {
              "Charset": "UTF-8",
              "Data": "The IAM Credential is rotated and updated on Secrets Manager"
            }
          },
          "Subject": {
            "Data": "New IAM Credential updated!!!"
          }
        },
        "Source": "test@zachjonesnoel.com"
      },
      "Resource": "arn:aws:states:::aws-sdk:ses:sendEmail",
      "ResultPath": "$.sendEmail"
    }
  }
}

Workflow execution

When all the states have executed successfully, the end result of the State Machine would mean that your IAM user's programmatic credentials are updated on Secrets Manager.

A successful workflow execution

Also, an email notification is sent to designated users/admins as this is an automation process.

The received email from the successful execution of SendEmail

Now, your applications can always use the secrets from Secrets Manager without the hurdle of updating it every time the IAM credentials are rotated.

For all the security reasons, the complete workflow walkthrough is not provided as that exposes the IAM credentials.

Conclusion

This is an orchestration of IAM credentials rotation which ensures your application is ways using secured credentials that can be updated in time of need. Even though this blog-post features only the Step Function module, this Step Function execution could be started from an event from EventBridge making it an event-triggered automation.

 
Share this