AWS MFA credential helper — exchange long-term credentials for temporary STS tokens
Project description
aws-xfa
Exchange long-term AWS credentials for temporary STS tokens — handles MFA automatically, integrates with 1Password, and can run as a background daemon that keeps credentials fresh without any manual steps.
Install
pip install aws-xfa
First run
If you don't have ~/.aws/credentials yet, just run:
aws-xfa # sets up the "default" profile
aws-xfa main # sets up a profile named "main"
The profile name you pass (or default when omitted) determines all section names in your credentials file. aws-xfa will prompt you for everything:
AWS Access Key ID: AKIA...
AWS Secret Access Key: ************
MFA device ARN (e.g. arn:aws:iam::123456789012:mfa/username): arn:aws:iam::...
AWS region (e.g. us-east-1): us-east-1
Would you like to add sub-profiles? [y/N]:
Use 1Password CLI to automatically fetch MFA codes? [y/N]:
Then it calls AWS STS and writes your temporary credentials to ~/.aws/credentials.
Existing credentials file
If you already have ~/.aws/credentials with a [default] section, aws-xfa will migrate it automatically — creating [default-long-term] for your permanent keys, and using [default] for the temporary STS credentials.
How profile names map to sections:
| Command | Profile | Long-term section | Short-term section |
|---|---|---|---|
aws-xfa |
default |
[default-long-term] |
[default] |
aws-xfa main |
main |
[main-long-term] |
[main] |
Your credentials file structure after setup (using the default profile):
[default-long-term]
aws_access_key_id = AKIA... # your permanent keys — never exposed to AWS CLI
aws_secret_access_key = ...
aws_mfa_device = arn:aws:iam::123456789012:mfa/username
[default]
aws_access_key_id = ASIA... # temporary — written by aws-xfa after each STS call
aws_secret_access_key = ...
aws_session_token = ...
aws_security_token = ...
expiration = 2026-03-04 22:00:00
Daily usage
aws-xfa
# Enter AWS MFA code for device [...]: 123456
# Success! Your credentials will expire in 12h 0m 0s at: 2026-03-05 10:00:00 UTC
Running again while credentials are still valid does nothing:
aws-xfa
# Your credentials are still valid for 11h 55m 34s, they will expire at ...
For a named profile ([main-long-term] → [main]):
aws-xfa main
Force refresh before expiry:
aws-xfa --force
aws-xfa main --force
Sub-profiles
If you use AWS role assumption (e.g. separate prod/stage accounts), aws-xfa can create sub-profiles that reference your parent profile as source_profile.
Sub-profiles are named {profile}-{name} — for example, profile main with sub-profile prod becomes main-prod. Profile default with sub-profile staging becomes default-staging.
During first-run setup, aws-xfa asks if you want to add sub-profiles. You can also add them at any time:
aws-xfa add-subprofile main # add sub-profiles under the "main" profile
aws-xfa add-subprofile default # add sub-profiles under the "default" profile
The interactive prompt:
Sub-profile name (e.g. prod, stage): prod
Role ARN to assume (e.g. arn:aws:iam::123456789012:role/role-name): arn:aws:iam::263649228919:role/role-name
Region [us-west-1]:
Added sub-profile 'main-prod'
Add another sub-profile? [y/N]: n
This writes to ~/.aws/config only (no credentials changes):
[profile main-prod]
source_profile = main
region = us-west-1
role_arn = arn:aws:iam::263649228919:role/role-name
output = json
1Password integration
Skip manual OTP entry entirely. If you answered y during setup, you're already configured. To enable it later:
aws-xfa --1pass
# Enter 1Password item name for profile 'default': AWS MFA
The item name is saved to ~/.config/aws-xfa/config.json. From then on, aws-xfa fetches the OTP automatically on every run — no --1pass flag needed.
aws-xfa # OTP fetched from 1Password silently (default profile)
aws-xfa main # same for named profile
Requires the op CLI to be installed and signed in. If op fails, aws-xfa falls back to prompting you manually.
Auto-refresh daemon
Keep credentials fresh in the background — no manual intervention ever. The daemon wakes 5 minutes before expiry and renews automatically.
Requires 1Password to be configured for the profile first (the daemon runs unattended).
aws-xfa daemon install default # configure 1Password if needed, then install and start
aws-xfa daemon status default # show running status
aws-xfa daemon stop default # stop without removing config
aws-xfa daemon delete default # stop and remove all artifacts and logs
What gets installed per platform:
| Platform | Persistence method |
|---|---|
| macOS | LaunchAgent plist (~/Library/LaunchAgents/com.user.aws-xfa-daemon-PROFILE.plist) |
| Linux | systemd user unit (falls back to double-fork on systems without systemd) |
| Windows | detached process + schtasks on-logon scheduled task |
Error logs: ~/.config/aws-xfa/errors-PROFILE.log
On Linux without systemd (Alpine, OpenRC, WSL), the daemon won't survive reboot automatically. The install command prints the command to add to your init scripts.
Options
| Flag | Description |
|---|---|
--force |
Refresh even if credentials are still valid |
--1pass |
Configure 1Password for this profile (one-time setup) |
--duration SECONDS |
Session duration (default: 43200 = 12 h, min: 900, max: 129600) |
--log-level debug |
Verbose output |
Environment variables:
| Variable | Effect |
|---|---|
MFA_STS_DURATION |
Session duration (same as --duration) |
AWS_REGION / AWS_DEFAULT_REGION |
Region used for the STS endpoint |
AWS_SHARED_CREDENTIALS_FILE |
Override the default ~/.aws/credentials path |
AWS_CONFIG_FILE |
Override the default ~/.aws/config path |
CLI flags take precedence over environment variables.
Before you use this tool
Please read these before deploying aws-xfa in any environment:
- DISCLAIMER.md — no warranty; you are responsible for your AWS credentials and account security
- SECURITY.md — how to report vulnerabilities
- LICENSE — Zero-Clause BSD (0BSD)
- CONTRIBUTING.md — how to contribute
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aws_xfa-1.2.0.tar.gz.
File metadata
- Download URL: aws_xfa-1.2.0.tar.gz
- Upload date:
- Size: 51.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
320118d272a33a937ce9171f10919aea37fce23132eee2dcac0e5c69043a3ed3
|
|
| MD5 |
1bb209b9c62591ed60384d02e5d9c060
|
|
| BLAKE2b-256 |
15e08ce1b046883020000720097fcf91796d467a4b69d750c8ff2c283b67ab13
|
File details
Details for the file aws_xfa-1.2.0-py3-none-any.whl.
File metadata
- Download URL: aws_xfa-1.2.0-py3-none-any.whl
- Upload date:
- Size: 21.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ab87ef52f00d9eea52d83a54bec5c617591b13c7ca320922494f298038c33961
|
|
| MD5 |
936dbb56dbd68045f0b72a570d866d6f
|
|
| BLAKE2b-256 |
50822972de16a3dcbf440b0fd00954c7f8f3162fd66321a766539031ea67e20c
|