Configure HashiCorp Vault as a vault backend with AWS IAM authentication

TL;DR

Enable the AWS auth method in HashiCorp Vault, configure it with credentials that can verify IAM identity.

Then in Kong Gateway, configure a Vault entity with the following:

  • Set config.auth_method to aws_iam.
  • Set config.aws_auth_role to the Vault role name.
  • Set config.aws_auth_region to your AWS region.
  • Optionally, set config.aws_access_key_id and config.aws_secret_access_key for Kong Gateway’s AWS credentials. If omitted, Kong Gateway uses the default AWS credentials provider chain.

Prerequisites

In this how-to, you’ll be running two Elastic Compute Cloud VMs: one with Kong Gateway and another with HashiCorp Vault. Since you’ll be using two VMs, you’ll need two AWS IAM roles so that the two VMS can communicate:

  1. Create an IAM role for the Kong Gateway VM with the following permissions:
    • Trust: ec2.amazonaws.com:
      {
          "Version": "2012-10-17",
          "Statement": [
              {
                  "Effect": "Allow",
                  "Principal": {
                      "Service": "ec2.amazonaws.com"
                  },
                  "Action": "sts:AssumeRole"
              },
              {
                  "Effect": "Allow",
                  "Principal": {
                      "AWS": "arn:aws:iam::123456789012:role/VaultRole"
                  },
                  "Action": "sts:AssumeRole"
              }
          ]
      }
      
    • Permission: sts:AssumeRole on the HashiCorp Vault role ARN:
      {
          "Version": "2012-10-17",
          "Statement": [
              {
                  "Sid": "Statement1",
                  "Effect": "Allow",
                  "Action": [
                      "ec2:DescribeInstances"
                  ],
                  "Resource": [
                      "*"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iam:GetRole"
                  ],
                  "Resource": [
                      "arn:aws:iam::123456789012:role/KongRole"
                  ]
              }
          ]
      }
      

      This has more permission than minimal permission for vault authentication because we need to allow the Kong Gateway process to communicate with AWS identity service on the EC2 VM where Kong Gateway is running.

  2. Create an IAM role for the HashiCorp Vault VM with the following permissions:
    • Trust: ec2.amazonaws.com and Kong Gateway role ARN (cross-role assume)
      {
         "Version": "2012-10-17",
         "Statement": [
             {
                 "Effect": "Allow",
                 "Principal": {
                     "Service": "ec2.amazonaws.com"
                 },
                 "Action": "sts:AssumeRole"
             },
             {
                 "Effect": "Allow",
                 "Principal": {
                     "AWS": "arn:aws:iam::123456789012:role/KongRole"
                 },
                 "Action": "sts:AssumeRole"
             }
         ]
      }
      
    • Permission: iam:getRole:
      {
         "Version": "2012-10-17",
           "Statement": [
               {
                   "Sid": "Statement1",
                   "Effect": "Allow",
                   "Action": [
                       "ec2:DescribeInstances"
                   ],
                   "Resource": [
                       "*"
                   ]
               },
               {
                   "Effect": "Allow",
                   "Action": [
                       "iam:GetRole"
                   ],
                   "Resource": [
                       "arn:aws:iam::123456789012:role/VaultRole"
                   ]
               }
           ]
        }
      
        {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Action": [
                        "sts:AssumeRole"
                    ],
                    "Resource": [
                        "arn:aws:iam::123456789012:role/KongRole"
                    ]
                }
            ]
        }
      

      This has more permission than minimal permission for vault authentication because we need to allow the Kong Gateway process to communicate with AWS identity service on the EC2 VM where Kong Gateway is running.

  3. Export Kong Gateway’s AWS region and the ARN of the IAM user that is associated with the EC2 VM that will be running HashiCorp Vault:
    export AWS_AUTH_REGION="us-east-1"
    export IAM_VAULT_ROLE_ARN="arn:aws:iam::123456789012:role/VaultRole"
    
  4. Create two EC2 VMs, one with Kong Gateway installed and running, and one for HashiCorp Vault and associate the respective IAM roles with the VMs. Open 8200 ports on the vault EC2 instance to allow requests from other EC2 VMs. We recommend creating two AWS EC2 VMs in the same VPC for simplicity.

You need HashiCorp Vault installed on your EC2 VM.

The steps in this how to assume that HashiCorp Vault and Kong Gateway are installed on separate EC2 VMs.
If your VM configuration is different, see the HashiCorp Vault AWS authentication documentation for the configuration changes you’ll need to make.

Configure HashiCorp Vault

Before you can configure the Vault entity in Kong Gateway, you must configure HashiCorp Vault to authenticate clients using AWS IAM identity and store a secret.

