diff --git a/nomad/vault_test.go b/nomad/vault_test.go index e17c3bce0..53063e635 100644 --- a/nomad/vault_test.go +++ b/nomad/vault_test.go @@ -764,6 +764,16 @@ func TestVaultClient_CreateToken_Root_Target_Role(t *testing.T) { } func TestVaultClient_CreateToken_Blacklist_Role(t *testing.T) { + // Need to skip if test is 0.6.4 + version, err := testutil.VaultVersion() + if err != nil { + t.Fatalf("failed to determine version: %v", err) + } + + if strings.Contains(version, "v0.6.4") { + t.SkipNow() + } + v := testutil.NewTestVault(t).Start() defer v.Stop() diff --git a/testutil/vault.go b/testutil/vault.go index 23241194d..4ae2bcee1 100644 --- a/testutil/vault.go +++ b/testutil/vault.go @@ -123,3 +123,11 @@ func getPort() uint64 { vaultPortOffset += 1 return p } + +// VaultVersion returns the Vault version as a string or an error if it couldn't +// be determined +func VaultVersion() (string, error) { + cmd := exec.Command("vault", "version") + out, err := cmd.Output() + return string(out), err +} diff --git a/website/source/docs/vault-integration/index.html.md b/website/source/docs/vault-integration/index.html.md index a57771090..2d1130908 100644 --- a/website/source/docs/vault-integration/index.html.md +++ b/website/source/docs/vault-integration/index.html.md @@ -24,10 +24,10 @@ install Vault separately from Nomad. Nomad does not run Vault for you. ## Vault Configuration To use the Vault integration, Nomad servers must be provided a Vault token. This -token can either be a root token or a token with permissions to create from a -role. The root token is the easiest way to get started, but we recommend a -role-based token for production installations. Nomad servers will renew the -token automatically. +token can either be a root token or a periodic token with permissions to create +from a token role. The root token is the easiest way to get started, but we +recommend a token role based token for production installations. Nomad servers +will renew the token automatically. ### Root Token Integration @@ -36,28 +36,26 @@ token](https://www.vaultproject.io/docs/concepts/tokens.html#root-tokens), no further configuration is needed as Nomad can derive a token for jobs using any Vault policies. -### Role based Integration +### Token Role based Integration Vault's [Token Authentication Backend][auth] supports a concept called "roles". -Roles allow policies to be grouped together and token creation to be delegated -to a trusted service such as Nomad. By creating a role, the set of policies that -tasks managed by Nomad can access may be limited compared to giving Nomad a root -token. Roles allow both whitelist and blacklist management of polcies accessible -to the role. +Token roles allow policies to be grouped together and token creation to be +delegated to a trusted service such as Nomad. By creating a token role, the set +of policies that tasks managed by Nomad can access may be limited compared to +giving Nomad a root token. Token roles allow both white-list and blacklist +management of policies accessible to the role. To configure Nomad and Vault to create tokens against a role, the following must occur: - 1. Create a set of Vault policies that can be used to generate a token for the - Nomad Servers that allow them to create from a role and manage created - tokens within the cluster. The required policies are described below. + 1. Create a "nomad-server" policy used by Nomad to create and manage tokens. - 2. Create a Vault role with the configuration described below. + 2. Create a Vault token role with the configuration described below. - 3. Configure Nomad to use the created role. + 3. Configure Nomad to use the created token role. - 4. Give Nomad servers a token with the policies created from step 1. The token - must also be periodic. + 4. Give Nomad servers a periodic token with the "nomad-server" policy created + above. #### Required Vault Policies @@ -65,14 +63,14 @@ The token Nomad receives must have the capabilities listed below. An explanation for the use of each capability is given. ``` -# Allow creating tokens under "nomad-cluster" role. The role name should be -# updated if "nomad-cluster" is not used. +# Allow creating tokens under "nomad-cluster" token role. The token role name +# should be updated if "nomad-cluster" is not used. path "auth/token/create/nomad-cluster" { capabilities = ["update"] } -# Allow looking up "nomad-cluster" role. The role name should be updated if -# "nomad-cluster" is not used. +# Allow looking up "nomad-cluster" token role. The token role name should be +# updated if "nomad-cluster" is not used. path "auth/token/roles/nomad-cluster" { capabilities = ["read"] } @@ -113,12 +111,12 @@ $ curl https://nomadproject.io/data/vault/nomad-server-policy.hcl -O -s -L $ vault policy-write nomad-server nomad-server-policy.hcl ``` -#### Vault Role Configuration +#### Vault Token Role Configuration -A Vault role must be created for use by Nomad. The role can be used to manage -what Vault policies are accessible by jobs submitted to Nomad. The policies can -be managed as a whitelist by using `allowed_policies` in the role definition or -as a blacklist by using `disallowed_policies`. +A Vault token role must be created for use by Nomad. The token role can be used +to manage what Vault policies are accessible by jobs submitted to Nomad. The +policies can be managed as a whitelist by using `allowed_policies` in the token +role definition or as a blacklist by using `disallowed_policies`. If using `allowed_policies`, task's may only request Vault policies that are in the list. If `disallowed_policies` is used, task may request any policy that is @@ -126,7 +124,7 @@ not in the `disallowed_policies` list. There are tradeoffs to both approaches but generally it is easier to use the blacklist approach and add policies that you would not like tasks to have access to into the `disallowed_policies` list. -An example role definition is given below: +An example token role definition is given below: ```json { @@ -139,51 +137,57 @@ An example role definition is given below: } ``` -##### Role Requirements +##### Token Role Requirements -Nomad checks that role's have an appropriate configuration for use by the +Nomad checks that token role has an appropriate configuration for use by the cluster. Fields that are checked are documented below as well as descriptions of the important fields. See Vault's [Token Authentication Backend][auth] documentation for all possible fields and more complete documentation. * `allowed_policies` - Specifies the list of allowed policies as a - comma-seperated string. This list should contain all policies that jobs running + comma-separated string. This list should contain all policies that jobs running under Nomad should have access to. -* `disallowed_policies` - Specifies the list of disallowed policies as a - comma-seperated string. This list should contain all policies that jobs running - under Nomad should **not** have access to. The policy created above that - grants Nomad the ability to generate tokens from the role should be included - in list of disallowed policies. This prevents tokens created by Nomad from - generating new tokens with different policies than those granted by Nomad. +* `disallowed_policies` - Specifies the list of disallowed policies as a + comma-seperated string. This list should contain all policies that jobs running + under Nomad should **not** have access to. The policy created above that + grants Nomad the ability to generate tokens from the token role should be + included in list of disallowed policies. This prevents tokens created by + Nomad from generating new tokens with different policies than those granted + by Nomad. -* `explicit_max_ttl` - Specifies the max TTL of a token. Must be set to `0` to + A regression occured in Vault 0.6.4 when validating token creation using a + token role with `disallowed_policies` such that it is not usable with + Nomad. This will be remedied in 0.6.5 and does not effect earlier versions + of Vault. + +* `explicit_max_ttl` - Specifies the max TTL of a token. **Must be set to `0`** to allow periodic tokens. * `name` - Specifies the name of the policy. We recommend using the name - `nomad-cluster`. If a different name is chosen, replace the role in the above - policy. + `nomad-cluster`. If a different name is chosen, replace the token role in the + above policy. -* `orphan` - Specifies whether tokens created againsts this role will be - orphaned and have no parents. Must be set to `false`. This ensures that the +* `orphan` - Specifies whether tokens created against this token role will be + orphaned and have no parents. **Must be set to `false`**. This ensures that the token can be revoked when the task is no longer needed or a node dies. * `period` - Specifies the length the TTL is extended by each renewal in seconds. It is suggested to set this value on the order of magnitude of 3 days - (259200 seconds) to avoid a large renewal request rate to Vault. Must be set - to a positive value. + (259200 seconds) to avoid a large renewal request rate to Vault. **Must be set + to a positive value**. -* `renewable` - Specifies whether created tokens are renewable. Must be set to - `true`. This allows Nomad to renew tokens for tasks. +* `renewable` - Specifies whether created tokens are renewable. **Must be set to + `true`**. This allows Nomad to renew tokens for tasks. -The above [`nomad-cluster` role](/data/vault/nomad-cluster-role.hcl) is +The above [`nomad-cluster` token role](/data/vault/nomad-cluster-role.hcl) is available for download. Below is an example of writing this role to Vault: ``` -# Download the role +# Download the token role $ curl https://nomadproject.io/data/vault/nomad-cluster-role.json -O -s -L -# Create the role with Vault +# Create the token role with Vault $ vault write /auth/token/roles/nomad-cluster @nomad-cluster-role.json ``` @@ -192,27 +196,27 @@ $ vault write /auth/token/roles/nomad-cluster @nomad-cluster-role.json To make getting started easy, the basic [`nomad-server` policy](/data/vault/nomad-server-policy.hcl) and -[role](/data/vault/nomad-cluster-role.json) described above are available for -download. +[`nomad-cluster` role](/data/vault/nomad-cluster-role.json) described above are +available for download. -The below example assumes Vault is accessible, unsealed and the the operator has +The below example assumes Vault is accessible, unsealed and the operator has appropriate permissions. ```shell -# Download the policy and role +# Download the policy and token role $ curl https://nomadproject.io/data/vault/nomad-server-policy.hcl -O -s -L $ curl https://nomadproject.io/data/vault/nomad-cluster-role.json -O -s -L # Write the policy to Vault $ vault policy-write nomad-server nomad-server-policy.hcl -# Create the role with Vault +# Create the token role with Vault $ vault write /auth/token/roles/nomad-cluster @nomad-cluster-role.json ``` -#### Retrieving the Role based Token +#### Retrieving the Token Role based Token -After the role is created, a token suitable for the Nomad servers may be +After the token role is created, a token suitable for the Nomad servers may be retrieved by issuing the following Vault command: ``` @@ -246,17 +250,14 @@ specification documentation][vault-spec]. ## Troubleshooting Upon startup, Nomad will attempt to connect to the specified Vault server. Nomad -will lookup the passed token and if the token is from a role, the role will be -validated. Nomad will not shutdown if given an invalid Vault token, but will log -the reasons the token is invalid and disable Vault integration. +will lookup the passed token and if the token is from a token role, the token +role will be validated. Nomad will not shutdown if given an invalid Vault token, +but will log the reasons the token is invalid and disable Vault integration. ## Assumptions - Vault 0.6.2 or later is needed. -# XXX -- Nomad is given either a root token or a token created from an approriate role. - [auth]: https://www.vaultproject.io/docs/auth/token.html "Vault Authentication Backend" [config]: /docs/agent/configuration/vault.html "Nomad Vault Configuration Block" [createfromrole]: /docs/agent/configuration/vault.html#create_from_role "Nomad vault create_from_role Configuration Flag"