Skip to content

Commit 902da46

Browse files
authored
feat: Add MFA support for AWS profiles with multi-factor authentication (#1)
- Implement interactive MFA token provider that prompts for token input - Configure AWS SDK to use MFA token provider for AssumeRole operations - Add stscreds dependency for handling STS assume role with MFA - Document MFA support in README with configuration examples Fixes the error: "assume role with MFA enabled, but AssumeRoleTokenProvider session option not set"
1 parent 521930a commit 902da46

File tree

3 files changed

+48
-2
lines changed

3 files changed

+48
-2
lines changed

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,32 @@ The tool uses the AWS SDK's default credential provider chain, which looks for c
8181
3. IAM roles for EC2 instances
8282
4. IAM roles for tasks (ECS/Fargate)
8383

84+
### MFA Support
85+
86+
The tool supports AWS profiles that require Multi-Factor Authentication (MFA). When using a profile with MFA enabled (configured with `mfa_serial` in `~/.aws/config`), the tool will:
87+
88+
1. Automatically detect that MFA is required
89+
2. Prompt you to enter your MFA token code
90+
3. Use the token to assume the role and generate temporary credentials
91+
92+
Example AWS config with MFA:
93+
94+
```ini
95+
[profile my-mfa-profile]
96+
region = us-east-1
97+
role_arn = arn:aws:iam::123456789012:role/MyRole
98+
source_profile = default
99+
mfa_serial = arn:aws:iam::123456789012:mfa/my-user
100+
```
101+
102+
Usage with MFA:
103+
104+
```bash
105+
export AWS_PROFILE=my-mfa-profile
106+
./elasticache-token -user-id iam-test-user-01 -replication-group-id iam-test-rg-01
107+
Enter MFA token: 123456
108+
```
109+
84110
## License
85111

86112
This project is released under the MIT License.

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ go 1.24.5
55
require (
66
github.com/aws/aws-sdk-go-v2 v1.37.2
77
github.com/aws/aws-sdk-go-v2/config v1.30.3
8+
github.com/aws/aws-sdk-go-v2/credentials v1.18.3
89
)
910

1011
require (
11-
github.com/aws/aws-sdk-go-v2/credentials v1.18.3 // indirect
1212
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.2 // indirect
1313
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.2 // indirect
1414
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.2 // indirect

pkg/awsutils/client.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,34 @@
11
package awsutils
22

33
import (
4+
"bufio"
45
"context"
6+
"fmt"
7+
"os"
8+
"strings"
59

610
"github.com/aws/aws-sdk-go-v2/aws"
711
"github.com/aws/aws-sdk-go-v2/config"
12+
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
813
)
914

15+
func InteractiveMFATokenProvider() (string, error) {
16+
fmt.Fprint(os.Stderr, "Enter MFA token: ")
17+
reader := bufio.NewReader(os.Stdin)
18+
token, err := reader.ReadString('\n')
19+
if err != nil {
20+
return "", fmt.Errorf("failed to read MFA token: %w", err)
21+
}
22+
return strings.TrimSpace(token), nil
23+
}
24+
1025
func LoadAWSConfig(ctx context.Context, region string) (aws.Config, error) {
11-
cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(region))
26+
cfg, err := config.LoadDefaultConfig(ctx,
27+
config.WithRegion(region),
28+
config.WithAssumeRoleCredentialOptions(func(options *stscreds.AssumeRoleOptions) {
29+
options.TokenProvider = InteractiveMFATokenProvider
30+
}),
31+
)
1232
if err != nil {
1333
return aws.Config{}, err
1434
}

0 commit comments

Comments
 (0)