Create configuration files

First, create the primary configuration file config.hcl for HashiCorp Vault in the ./vault directory:

listener "tcp" {
  address     = "0.0.0.0:8200"
  tls_disable = true
}

storage "file" {
  path = "./vault/data"
}

ui = true

Then, create the HashiCorp Vault policy file rw-secrets.hcl in the ./vault directory:

path "*" {
  capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}

Configure the Vault and store a secret

  1. In a new terminal, start HashiCorp Vault:
    vault server -config=./vault/config.hcl
    
  2. In your previous terminal, set the Vault address:
    export VAULT_ADDR="http://localhost:8200"
    
  3. Initialize the Vault:
    vault operator init -key-shares=1 -key-threshold=1
    

    This outputs your unseal key and initial root token. Export them as environment variables:

    export HCV_UNSEAL_KEY='YOUR-UNSEAL-KEY'
    export DECK_HCV_TOKEN='YOUR-INITIAL-ROOT-TOKEN'
    
  4. Unseal your Vault:
    vault operator unseal $HCV_UNSEAL_KEY
    
  5. Log in to your Vault:
    vault login $DECK_HCV_TOKEN
    
  6. Write the policy to access secrets:
    vault policy write rw-secrets ./vault/rw-secrets.hcl
    
  7. Enable AWS authentication:
    vault auth enable aws
    
  8. Configure the AWS client:
    vault write auth/aws/config/client \
     use_sts_region_from_client=true
    
  9. Create an IAM role that binds to Kong Gateway’s IAM principal:
    vault write auth/aws/role/kong-role \
      auth_type=iam \
      bound_iam_principal_arn="$IAM_VAULT_ROLE_ARN" \
      token_policies="rw-secrets"
    
  10. Enable the K/V secrets engine:
    vault secrets enable -path=kong kv
    
  11. Create a secret:
    vault kv put kong/headers/request header="x-kong:test"
    
  12. Confirm you can retrieve the secret through Vault:
    vault kv get kong/headers/request
    

Set environment variables

Find the internal IP for your VM:

hostname -I

Export the following environment variables before creating the Vault entity:

export HCV_HOST="YOUR VM INTERNAL IP"
export AWS_AUTH_ROLE=kong-role

Create a Vault entity for HashiCorp Vault

Using decK, create a Vault entity in the kong.yaml file with the required parameters for HashiCorp Vault AWS IAM authentication:

curl -X POST "http://localhost:8001/vaults" \
     --no-progress-meter --fail-with-body  \
     --json '{
       "name": "hcv",
       "prefix": "hashicorp-vault",
       "description": "Storing secrets in HashiCorp Vault",
       "config": {
         "host": "'$HCV_HOST'",
         "kv": "v1",
         "mount": "kong",
         "port": 8200,
         "protocol": "http",
         "auth_method": "aws_iam",
         "aws_auth_role": "'$AWS_AUTH_ROLE'",
         "aws_auth_region": "'$AWS_AUTH_REGION'",
         "aws_assume_role_arn": "'$IAM_VAULT_ROLE_ARN'",
         "aws_role_session_name": "kong"
       }
     }'

Validate

To validate that the secret was stored correctly in HashiCorp Vault, call a secret from your vault using the kong vault get command:

kong vault get {vault://hashicorp-vault/headers/request/header}

If the vault was configured correctly, this command returns the value of the secret. You can use {vault://hashicorp-vault/headers/request/header} to reference the secret in any referenceable field.

For more information about supported secret types, see What can be stored as a secret.

Cleanup

Stop the HashiCorp Vault process by running the following:

pkill vault

Unset environment variables:

unset VAULT_ADDR
unset AWS_ACCESS_KEY_ID
unset AWS_SECRET_ACCESS_KEY
curl -Ls https://get.konghq.com/quickstart | bash -s -- -d

FAQs

No, these fields are optional. If omitted, Kong Gateway uses the default AWS credentials provider chain, which checks environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY), shared credential files, and EC2 instance profiles in order. Providing them explicitly in the entity is useful when you want to configure Kong Gateway’s AWS identity independently of the host environment.

You can rotate your secret in HashiCorp Vault by creating a new secret version with the updated value. You’ll also want to configure the ttl settings in your Kong Gateway Vault entity so that Kong Gateway pulls the rotated secret periodically.

Yes, you can also configure a Vault in one of the following ways:

  • Using environment variables, set at Kong Gateway startup
  • Using parameters in kong.conf, set at Kong Gateway startup

See the Vault reference for your provider for the available parameters and their format in each method.

Help us make these docs great!

Kong Developer docs are open source. If you find these useful and want to make them better, contribute today!