HashiCorp Vault AWS Secrets Engine

Marco Urrea
4 min readMar 6, 2020

HashiCorp Vault AWS Secrets Engine

This is a hands-on tutorial on how to enable Amazon’s AWS Secrets engine in HashiCorp Vault.

Requirements:

  • Download and install HashiCorp Vault.
  • An AWS account

AWS: Setting Up your IAM credentials

  1. Sign in to the AWS Console.
  2. On the top-right corner click on your username@domain, followed and then on My Security Credentials.

3. On the AWS IAM Credentials tab, in the Access keys for CLI, SDK, and API access section, click Create access key, which will trigger a pop-up.

4. At the bottom of the pop-up look for the Access key ID, and Secrets access key (click Show secret access key to unveil its value). Store those two values because we will use them in the next section and click Close.

For security purposes, I replaced my Access key ID with some template text.

As an alternative, you can download those values as a .csv file.

HashiCorp Vault: AWS Secrets Engine

  1. Start your Vault Server and assign the correct API address.
  2. Once started the vault server, in another terminal, enable the AWS secrets engine with the following command:
vault secrets enable -path=aws aws

Output:

Success! Enabled the aws secrets engine at: aws/

If you sign in to your Vault UI, usually located at http://127.0.0.1:8200, you should notice in the first row the AWS secrets engine is enabled.

Notice the AWS Secrets engine is now enabled.

3. In the last section, we created our AIM Access Key and Secret, which we will use in this step.

vault write aws/config/root \
access_key=<Your AWS Access key ID> \
secret_key=<Your AWS Secret access key> \
region=us-east-1

Output:

Success! Data written to: aws/config/root

AWS Full ARN Policy Creation

1. Creating a role policy, named my-role, which will be used to generate user credentials against this role. The purpose of this role is that Vault creates an access key and secret key for the IAM user and returns its values. This inline policy references to AWS full ARN policy.

vault write aws/roles/my-role \
credential_type=iam_user \
policy_document=-<<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1426528957000",
"Effect": "Allow",
"Action": [
"ec2:*"
],
"Resource": [
"*"
]
}
]
}
EOF

Output:

Success! Data written to: aws/roles/my-role

Usage

vault read aws/creds/my-role

Output:

vault read aws/creds/my-role
Key Value
--- -----
lease_id aws/creds/my-role/XHHsCOS135tbkD0gMz9A8ge
lease_duration 768h
lease_renewable true
access_key AKIATOT...
secret_key RqLzsRWVDcNcqMH...
security_token <nil>

Disclaimer: When running an automation or a pipeline add a delay of 5 to 10 seconds. STS method is preferable to avoid the wait.

Secret Revocation

The following command releases a lease, use the lease_id value from the previous output after the keyword revoke

vault lease revoke aws/creds/my-role/XHHsCOS135tbkD0gMz9A8ge

Output:

All revocation operations queued successfully!

STS Federation Token Generation

It must be configured by using IAM user credentials due to a current AWS limitation.

  1. We need to create a file named policy.json, this is because when I attempted to add the policy as an inline policy I couldn’t generate the token and the TTL(Time To Live) were not working for me. For this task, I used my favorite command-line editor - emacs- and used the following command to create the file:
emacs -nw policy.json

2. Paste the following content in the text editor:

{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": [
"ec2:*",
"sts:GetFederationToken"
],
"Resource": "*"
}
}

Notice that under actions we set the sts:GetFederationToken policy with all the permissions to ec2.

3. To save the file use Ctrl+x and Ctrl+c.

4. To create a role named ec2_admin with the STS policy run the following command:

vault write aws/roles/ec2_admin \
credential_type=federation_token \
policy_document=@policy.json

Output:

Success! Data written to: aws/roles/ec2_admin

Usage

Creating an STS Federation token:

vault write aws/sts/ec2_admin ttl=60m

ttl refers to Time To Live. I played with it and accepts seconds, minutes and hours. Remember to keep on mind its constraints which are the following:

Member must have value less than or equal to 129600 seconds.
Member must have a minimum field value of 900 seconds.

Output:

Key                Value
--- -----
lease_id aws/sts/ec2_admin/AAEHbv7esgcAfjBysVCegseg5
lease_duration 1h3s
lease_renewable false
access_key ASIAT1234566S2M...
secret_key 0V4pcg3FMArn7i4...
security_token FwoGZXIvYXdzEMz//////////Opj92S7pLxZLQAazj...

Notice that the STS contains besides an access and secret key; a security token.

You might be wondering in which scenarios is this token useful, some examples scenarios are cross-account authentication or single sign-on(SSO).

Secret Revocation

The following command releases a lease, use the lease_id value from the previous output after the keyword revoke

vault lease revoke aws/sts/ec2_admin/AAEHbv7esgcAfjBysVCegseg5

Output:

All revocation operations queued successfully!

Additional notes:

With STS I had to use a file because the inline policy didn’t work for me as it did in the first example.

Finally, If you liked the article, please hit the follow button and leave lots of claps!

--

--

Marco Urrea

DevOps engineer at DigitalOnUs with a background in cloud computing, automation, and data integration. I’m also a fitness nerd into comic books, and traveling.