
aws-vault vs Granted: A Comparison of Tools for Securely Managing AWS Credentials on macOS
This page has been translated by machine translation. View original
Introduction
When developing with AWS, are you storing your access keys in plain text in ~/.aws/credentials? This poses a high security risk, and if the file is ever leaked, your AWS account could be used fraudulently.
This article compares two tools for securely managing AWS credentials on macOS — aws-vault and Granted — and covers everything from setup procedures to everyday usage and multi-account operation workflows.
Why Plain Text Credentials Are Dangerous
When you run the default aws configure, your access keys are stored in plain text in ~/.aws/credentials.
[default]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
This file is at risk of leaking through the following channels:
- Accidental commits to a dotfiles repository
- File reading by malware
- Leakage from disk backups
- Access by other users on shared devices
Both aws-vault and Granted solve this problem by encrypting and storing credentials in the OS keychain and generating temporary credentials with STS.
Prerequisites and Environment
- macOS (with Keychain Access support)
- Homebrew installed
- AWS CLI installed
- IAM user access keys (with MFA configured)
aws-vault
Overview
aws-vault is a Go-based CLI tool developed by 99designs. It encrypts and stores AWS credentials in the OS keychain, and uses STS GetSessionToken and AssumeRole to generate temporary credentials.
Installation
brew install --cask aws-vault
Initial Setup
1. Storing Credentials
aws-vault add my-profile
You will be prompted to enter your access key ID and secret key. The entered information is encrypted and stored in the macOS Keychain.
Key point: It is not saved to
~/.aws/credentials. You can verify it in Keychain Access.app as the "aws-vault" keychain.
2. Configuring ~/.aws/config
[profile my-profile]
region = ap-northeast-1
[profile my-profile-admin]
source_profile = my-profile
role_arn = arn:aws:iam::123456789012:role/AdminRole
mfa_serial = arn:aws:iam::123456789012:mfa/your.name
region = ap-northeast-1
source_profile: Specify the profile name saved in aws-vaultrole_arn: The ARN of the role to AssumeRole intomfa_serial: The ARN of the MFA device (found in the "Security credentials" tab of the IAM console)
3. Verification
aws-vault exec my-profile-admin -- aws sts get-caller-identity
You will be prompted to enter an MFA token, and upon success you will get output like the following:
{
"UserId": "AROA3XFRBF23EXAMPLE:session-name",
"Account": "123456789012",
"Arn": "arn:aws:sts::123456789012:assumed-role/AdminRole/session-name"
}
How macOS Keychain Integration Works

- Dedicated keychain: Credentials saved with
aws-vault addare stored not in the login keychain, but in a dedicated "aws-vault" keychain - Code signing: macOS release builds are code-signed, preventing repeated password prompts when accessing the Keychain
- Temporary credentials: Temporary credentials are generated via
GetSessionTokenfrom the stored long-term credentials (valid for 1 hour by default). Only temporary credentials are passed to applications - How to verify: Open Keychain Access.app and check the stored information from the "aws-vault" keychain in the sidebar
Commonly Used Commands
| Command | Description |
|---|---|
aws-vault add <profile> |
Save credentials to the Keychain |
aws-vault exec <profile> -- <cmd> |
Execute a single command with temporary credentials |
aws-vault exec <profile> |
Open a subshell with temporary credentials |
aws-vault list |
Display profile list and session expiration |
aws-vault login <profile> |
Log in to the AWS console in a browser |
aws-vault rotate <profile> |
Automatically rotate access keys |
aws-vault remove <profile> |
Delete saved credentials |
aws-vault clear <profile> |
Clear cached sessions |
Common Troubleshooting
"already in subshell" Error
aws-vault: error: exec: running in an existing aws-vault subshell
This occurs when you are already inside an aws-vault subshell. Either exit the subshell with exit and re-run, or check your current session with echo $AWS_VAULT.
exit # Exit the subshell
aws-vault exec my-profile-admin # Run again
exitis not an aws-vault-specific command; it is a shell built-in. Because aws-vault'sexeclaunches a nested shell process, runningexitterminates that shell and returns you to the parent shell.
Session Expiration
# If a command fails due to session expiration
aws-vault clear my-profile-admin # Clear the cache
aws-vault exec my-profile-admin # Obtain a new session (re-enter MFA)
Granted
Overview
Granted is a Go-based CLI tool developed by Common Fate. Like aws-vault, it encrypts and stores credentials in the Keychain, but its greatest feature is that it can switch credentials directly in the current shell without using a subshell.
Installation
brew tap common-fate/granted
brew install granted
After installation, verify the version.
granted -v
On first run, you will be prompted to add an alias to your shell profile. This enables the assume command. After configuration, restart your terminal.
Initial Setup
Since Granted reads ~/.aws/config, the same configuration file used with aws-vault can be used as-is.
1. Secure Storage of IAM Credentials
Granted can also store credentials in the keychain.
granted credentials import
This command migrates plain text credentials from ~/.aws/credentials to the system keychain.
2. Configuring ~/.aws/config
The same configuration used with aws-vault works as-is.
[profile my-profile]
region = ap-northeast-1
[profile my-profile-admin]
source_profile = my-profile
role_arn = arn:aws:iam::123456789012:role/AdminRole
mfa_serial = arn:aws:iam::123456789012:mfa/your.name
region = ap-northeast-1
3. Verification
assume my-profile-admin
Running assume without specifying a profile lets you select a profile using an interactive fuzzy search.
assume
# → Profile list is displayed with fuzzy search
Commonly Used Commands
| Command | Description |
|---|---|
assume |
Interactively select a profile and AssumeRole |
assume <profile> |
AssumeRole with the specified profile (exports environment variables to the current shell) |
assume -c <profile> |
Open the AWS console in a browser (can be logged into multiple accounts simultaneously) |
granted credentials import |
Import from ~/.aws/credentials to the keychain |
granted sso populate |
Automatically generate profiles from SSO configuration |
aws-vault vs Granted Comparison
Basic Comparison
| Item | aws-vault | Granted |
|---|---|---|
| Developer | 99designs | Common Fate |
| Language | Go | Go |
| Credential storage | macOS Keychain | macOS Keychain |
| Temporary credentials | STS GetSessionToken / AssumeRole | STS GetSessionToken / AssumeRole |
| Shell behavior | Spawns a subshell | Exports environment variables to the current shell |
| SSO support | Basic (manual configuration required) | First-class support |
| Profile selection | Enter profile name exactly | Interactive selection with fuzzy search |
Multi-Account Operation Comparison

