Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

vac | AWS credentials management leveraging Vault

PkgGoDev Go Report Card test Coverage Status release

vac is a wrapper to manage AWS credentials dynamically using Hashicorp Vault.

It is heavily inspired from jantman/vault-aws-creds and ahmetb/kubectx.

Written in golang, it can work on most common platforms (Linux, MacOS, Windows).

It leverages the external process sourcing capabilities of the AWS CLI config definition.



Have a look onto the latest release page and pick your flavor.

Checksums are signed with the following GPG key: C09C A9F7 1C5C 988E 65E3  E5FC ADEA 38ED C46F 25BE


~$ go install


~$ brew install mvisonneau/tap/vac


~$ docker run -it --rm
~$ docker run -it --rm
~$ docker run -it --rm


~$ scoop bucket add
~$ scoop install vac

Binaries, DEB and RPM packages

Have a look onto the latest release page to pick your flavor and version. Here is an helper to fetch the most recent one:

~$ export VAC_VERSION=$(curl -s "" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
# Binary (eg: linux/amd64)
~$ wget${VAC_VERSION}/vac_${VAC_VERSION}_linux_amd64.tar.gz
~$ tar zxvf vac_${VAC_VERSION}_linux_amd64.tar.gz -C /usr/local/bin

# DEB package (eg: linux/386)
~$ wget${VAC_VERSION}/vac_${VAC_VERSION}_linux_386.deb
~$ dpkg -i vac_${VAC_VERSION}_linux_386.deb

# RPM package (eg: linux/arm64)
~$ wget${VAC_VERSION}/vac_${VAC_VERSION}_linux_arm64.rpm
~$ rpm -ivh vac_${VAC_VERSION}_linux_arm64.rpm


  • Once you have installed it, create a new profile in your ~/.aws/credentials file:
~$ cat - <<EOF >> ~/.aws/credentials

credential_process = $(which vac) get
  • You will need to set the following env variable to use this profile
~$ export AWS_PROFILE=vac

(you can omit this part by using it as your default profile instead)

  • Finally assuming that you have sorted out your Vault accesses already, you need to chose which engine/role to use:
~$ vac
[follow prompt]

Advanced usage

~$ vac --help
   vac - Manage AWS credentials dynamically using Vault

   vac [global options] command [command options] [arguments...]

   get      get the creds in credential_process format (json)
   status   returns some info about the current context, cached credentials and Vault server connectivity
   help, h  Shows a list of commands or help for one command

   --engine path, -e path  engine path [$VAC_ENGINE]
   --role name, -r name    role name [$VAC_ROLE]
   --state path, -s path   state path (default: "~/.vac_state") [$VAC_STATE_PATH]
   --log-level level       log level (debug,info,warn,fatal,panic) (default: "info") [$VAC_LOG_LEVEL]
   --log-format format     log format (json,text) (default: "text") [$VAC_LOG_FORMAT]
   --help, -h              show help

Static configuration

You are forced to use the fuzzyfinding capabilities. This is particularily useful in a non-TTY usage scenario. eg:

# ~/.aws/credentials
credential_process = /usr/local/bin/vac get
credential_process = /usr/local/bin/vac -e dev -r admin get
credential_process = /usr/local/bin/vac -e staging -r admin get

You can also dynamically switch your context without a prompt by doing the following:

# only prompt for chosing a role in the "dev" engine
~$ vac -e dev

# no prompt, automatically switch to "admin" role in the "dev" engine
~$ vac -e dev -r admin

TTL and cache bypass

The get command can take various flags in order to manage the credentials TTLs but also when to refresh them:

~$ vac get --help
   vac get - get the creds in credential_process format (json)

   vac get [command options] [arguments...]

   --min-ttl duration           min-ttl duration (default: 0s) [$VAC_MIN_TTL]
   --ttl duration, -t duration  ttl duration (default: 0s) [$VAC_TTL]
   --force-generate, -f         bypass currently cached creds and generate new ones [$VAC_FORCE_GENERATE]


# Generate credentials valid for 1h
~$ vac get --ttl 1h

# Generate credentials valid for 1h but replace them if existing ones expire in less than 30m
~$ vac get --ttl 1h --min-ttl 30m

# Generate credentials valid for 2h, indepently if some valid ones are still present in the cache
~$ vac get --ttl 2 -f

you can of course define them in your ~/.aws/credentials profiles as well

~$ cat - <<EOF >> ~/.aws/credentials
credential_process = $(which vac) get --ttl 4h
credential_process = $(which vac) get -f

Get information about current configuration

You can use the status command in order to retrieve some info about:

  • Current context (selected engine/role)
  • Cached credentials
  • Vault server connectivity details
~$ vac status
|  LOCAL STATE   |                     |
| Current Engine | dev                 |
| Current Role   | admin               |
| dev       | admin  | in 2 hours    |
| prod      | admin  | 2 days ago    |
| staging   | admin  | 2 days ago    |
|    VAULT    |                                      |
| ClusterID   | 0e6b2fcd-e84b-a7cd-f84d-6b31947a8d73 |
| ClusterName | vault-cluster-90f72c95               |
| Initialized | true                                 |
| Sealed      | false                                |
| Version     | 1.5.3                                |

Required Vault policies

To be able to use all the lookup features, you will need some

# List available AWS engines
path "sys/mounts" {
  capabilities = ["read"]

# List all the roles for each <engine_path>
# path "<engine_path>/roles" {
#  capabilities = ["list"]
# }
# eg:
path "dev/roles" {
 capabilities = ["list"]

path "staging/roles" {
 capabilities = ["list"]

# Assume the role
# path "<engine_path>/sts/<role>" {
#  capabilities = ["update"]
# }
# eg:

path "dev/sts/admin" {
  capabilities = ["update"]

path "staging/sts/admin" {
  capabilities = ["update"]


  • It currently only supports authenticating using STS assumed_role or federation_tokens methods.
  • It will list all available engines and roles according to the defined policies. This result may not be relevant to what an user can actually assume.


Contributions are more than welcome! Feel free to submit a PR.