DEV Community

Toshimitsu Takahashi
Toshimitsu Takahashi

Posted on

Seamless Local Development with MFA-Enabled Roles on AWS

This article is a translation of https://zenn.dev/tilfin/articles/ab53ae77a8378f.

The Challenge

Many of us have an AWS account for our main login portal and separate AWS accounts for each project. We often need to assume roles to obtain temporary credentials and access resources like S3 and DynamoDB on AWS from our local development environment.

The challenge lies in the short-lived nature of these credentials. In a development environment where the server automatically reloads upon code changes, manually renewing credentials and restarting the server every hour becomes a tedious task. This becomes even more cumbersome with MFA (Multi-Factor Authentication), requiring manual one-time password entry.

This article outlines the steps I took to streamline this process and enable seamless development without interruptions.

Temporary Credential Issuance

While aws sts assume-role is the standard AWS CLI command for this purpose, I've developed a tool called swrole to simplify this process.

https://github.com/tilfin/homebrew-aws/tree/master?tab=readme-ov-file#swrole

swrole 1.1 Release

This latest update introduces multiple ways to handle one-time passwords (OTP). While version 1.0 only supported interactive input, version 1.1 allows you to pass the OTP directly as a command argument using -t 123456. Additionally, you can now define generate_token within the target profile section of your ~/.aws/config file. This enables automatic OTP retrieval from services like 1Password.

~/.aws/credentials

[my-company]
aws_access_key_id = XXXXXXXXXX
aws_secret_access_key = XXXXXXXXXX
Enter fullscreen mode Exit fullscreen mode

~/.aws/config

[profile my-company]
region = ap-northeast-1

[profile project-dev]
role_arn = arn:aws:iam::111111111111:role/developer
mfa_serial = arn:aws:iam::000000000000:mfa/member
source_profile = my-company
region = ap-northeast-1
generate_token = op item get "AWS Account" --otp
Enter fullscreen mode Exit fullscreen mode

In this example, generate_token is configured to fetch the OTP for "AWS Account" using the 1Password CLI.

Leveraging Process Credential Provider in AWS SDKs

During my research, I discovered the credential_process configuration option in ~/.aws/config. This allows AWS SDKs to execute a specified command and utilize the resulting JSON output (from standard output) as credentials.

https://docs.aws.amazon.com/sdkref/latest/guide/feature-process-credentials.html

Recognizing its potential, I've incorporated this functionality into swrole version 1.1. Using the -j option now outputs the credential JSON in the format expected by the Process credential provider.

However, directly using credential_process with the project-dev profile won't work seamlessly due to the SDK's credential prioritization. We need to define a separate profile specifically for application development.

~/.aws/config

[profile app-dev]
credential_process = swrole -j project-dev
Enter fullscreen mode Exit fullscreen mode

~/.aws/credentials

[app-dev]
region = ap-northeast-1
Enter fullscreen mode Exit fullscreen mode

While other SDKs are untested, using ~/.aws/credentials for credential_process works with AWS SDK JavaScript v3.

Now, you can run your development server with this AWS profile, triggering the seamless credential fetching process:

$ AWS_PROFILE=app-dev pnpm dev
Enter fullscreen mode Exit fullscreen mode

Important: Ensure your AWS SDK utilizes proper credential caching to avoid issues with concurrent requests using the same one-time password.

Additional Notes

I encountered some challenges with AWS SDK JavaScript v3's credential caching behavior related to this approach. You can find a detailed explanation in this article:

Optimizing Credential Configuration in AWS SDK for JavaScript v3: Understanding Cache Mechanisms and Best Practices

Furthermore, this method eliminates the need for manual OTP input even with the AWS CLI itself.

Top comments (0)