When handling multiple projects × environments (stg/prod), there is a significant difference in workflow.
aws-vault: One Shell, One Account
aws-vault exec project-a-stg # Subshell 1
# Do work...
exit # Exit the subshell
aws-vault exec project-b-prod # Subshell 2 (re-enter MFA if expired)
# Do work...
exit
aws-vault exec project-a-stg # Go back (re-enter MFA if expired)
Every time you switch accounts, you need exit → exec, and the shell context (current directory, environment variables, command history) is lost.
Granted: Switch Within the Shell
assume project-a-stg # Set environment variables in the current shell
# Do work...
assume project-b-prod # Simply overwrite the environment variables
# Do work...
assume project-a-stg # Go back, no exit needed
Since no subshell is used, you can switch while maintaining the shell context.
Differences in AWS Console Access
# aws-vault: One account per browser session
aws-vault login project-a-stg # Open console in browser
aws-vault login project-b-prod # Logged out of the above session
# Granted: Can open multiple accounts in the browser simultaneously
assume -c project-a-stg # Tab 1: project-a-stg console
assume -c project-b-prod # Tab 2: project-b-prod console (separate container)
assume -c project-c-dev # Tab 3: project-c-dev console
Granted uses the browser's container feature to allow simultaneous login to multiple AWS accounts. This is extremely convenient for multi-account operations.
Differences in Session Renewal
With an IAM + MFA configuration, behavior differs when a session expires.
| Operation | aws-vault | Granted |
|---|---|---|
| Re-authentication flow | exit subshell → run exec again → enter MFA |
Re-run assume → enter MFA |
| Shell context | Lost (new subshell) | Maintained (same shell) |
| SSO re-authentication | Manual | Automatically opens browser with --auto-login |
Note: Entering an MFA token cannot be skipped with either tool. The difference is whether the shell context is maintained during re-authentication.
About awsume
awsume is a Python-based tool that, like Granted, exports environment variables to the current shell. It has excellent features such as automatic refresh via autoawsume and a plugin system, but for the following reasons this article recommends the two options of aws-vault and Granted:
- Credentials are stored in plain text in
~/.aws/credentials(no Keychain integration) - Python dependency (requires runtime installation and version management)
- Slower CLI startup compared to Go binaries
Which Should You Choose?
Cases Where aws-vault Is a Good Fit
- Simple IAM + MFA configuration managing a small number of accounts
- Your team is already using aws-vault (want to avoid switching costs)
- You prefer a single binary with minimal dependencies
Cases Where Granted Is a Good Fit
- Multi-account operations across multiple projects × multiple environments (stg/prod)
- Using AWS SSO / IAM Identity Center (or planning to migrate)
- Development workflows with frequent account switching
- Want to have multiple AWS account consoles open simultaneously
Regarding Migration
Migrating from aws-vault to Granted is relatively straightforward. The ~/.aws/config settings can be shared as-is, and credentials can be migrated with granted credentials import. It is also possible to have both installed at the same time.
Summary
Both aws-vault and Granted are excellent tools that securely store AWS credentials in the Keychain and allow operation with temporary credentials.
- Security is equivalent: Both use Keychain encryption + STS temporary authentication
- Differences emerge in daily workflow: Subshell approach (aws-vault) vs. environment variable export approach (Granted)
- Granted wins for multi-account use: Ease of account switching, fuzzy search, and simultaneous multi-console login are convenient
If you are setting things up from scratch, Granted is recommended, especially in multi-account environments. If you are already using aws-vault with a single account, there is no pressing need to migrate.

