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