github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/website/content/docs/integrations/vault-integration.mdx (about)

     1  ---
     2  layout: docs
     3  page_title: Vault Integration
     4  description: >-
     5    Learn how to integrate Nomad with HashiCorp Vault and retrieve Vault tokens
     6    for
     7  
     8    tasks.
     9  ---
    10  
    11  # Vault Integration
    12  
    13  Many workloads require access to tokens, passwords, certificates, API keys, and
    14  other secrets. To enable secure, auditable and easy access to your secrets,
    15  Nomad integrates with HashiCorp's [Vault][]. Nomad servers and clients
    16  coordinate with Vault to derive a Vault token that has access to only the Vault
    17  policies the tasks needs. Nomad clients make the token available to the task and
    18  handle the tokens renewal. Further, Nomad's [`template` block][template] can
    19  retrieve secrets from Vault making it easier than ever to secure your
    20  infrastructure.
    21  
    22  Note that in order to use Vault with Nomad, you will need to configure and
    23  install Vault separately from Nomad. Nomad does not run Vault for you.
    24  
    25  -> **Note:** Vault integration requires Vault version 0.6.2 or higher.
    26  
    27  ## Vault Configuration
    28  
    29  To use the Vault integration, Nomad servers must be provided a Vault token. This
    30  token can either be a root token or a periodic token with permissions to create
    31  from a token role. The root token is the easiest way to get started, but we
    32  recommend a token role based token for production installations. Nomad servers
    33  will renew the token automatically. **Note that the Nomad clients do not need to
    34  be provided with a Vault token.**
    35  
    36  -> **Note:** See the [Enterprise specific section][ent] for configuring Vault Enterprise
    37  
    38  ### Root Token Integration
    39  
    40  If Nomad is given a [root
    41  token](https://www.vaultproject.io/docs/concepts/tokens#root-tokens), no
    42  further configuration is needed as Nomad can derive a token for jobs using any
    43  Vault policies. Best practices recommend using a periodic token with the minimal
    44  permissions necessary instead of providing Nomad the root vault token.
    45  
    46  ### Token Role based Integration
    47  
    48  Vault's [Token Authentication Backend][auth] supports a concept called "roles".
    49  Token roles allow policies to be grouped together and token creation to be
    50  delegated to a trusted service such as Nomad. By creating a token role, the set
    51  of policies that tasks managed by Nomad can access may be limited compared to
    52  giving Nomad a root token. Token roles allow both allowlist and denylist
    53  management of policies accessible to the role.
    54  
    55  To configure Nomad and Vault to create tokens against a role, the following must
    56  occur:
    57  
    58  1. Create a "nomad-server" policy used by Nomad to create and manage tokens.
    59  
    60  2. Create a Vault token role with the configuration described below.
    61  
    62  3. Configure Nomad to use the created token role.
    63  
    64  4. Give Nomad servers a periodic token with the "nomad-server" policy created
    65     above.
    66  
    67  #### Required Vault Policies
    68  
    69  The token Nomad receives must have the capabilities listed below. An explanation
    70  for the use of each capability is given.
    71  
    72  ```hcl
    73  # Allow creating tokens under "nomad-cluster" token role. The token role name
    74  # should be updated if "nomad-cluster" is not used.
    75  path "auth/token/create/nomad-cluster" {
    76    capabilities = ["update"]
    77  }
    78  
    79  # Allow looking up "nomad-cluster" token role. The token role name should be
    80  # updated if "nomad-cluster" is not used.
    81  path "auth/token/roles/nomad-cluster" {
    82    capabilities = ["read"]
    83  }
    84  
    85  # Allow looking up the token passed to Nomad to validate # the token has the
    86  # proper capabilities. This is provided by the "default" policy.
    87  path "auth/token/lookup-self" {
    88    capabilities = ["read"]
    89  }
    90  
    91  # Allow looking up incoming tokens to validate they have permissions to access
    92  # the tokens they are requesting. This is only required if
    93  # `allow_unauthenticated` is set to false.
    94  path "auth/token/lookup" {
    95    capabilities = ["update"]
    96  }
    97  
    98  # Allow revoking tokens that should no longer exist. This allows revoking
    99  # tokens for dead tasks.
   100  path "auth/token/revoke-accessor" {
   101    capabilities = ["update"]
   102  }
   103  
   104  # Allow checking the capabilities of our own token. This is used to validate the
   105  # token upon startup. Note this requires update permissions because the Vault API
   106  # is a POST
   107  path "sys/capabilities-self" {
   108    capabilities = ["update"]
   109  }
   110  
   111  # Allow our own token to be renewed.
   112  path "auth/token/renew-self" {
   113    capabilities = ["update"]
   114  }
   115  ```
   116  
   117  The above [`nomad-server` policy](/data/vault/nomad-server-policy.hcl) is
   118  available for download. Below is an example of writing this policy to Vault:
   119  
   120  ```shell-session
   121  # Download the policy
   122  $ curl https://nomadproject.io/data/vault/nomad-server-policy.hcl -O -s -L
   123  
   124  # Write the policy to Vault
   125  $ vault policy write nomad-server nomad-server-policy.hcl
   126  ```
   127  
   128  #### Vault Token Role Configuration
   129  
   130  A Vault token role must be created for use by Nomad. The token role can be used
   131  to manage what Vault policies are accessible by jobs submitted to Nomad. The
   132  policies can be managed as a allowlist by using `allowed_policies` in the token
   133  role definition or as a denylist by using `disallowed_policies`.
   134  
   135  If using `allowed_policies`, tasks may only request Vault policies that are in
   136  the list. If `disallowed_policies` is used, task may request any policy that is
   137  not in the `disallowed_policies` list. There are trade-offs to both approaches
   138  but generally it is easier to use the denylist approach and add policies that
   139  you would not like tasks to have access to into the `disallowed_policies` list.
   140  
   141  An example token role definition is given below:
   142  
   143  ```json
   144  {
   145    "disallowed_policies": "nomad-server",
   146    "token_explicit_max_ttl": 0,
   147    "name": "nomad-cluster",
   148    "orphan": true,
   149    "token_period": 259200,
   150    "renewable": true
   151  }
   152  ```
   153  
   154  ##### Token Role Requirements
   155  
   156  Nomad checks that token role has an appropriate configuration for use by the
   157  cluster. Fields that are checked are documented below as well as descriptions of
   158  the important fields. See Vault's [Token Authentication Backend][auth]
   159  documentation for all possible fields and more complete documentation.
   160  
   161  - `allowed_policies` - Specifies the list of allowed policies as a
   162    comma-separated string. This list should contain all policies that jobs running
   163    under Nomad should have access to.
   164  
   165  - `disallowed_policies` - Specifies the list of disallowed policies as a
   166    comma-separated string. This list should contain all policies that jobs running
   167    under Nomad should **not** have access to. The policy created above that
   168    grants Nomad the ability to generate tokens from the token role should be
   169    included in list of disallowed policies. This prevents tokens created by
   170    Nomad from generating new tokens with different policies than those granted
   171    by Nomad.
   172  
   173    A regression occurred in Vault 0.6.4 when validating token creation using a
   174    token role with `disallowed_policies` such that it is not usable with
   175    Nomad. This was remedied in 0.6.5 and does not effect earlier versions
   176    of Vault.
   177  
   178  - `token_explicit_max_ttl` - Specifies the max TTL of a token. **Must be set to `0`** to
   179    allow periodic tokens.
   180  
   181  - `name` - Specifies the name of the policy. We recommend using the name
   182    `nomad-cluster`. If a different name is chosen, replace the token role in the
   183    above policy.
   184  
   185  - `orphan` - Specifies whether tokens created against this token role will be
   186    orphaned and have no parents. Nomad does not enforce the value of this field
   187    but understanding the implications of each value is important.
   188  
   189    If set to false, all tokens will be revoked when the Vault token given to
   190    Nomad expires. This makes it easy to revoke all tokens generated by Nomad but
   191    forces all Nomad servers to use the same Vault token, even through upgrades of
   192    Nomad servers. If the Vault token that was given to Nomad and used to generate
   193    a tasks token expires, the token used by the task will also be revoked which
   194    is not ideal.
   195  
   196    When set to true, the tokens generated for tasks will not be revoked when
   197    Nomad's token is revoked. However Nomad will still revoke tokens when the
   198    allocation is no longer running, minimizing the lifetime of any task's token.
   199    With orphaned enabled, each Nomad server may also use a unique Vault token,
   200    making bootstrapping and upgrading simpler. As such, **setting `orphan = true`
   201    is the recommended setting**.
   202  
   203  - `token_period` - Specifies the length the TTL is extended by each renewal in
   204    seconds. It is suggested to set this value on the order of magnitude of 3 days
   205    (259200 seconds) to avoid a large renewal request rate to Vault. **Must be set
   206    to a positive value**.
   207  
   208  - `renewable` - Specifies whether created tokens are renewable. **Must be set to
   209    `true`**. This allows Nomad to renew tokens for tasks.
   210  
   211  The above [`nomad-cluster` token role](/data/vault/nomad-cluster-role.json) is
   212  available for download. Below is an example of writing this role to Vault:
   213  
   214  ```shell-session
   215  # Download the token role
   216  $ curl https://nomadproject.io/data/vault/nomad-cluster-role.json -O -s -L
   217  
   218  # Create the token role with Vault
   219  $ vault write /auth/token/roles/nomad-cluster @nomad-cluster-role.json
   220  ```
   221  
   222  #### Example Configuration
   223  
   224  To make getting started easy, the basic [`nomad-server`
   225  policy](/data/vault/nomad-server-policy.hcl) and
   226  [`nomad-cluster` role](/data/vault/nomad-cluster-role.json) described above are
   227  available for download.
   228  
   229  The below example assumes Vault is accessible, unsealed and the operator has
   230  appropriate permissions.
   231  
   232  ```shell-session
   233  # Download the policy and token role
   234  $ curl https://nomadproject.io/data/vault/nomad-server-policy.hcl -O -s -L
   235  $ curl https://nomadproject.io/data/vault/nomad-cluster-role.json -O -s -L
   236  
   237  # Write the policy to Vault
   238  $ vault policy write nomad-server nomad-server-policy.hcl
   239  
   240  # Create the token role with Vault
   241  $ vault write /auth/token/roles/nomad-cluster @nomad-cluster-role.json
   242  ```
   243  
   244  #### Retrieving the Token Role based Token
   245  
   246  After the token role is created, a token suitable for the Nomad servers may be
   247  retrieved by issuing the following Vault command:
   248  
   249  ```shell-session
   250  $ vault token create -policy nomad-server -period 72h -orphan
   251  Key             Value
   252  ---             -----
   253  token           f02f01c2-c0d1-7cb7-6b88-8a14fada58c0
   254  token_accessor  8cb7fcb3-9a4f-6fbf-0efc-83092bb0cb1c
   255  token_duration  259200s
   256  token_renewable true
   257  token_policies  [default nomad-server]
   258  ```
   259  
   260  The `-orphan` flag is included when generating the Nomad server token above to
   261  prevent revocation of the token when its parent expires. Vault typically
   262  creates tokens with a parent-child relationship. When an ancestor token is
   263  revoked, all of its descendant tokens and their associated leases are revoked
   264  as well.
   265  
   266  When generating Nomad's Vault token, we need to ensure that revocation of the
   267  parent token does not revoke Nomad's token. To prevent this behavior we
   268  specify the `-orphan` flag when we create the Nomad's Vault token. All
   269  other tokens generated by Nomad for jobs will be generated using the policy
   270  default of `orphan = false`.
   271  
   272  More information about creating orphan tokens can be found in
   273  [Vault's Token Hierarchies and Orphan Tokens documentation][tokenhierarchy].
   274  
   275  The [`-period` flag](https://www.vaultproject.io/docs/commands/token/create#period) is required to allow the automatic renewal of the token. If this is left out, a [`vault token renew` command](https://www.vaultproject.io/docs/commands/token/renew) will need to be run manually to renew the token.
   276  
   277  The token can then be set in the server configuration's
   278  [`vault` stanza][config], as a command-line flag, or via an environment
   279  variable.
   280  
   281  ```shell-session
   282  $ VAULT_TOKEN=f02f01c2-c0d1-7cb7-6b88-8a14fada58c0 nomad agent -config /path/to/config
   283  ```
   284  
   285  An example of what may be contained in the configuration is shown below. For
   286  complete documentation please see the [Nomad agent Vault integration][config]
   287  configuration.
   288  
   289  ```hcl
   290  vault {
   291    enabled          = true
   292    ca_path          = "/etc/certs/ca"
   293    cert_file        = "/var/certs/vault.crt"
   294    key_file         = "/var/certs/vault.key"
   295    address          = "https://vault.service.consul:8200"
   296    create_from_role = "nomad-cluster"
   297  }
   298  ```
   299  
   300  ## Agent Configuration
   301  
   302  To enable Vault integration, please see the [Nomad agent Vault
   303  integration][config] configuration.
   304  
   305  ## Vault Definition Syntax
   306  
   307  To configure a job to retrieve Vault tokens, please see the [`vault` job
   308  specification documentation][vault-spec].
   309  
   310  ## Troubleshooting
   311  
   312  ### Invalid Vault token
   313  
   314  Upon startup, Nomad will attempt to connect to the specified Vault server. Nomad
   315  will lookup the passed token and if the token is from a token role, the token
   316  role will be validated. Nomad will not shutdown if given an invalid Vault token,
   317  but will log the reasons the token is invalid and disable Vault integration.
   318  
   319  ### Permission Denied errors
   320  
   321  If you are using a Vault version less than 0.7.1 with a Nomad version greater than or equal to 0.6.1, you will need to update your task's policy (listed in [the `vault` stanza of the job specification][vault-spec]) to add the following:
   322  
   323  ```hcl
   324  path "sys/leases/renew" {
   325      capabilities = ["update"]
   326  }
   327  ```
   328  
   329  This is included in Vault's "default" policy beginning with Vault 0.7.1 and is relied upon by Nomad's Vault integration beginning with Nomad 0.6.1. If you're using a newer Nomad version with an older Vault version, your default policy may not automatically include this and you will see "permission denied" errors in your Nomad logs similar to the following:
   330  
   331  ```plaintext
   332  Code: 403. Errors:
   333  URL: PUT https://vault:8200/v1/sys/leases/renew
   334  * permission denied
   335  ```
   336  
   337  ### No Secret Exists
   338  
   339  Vault has two APIs for secrets, [`v1` and `v2`][vault-secrets-version]. Each version
   340  has different paths, and Nomad does not abstract this for you. As such you will
   341  need to specify the path as reflected by Vault's HTTP API, rather than the path
   342  used in the `vault kv` command.
   343  
   344  You can see examples of `v1` and `v2` syntax in the
   345  [template documentation][vault-kv-templates].
   346  
   347  ## Enterprise Configuration
   348  
   349  <EnterpriseAlert />
   350  
   351  Nomad Enterprise 0.12.2 introduced the ability for jobs to use multiple Vault Namespaces.
   352  There are a few configuration settings to consider when using this functionality.
   353  
   354  ### Example Configuration
   355  
   356  Below is an example for creating two Namespaces within Vault.
   357  
   358  ```shell-session
   359  # Create a namespace "engineering" within Vault
   360  $ vault namespace create engineering
   361  
   362  # Create a child namespace "frontend" under "engineering"
   363  $ vault namespace create -namespace=engineering frontend
   364  ```
   365  
   366  ### Required Vault Policies
   367  
   368  Policies are configured per Vault namespace. We will apply the policy in the example above to each namespace—engineering and engineering/frontend.
   369  
   370  ```shell-session
   371  # Create the "nomad-server" policy in the "engineering" namespace
   372  $ vault policy write -namespace=engineering nomad-server nomad-server-policy.hcl
   373  
   374  # Create the "nomad-server" policy in the "engineering/frontend" namespace
   375  $ vault policy write -namespace=engineering/frontend nomad-server nomad-server-policy.hcl
   376  ```
   377  
   378  We will also configure the previously configured `nomad-cluster` role with each Namespace
   379  
   380  ```shell-session
   381  # Create the "nomad-cluster" token role in the "engineering" namespace
   382  $ vault write -namespace=engineering /auth/token/roles/nomad-cluster @nomad-cluster-role.json
   383  
   384  # Create the "nomad-cluster" token role in the "engineering/frontend" namespace
   385  $ vault write -namespace=engineering/frontend /auth/token/roles/nomad-cluster @nomad-cluster-role.json
   386  ```
   387  
   388  The [Nomad agent Vault integration][config] configuration supports specifying a Vault Namespace, but since
   389  we will be using multiple it can be left blank. By default Nomad will interact with Vault's root Namespace, but individual jobs may specify other Vault Namespaces to use.
   390  
   391  ```hcl
   392  vault {
   393    enabled               = true
   394    ca_path               = "/etc/certs/ca"
   395    cert_file             = "/var/certs/vault.crt"
   396    key_file              = "/var/certs/vault.key"
   397    address               = "https://vault.service.consul:8200"
   398    create_from_role      = "nomad-cluster"
   399    allow_unauthenticated = false # Disabling allow_unauthenticated is a best practice for securing your cluster
   400  }
   401  ```
   402  
   403  The same steps can be taken to inject a Vault token from the [Retrieving the Token Role based Token](#retrieving-the-token-role-based-token) steps.
   404  
   405  ### Submitting a job with a Vault Namespace
   406  
   407  Since [`allow_unauthenticated`][allow_unauth] is set to `false` job submitters will need to provide a sufficiently privileged token when submitting a job.
   408  
   409  [allow_unauth]: /docs/configuration/vault#allow_unauthenticated
   410  
   411  The example job file below specifies to use the `engineering` Namespace in Vault. It will then read the value at secret/foo and fetch the value for key `bar`
   412  
   413  ```hcl
   414  job "vault" {
   415    datacenters = ["dc1"]
   416  
   417    group "demo" {
   418      task "task" {
   419        vault {
   420          namespace = "engineering"
   421          policies  = ["access-kv"]
   422        }
   423  
   424        driver = "raw_exec"
   425        config {
   426          command = "/usr/bin/cat"
   427          args    = ["secrets/config.txt"]
   428        }
   429  
   430        template {
   431          data        = <<EOF
   432  {{ with secret "secret/foo" }}
   433  SOME_VAL={{.Data.bar}}
   434  {{ end }}
   435  EOF
   436          destination = "secrets/config.txt"
   437        }
   438      }
   439    }
   440  }
   441  
   442  ```
   443  
   444  To Submit this job a token that has the `access-kv` policy in the Namespace `engineering`
   445  
   446  ```shell-session
   447  $ vault token create -policy access-kv -namespace=engineering -period 72h -orphan
   448  
   449  Key                  Value
   450  ---                  -----
   451  token                s.H39hfS7eHSbb1GpkdzOQLTmz.fvuLy
   452  token_accessor       VsKtJwaShwtTo1r9nWV9Rlad.fvuLy
   453  token_duration       72h
   454  token_renewable      true
   455  token_policies       ["access-kv" "default"]
   456  identity_policies    []
   457  policies             ["access-kv" "default"]
   458  ```
   459  
   460  The token can then be submitted with our job
   461  
   462  ```shell-session
   463  $ VAULT_TOKEN=s.H39hfS7eHSbb1GpkdzOQLTmz.fvuLy nomad job run vault.nomad
   464  ```
   465  
   466  [auth]: https://www.vaultproject.io/docs/auth/token 'Vault Authentication Backend'
   467  [config]: /docs/configuration/vault 'Nomad Vault Configuration Block'
   468  [createfromrole]: /docs/configuration/vault#create_from_role 'Nomad vault create_from_role Configuration Flag'
   469  [template]: /docs/job-specification/template 'Nomad template Job Specification'
   470  [vault]: https://www.vaultproject.io/ 'Vault by HashiCorp'
   471  [vault-spec]: /docs/job-specification/vault 'Nomad Vault Job Specification'
   472  [tokenhierarchy]: https://www.vaultproject.io/docs/concepts/tokens#token-hierarchies-and-orphan-tokens 'Vault Tokens - Token Hierarchies and Orphan Tokens'
   473  [vault-secrets-version]: https://www.vaultproject.io/docs/secrets/kv 'KV Secrets Engine'
   474  [vault-kv-templates]: /docs/job-specification/template#vault-kv-api-v1 'Vault KV API v1'
   475  [ent]: /docs/integrations/vault-integration#enterprise-configuration