Two small scripts for managing AWS MFA authentication from the command line.
setup-aws-mfa— registers your long-lived AWS credentials and MFA device into~/.aws/profile-meta.jsonrefresh-aws-mfa— uses your MFA code to get a temporary session token and writes it to~/.aws/credentials
Temporary credentials are valid for 12 hours (AWS STS default). Run refresh-aws-mfa again when they expire.
- Python 3
- AWS CLI
curl -fsSL https://raw.githubusercontent.com/deepgram/aws-mfa-tools/main/install.sh | bashThis downloads setup-aws-mfa and refresh-aws-mfa into ~/.local/bin and makes them executable. If ~/.local/bin is not in your PATH, the installer will tell you what to add to your shell config.
Before using these scripts you need a virtual MFA device enrolled on your AWS account. If you have already done this, skip to Setup.
- Log into the AWS Console
- Click your username in the top-right corner → Security credentials
- Scroll to Multi-factor authentication (MFA) → click Assign MFA device
- Give the device a name (e.g. your username), choose Authenticator app, click Next
- Open your authenticator app (Google Authenticator, Authy, 1Password, etc.) and scan the QR code
- Enter two consecutive 6-digit codes from the app to confirm, click Add MFA
The device name you choose in step 4 is what you will enter when prompted by setup-aws-mfa.
Run once per AWS account/profile:
setup-aws-mfaYou will be prompted for:
| Field | Description |
|---|---|
| AWS Account ID | 12-digit account ID (e.g. 123456789012) |
| Access Key ID | Long-lived IAM access key (AKIA...) |
| Secret Access Key | Corresponding secret |
| MFA Device name | Your MFA device name — just the suffix, e.g. john-doe (the script prepends mfa/ automatically) |
| Profile name | default, or a named profile (e.g. internal) |
Credentials are stored in ~/.aws/profile-meta.json with 600 permissions. The MFA device ARN is constructed as:
arn:aws:iam::<account-id>:mfa/<device-name>
To register multiple accounts, run setup-aws-mfa again and choose a different profile name each time.
refresh-aws-mfa # refresh the default profile
refresh-aws-mfa --profile internal # refresh a named profileYou will be prompted for your current 6-digit MFA code. On success, ~/.aws/credentials is updated with temporary aws_access_key_id, aws_secret_access_key, and aws_session_token for the chosen profile. A backup of the previous credentials file is saved as ~/.aws/credentials.bak.
Default profile — works automatically:
aws s3 lsNamed profile — pass --profile or export:
aws --profile internal s3 ls
# or
export AWS_PROFILE=internal
aws s3 lssetup-aws-mfa writes a metadata file at ~/.aws/profile-meta.json:
{
"profiles": {
"internal": {
"account": "409749468643",
"mfa-device": "mfa/john-doe",
"access-key-id": "AKIA...",
"secret-access-key": "..."
}
}
}refresh-aws-mfa reads this file, calls sts:GetSessionToken with your MFA code using the long-lived credentials directly (bypassing any existing session token in the environment), and writes the resulting temporary credentials into ~/.aws/credentials.
The AWS CLI is used directly; no additional Python packages are required.
~/.aws/profile-meta.json not found
Run setup-aws-mfa first.
Profile 'X' not found
Run setup-aws-mfa again and use the same profile name, or check available profiles in ~/.aws/profile-meta.json.
AccessDenied when calling S3 or other services
Your session has likely expired. Run refresh-aws-mfa to get new credentials.
InvalidClientTokenId or AuthFailure
Your long-lived access key may be incorrect or deactivated. Re-run setup-aws-mfa with updated credentials.