Vault Agent

The Vault Agent is a client daemon that runs alongside an application to enable legacy applications to interact and consume secrets.

Vault Agent provides several different features:

Securely Configure Auto-Auth and Token Sink

Slides 1-13

Vault Agent – Auto-Auth

Vault Agent supports many types of auth methods to authenticate and obtain a token.

Auth methods are generally the methods you’d associate with “machine-oriented” auth methods:

Vault Agent Configuration File

# agent.hcl
auto_auth {
  # Auto-Auth Configuration (AppRole)
  method "approle" {
    mount_path = "auth/approle"
    config = {
      role_id_file_path = "<path-to-file>"
      secret_id_file_path = "<path-to-file>"
      # By default vault will delete the secret_id file above after reading it.
      # Vault assumes you are injecting the secret id file via a deployment process such as Jenkins or via kubernetes
      # Use this parameter to disable this functionality (not recommended)
      # ? how to handle a stand alone server that restarts ?
      remove_secret_id_file_after_reading = false
    }
  }

  # Sink Configuration
  sink "file" {
    config = {
      path = "/etc/vault.d/token.txt"
    }
  }
}

# Vault
vault {
  address = "http://<cluster_IP>:8200"
}

Starting the Vault Agent

vault agent -config=/etc/vault.d/agent.hcl

Vault Agent - Sink

As of today, file is the only supported method of storing the auto-auth token

Common configuration parameters include:

Auto-Auth Security Concerns

Protecting the Token using Response Wrapping

To help secure tokens when using Auto-Auth, you can have Vault response wrap the token when the Vault Agent authenticates

The placement of the wrap_ttl in the Vault Agent configuration file determines where the response wrapping happens.

Response-Wrapping the Token - Comparison

Response Wrapped by the Auth Method:

# agent.hcl
pid_file = "/home/vault/pidfile"

auto_auth {
  method "kubernetes" {
    wrap_ttl = "5m" # wrap_ttl goes here for wrapping at the auth method.
    mount_path = "auth/kubernetes"
    config = {
      role = "example"
    }
  }
  sink "file" {
    config = {
      path = "/etc/vault/token"
    }
  }

vault {
  address = "http://<cluster_IP>:8200"
}

Response Wrapped by the Sink

# agent.hcl
pid_file = "/home/vault/pidfile"

auto_auth {
  method "kubernetes" {
    mount_path = "auth/kubernetes"
    config = {
      role = "example"
    }
  }
  sink "file" {
    wrap_ttl = "5m" # wrap_ttl goes here for wrapping at the sink method
    config = {
      path = "/etc/vault/token"
    }
  }
}

vault {
  address = "http://<cluster_IP>:8200"
}

Vault Templating

Slides 15-24

Consul Template

Consul Template - Workflow

  1. Create a templated file that specifies the path and data you want
  2. Execute Consul Template. Consul Template retrieves data and renders to destination file
  3. The application reads the new file at runtime that includes secrets retrieved from Vault

Create a templated file

# /etc/vault/web.tmpl
production:
  adapter: postgresql
  encoding: unicode
  database: orders
  host: postgres.hcvop.com # The path in Vault to read secrets from
  
  username: "" # The data to be retrieved and consumed from the Vault response
  password: ""
  

Destination File that application server will read at runtime

# /etc/webapp/config.yml
production:
  adapter: postgresql
  encoding: unicode
  database: orders
  host: postgres.hcvop.com
  username: "v-vault-readonly-fm3dfm20sm2s"
  password: "fjk39fkj49fks02k_3ks02mdz1s1"

Vault Agent Templating

Template Configuration

auto_auth {
  method "approle" {
    mount_path = "auth/approle"
...
sink "file" {
  config = {
    path = "/etc/vault.d/token.txt"
...

# Global Template Configurations (affects all templates)
template_config {
  exit_on_retry_failure = true 
  static_secret_render_interval = "10m"
}

# Template Configuration
template {
  source = "/etc/vault/web.tmpl"
  destination = "/etc/webapp/config.yml"
}