Storing Gloo Gateway secrets in HashiCorp Vault

Use HashiCorp Vault Key-Value storage as a backing store for Gloo Gateway secrets.

When Gloo Gateway boots, it reads the gloo.solo.io.Settings custom resource named default in the gloo-system namespace of your Kubernetes cluster to receive the proxy configuration for the gateway. By default, this configuration directs Gloo Gateway to connect to and use Kubernetes as the secret store for your environment. If you want Gloo Gateway to read and write secrets using a HashiCorp Vault instance instead of storing secrets directly in your Kubernetes cluster, you can edit the Settings custom resource to point the gateway proxy to Vault.

Want to use Vault with Gloo Gateway outside of Kubernetes instead? You can provide your settings file to Gloo Gateway inside of a configuration directory when you run Gloo Gateway locally

Customizing the Gloo Gateway settings file

Edit the default settings resource so Gloo Gateway reads and writes secrets using HashiCorp Vault.

Before you begin: Set up a Vault instance either in your Gloo Gateway cluster or externally. Your instance must be routable on an address that you provide to Gloo Gateway in the following steps, such as http://vault:8200.

  1. Edit the default settings resource.

    kubectl --namespace gloo-system edit settings default
    
  2. Make the following changes to the resource.

    • Remove the existing kubernetesSecretSource, vaultSecretSource, or directorySecretSource field, which directs the gateway to use secret stores other than Vault.
    • Add the secretOptions section and define a Vault secret source as shown in this guide. Optionally, a Kubernetes and/or a Directory secret source can also be specified.
      If you specify both a Kubernetes and Vault secret source in your Settings resource, the Kubernetes secret is looked up first. Keep in mind that when you specify multiple secret sources, the name and namespace of each secret must be unique to avoid unanticipated behavior.
    • Add the refreshRate field to configure the polling rate at which we watch for changes in Vault secrets and the local filesystem of where Gloo Gateway runs.
       apiVersion: gloo.solo.io/v1
       kind: Settings
       metadata:
         name: default
         namespace: gloo-system
       spec:
         discoveryNamespace: gloo-system
         gateway:
           validation:
             alwaysAccept: true
             proxyValidationServerAddr: gloo:9988
         gloo:
           xdsBindAddr: 0.0.0.0:9977
         kubernetesArtifactSource: {}
         kubernetesConfigSource: {}
         # Delete or comment out the existing *SecretSource field
         #kubernetesSecretSource: {}
         secretOptions:
           sources:
           # Enable secrets to be read from and written to HashiCorp Vault
           - vault:
             # Add the address that your Vault instance is routeable on
             address: http://vault:8200
             accessToken: root
         # Add the refresh rate for polling config backends for changes
         # This setting is used for watching vault secrets and by other resource clients
         refreshRate: 15s
    
       

For the full list of options for Gloo Gateway Settings, including the ability to set auth/TLS parameters for Vault, see the v1.Settings API reference .

An example using AWS IAM auth might look like the following:

   apiVersion: gloo.solo.io/v1
   kind: Settings
   metadata:
     name: default
     namespace: gloo-system
   spec:
     discoveryNamespace: gloo-system
     gateway:
       validation:
         alwaysAccept: true
         proxyValidationServerAddr: gloo:9988
     gloo:
       xdsBindAddr: 0.0.0.0:9977
     kubernetesArtifactSource: {}
     kubernetesConfigSource: {}
     # Delete or comment out the existing *SecretSource field
     #kubernetesSecretSource: {}
     secretOptions:
       sources:
       # Enable secrets to be read from and written to HashiCorp Vault
       - vault:
           # Address that your Vault instance is routeable on
           address: http://vault:8200
           aws:
             vaultRole: vault-role
             region: us-east-1
             iamServerIdHeader: vault.example.com
             accessKeyId: your-aws-iam-access-key-id
             secretAccessKey: your-aws-iam-secret-access-key
             sessionToken: your-aws-iam-session-token
     # refresh rate for polling config backends for changes
     # this is used for watching vault secrets and by other resource clients
     refreshRate: 15s
     requestTimeout: 0.5s
   

Writing secret objects to Vault

After configuring Vault as your secret store, be sure to write any Vault secrets by using Gloo Gateway-style YAML. You can either use the glooctl create secret command or manually write secrets.

Using glooctl

To get started writing Gloo Gateway secrets for use with Vault, you can use the glooctl create secret command. A benefit of using glooctl for secret creation is that the secret is created in the path that Gloo Gateway watches, secret/root/gloo.solo.io/v1/gloo-system/tls-secret.

For example, you might use the following command to create a secret in Vault.

glooctl create secret tls \
    --certchain /path/to/cert.pem \
    --privatekey /path/to/key.pem
    --name tls-secret \
    --use-vault \
    --vault-address http://vault:8200/ \
    --vault-token "$VAULT_TOKEN"

This command creates a TLS secret with the following value:

{
  "metadata": {
    "name": "tls-secret",
    "namespace": "gloo-system"
  },
  "tls": {
    "certChain": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----\n",
    "privateKey": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
  }
}

You can also include the -o json flag in the command for JSON-formatted secrets, which can be manually stored as values in Vault.

Manually writing secrets

Instead of using the glooctl create secret command to create the Vault secret and automatically store the secret key in your Vault instance, you can use your own configuration file to create the secret. Note that you must use the same YAML format for the secret so that Gloo Gateway can read the secret. For more information, see the v1.Secret API reference .

If you manually write Gloo Gateway secrets, you must store them in Vault with the correct Vault key names, which adhere to the following format:

<secret_engine_path_prefix>/<gloo_root_key>/<resource_group>/<group_version>/Secret/<resource_namespace>/<resource_name>

For example, if you want to create a secret named tls-secret in the gloo-system namespace, store the secret file in Vault on the path secret/root/gloo.solo.io/v1/Secret/gloo-system/tls-secret.

Path Description
<secret_engine_path_prefix> The pathPrefix configured in the Settings vaultSecretSource. Defaults to secret. Note that the default path for the kv secrets engine in Vault is kv when Vault is not run with -dev.
<gloo_root_key> The rootKey configured in the Settings vaultSecretSource. Defaults to gloo
<resource_group> The API group/proto package in which resources of the given type are contained. The Gloo Gateway secrets custom resource has the resource group gloo.solo.io.
<group_version> The API group version/go package in which resources of the given type are contained. For example, Gloo Gateway secrets have the resource group version v1.
<resource_namespace> The namespace in which the secret exists. This must match the metadata.namespace of the resource YAML.
<resource_name> The name of the secret. This must match the metadata.name of the resource YAML, and should be unique for all secrets within a given namespace.

You can also use the --dry-run flag in the glooctl secret create command to generate your secret in a YAML file.