From 49af594287b3539bfdcac4a5c1e85fe0a18f3d43 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Sat, 2 Dec 2017 13:34:51 -0500 Subject: [PATCH 01/18] Update some rekey docs Fixes #3306 --- website/source/guides/rekeying-and-rotating.html.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/website/source/guides/rekeying-and-rotating.html.md b/website/source/guides/rekeying-and-rotating.html.md index dcc0334c1c67..42bd7da5520a 100644 --- a/website/source/guides/rekeying-and-rotating.html.md +++ b/website/source/guides/rekeying-and-rotating.html.md @@ -64,7 +64,8 @@ either of these processes. ## Rekeying Vault Rekeying the Vault requires a quorum of unseal keys. Before continuing, you -should ensure all unseal key holders are available to assist with the rekeying. +should ensure enough unseal key holders are available to assist with the +rekeying to match the threshold configured when the keys were issued. First, initialize a rekeying operation. The flags represent the **newly desired** number of keys and threshold: From b64a416101edb6f80e3b64194ebd1e073a6735d5 Mon Sep 17 00:00:00 2001 From: immutability Date: Sat, 2 Dec 2017 13:43:37 -0500 Subject: [PATCH 02/18] Missing command for vault PUT operation (#3355) --- website/source/guides/plugin-backends.html.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/source/guides/plugin-backends.html.md b/website/source/guides/plugin-backends.html.md index 9cbb0869e0e9..d021405cb573 100644 --- a/website/source/guides/plugin-backends.html.md +++ b/website/source/guides/plugin-backends.html.md @@ -59,7 +59,7 @@ and use that to register the plugin into Vault's plugin catalog. $ shasum -a 256 /etc/vault/vault_plugins/mock-plugin 2c071aafa1b30897e60b79643e77592cb9d1e8f803025d44a7f9bbfa4779d615 /etc/vault/vault_plugins/mock-plugin -$ vault sys/plugins/catalog/mock-plugin sha_256=2c071aafa1b30897e60b79643e77592cb9d1e8f803025d44a7f9bbfa4779d615 command=mock-plugin +$ vault write sys/plugins/catalog/mock-plugin sha_256=2c071aafa1b30897e60b79643e77592cb9d1e8f803025d44a7f9bbfa4779d615 command=mock-plugin Success! Data written to: sys/plugins/catalog/mock-plugin ``` @@ -100,4 +100,4 @@ sys/ system system_e3a4cccd n/a n/a n/a false ``` [plugin-system]: /docs/internals/plugins.html -[database-backend]: /docs/secrets/databases/index.html \ No newline at end of file +[database-backend]: /docs/secrets/databases/index.html From 100ec6c29294fa5b30259992896adca7271f5f47 Mon Sep 17 00:00:00 2001 From: Marc Sensenich Date: Sat, 2 Dec 2017 14:12:39 -0500 Subject: [PATCH 03/18] Remove Trailing White space in Kubernetes Doc (#3360) Removed a trailing white space from which caused `Error loading data: Invalid key/value pair ' ': format must be key=value` if copying the example ``` vault write auth/kubernetes/role/demo \ bound_service_account_names=vault-auth \ bound_service_account_namespaces=default \ policies=default \ ttl=1h ``` --- website/source/docs/auth/kubernetes.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/auth/kubernetes.html.md b/website/source/docs/auth/kubernetes.html.md index 8782db9aacea..c83f60426abe 100644 --- a/website/source/docs/auth/kubernetes.html.md +++ b/website/source/docs/auth/kubernetes.html.md @@ -111,7 +111,7 @@ login it first must be configured in a role. ``` vault write auth/kubernetes/role/demo \ - bound_service_account_names=vault-auth \ + bound_service_account_names=vault-auth \ bound_service_account_namespaces=default \ policies=default \ ttl=1h From 14b43deb0585da44bdd88535a5f1b71bd8f99d31 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Sat, 2 Dec 2017 14:18:23 -0500 Subject: [PATCH 04/18] Update cassandra docs with consistency value. Fixes #3361 --- website/source/api/secret/cassandra/index.html.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/website/source/api/secret/cassandra/index.html.md b/website/source/api/secret/cassandra/index.html.md index 5bfabb5df00e..17cb71dedc4e 100644 --- a/website/source/api/secret/cassandra/index.html.md +++ b/website/source/api/secret/cassandra/index.html.md @@ -62,6 +62,11 @@ Cassandra. - `connect_timeout` `(string: "5s")` – Specifies the connection timeout to use. +- `consistency` `(string: "")` – Specifies the consistency option to use. See + the [gocql + definition](https://github.com/gocql/gocql/blob/master/frame.go#L203) for + valid options. + TLS works as follows: - If `tls` is set to true, the connection will use TLS; this happens From 3b56130f10720552772aefed16e29c667774c94b Mon Sep 17 00:00:00 2001 From: Paul Pieralde Date: Mon, 4 Dec 2017 07:34:05 -0800 Subject: [PATCH 05/18] Fix docs for Transit API (#3588) --- website/source/api/secret/transit/index.html.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/source/api/secret/transit/index.html.md b/website/source/api/secret/transit/index.html.md index 2ad67ae85b53..01de3664a727 100644 --- a/website/source/api/secret/transit/index.html.md +++ b/website/source/api/secret/transit/index.html.md @@ -790,7 +790,7 @@ supports signing. Required if key derivation is enabled; currently only available with ed25519 keys. - - `prehashed` `(bool: false)` - Set to `true` when the input is already +- `prehashed` `(bool: false)` - Set to `true` when the input is already hashed. If the key type is `rsa-2048` or `rsa-4096`, then the algorithm used to hash the input should be indicated by the `algorithm` parameter. @@ -855,11 +855,11 @@ data. `/transit/hmac` function. Either this must be supplied or `signature` must be supplied. - - `context` `(string: "")` - Base64 encoded context for key derivation. +- `context` `(string: "")` - Base64 encoded context for key derivation. Required if key derivation is enabled; currently only available with ed25519 keys. - - `prehashed` `(bool: false)` - Set to `true` when the input is already +- `prehashed` `(bool: false)` - Set to `true` when the input is already hashed. If the key type is `rsa-2048` or `rsa-4096`, then the algorithm used to hash the input should be indicated by the `algorithm` parameter. From e2cdbf4913f46f1ea68e37d6e56bbcc616eb059b Mon Sep 17 00:00:00 2001 From: csawyerYumaed Date: Mon, 4 Dec 2017 07:51:16 -0800 Subject: [PATCH 06/18] update relatedtools, add Goldfish UI. (#3597) Add link to Goldfish a web UI for Vault. --- website/source/api/relatedtools.html.md | 1 + 1 file changed, 1 insertion(+) diff --git a/website/source/api/relatedtools.html.md b/website/source/api/relatedtools.html.md index cb109fc5f389..6b442eed3f3a 100644 --- a/website/source/api/relatedtools.html.md +++ b/website/source/api/relatedtools.html.md @@ -24,5 +24,6 @@ The following list of tools is maintained by the community of Vault users; Hashi * [vault-exec](https://github.com/kmanning/vault_exec) - a shell wrapper to execute arbitrary scripts using temporary AWS credentials managed by Vault * [pouch](https://github.com/tuenti/pouch) - A set of tools to manage provisioning of secrets on hosts based on the AppRole authentication method of Vault * [vault-aws-creds](https://github.com/jantman/vault-aws-creds) - Python helper to export Vault-provided temporary AWS creds into the environment +* [goldfish](https://github.com/Caiyeon/goldfish) - A Vault UI panel written with VueJS and Vault native Go API. Want to add your own project, or one that you use? Additions are welcome via [pull requests](https://github.com/hashicorp/vault/blob/master/website/source/api/relatedtools.html.md). From b94916c57041c6c98b5100941fdb7cb582a06f30 Mon Sep 17 00:00:00 2001 From: Chris White <30322216+mschriswhite@users.noreply.github.com> Date: Mon, 4 Dec 2017 07:52:30 -0800 Subject: [PATCH 07/18] Add command to example to register plugin (#3601) The example command to register the plugin into the plugin catalog was missing the command. From 9692cde57f0cf0f3143aba9853ba0829a28f89c7 Mon Sep 17 00:00:00 2001 From: crdotson Date: Mon, 4 Dec 2017 10:53:58 -0500 Subject: [PATCH 08/18] Fix spelling (#3609) changed "aomma" to "comma" --- website/source/api/secret/ssh/index.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/api/secret/ssh/index.html.md b/website/source/api/secret/ssh/index.html.md index 5b28c0454160..4ccd8b83b234 100644 --- a/website/source/api/secret/ssh/index.html.md +++ b/website/source/api/secret/ssh/index.html.md @@ -143,7 +143,7 @@ This endpoint creates or updates a named role. credentials can be created for any domain. See also `allow_bare_domains` and `allow_subdomains`. -- `key_option_specs` `(string: "")` – Specifies a aomma separated option +- `key_option_specs` `(string: "")` – Specifies a comma separated option specification which will be prefixed to RSA keys in the remote host's authorized_keys file. N.B.: Vault does not check this string for validity. From 0a53ea27bff8576ba492c21b42e0bec249242a61 Mon Sep 17 00:00:00 2001 From: Brian Shumate Date: Mon, 4 Dec 2017 10:56:16 -0500 Subject: [PATCH 09/18] Docs: mlock() notes, fixes #3605 (#3614) --- website/source/docs/configuration/index.html.md | 2 ++ website/source/guides/upgrading/index.html.md | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/website/source/docs/configuration/index.html.md b/website/source/docs/configuration/index.html.md index 7660e1a461c6..4694f38db20f 100644 --- a/website/source/docs/configuration/index.html.md +++ b/website/source/docs/configuration/index.html.md @@ -88,6 +88,8 @@ to specify where the configuration is. sudo setcap cap_ipc_lock=+ep $(readlink -f $(which vault)) ``` + If you use a Linux distribution with systemd, you can also add the above `setcap` command as an [ExecStartPre](https://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStartPre=) additional command in your Vault unit file to ensure that `mlock()` capability is added to the `vault` binary before executing. + - `plugin_directory` `(string: "")` – A directory from which plugins are allowed to be loaded. Vault must have permission to read files in this directory to successfully load plugins. diff --git a/website/source/guides/upgrading/index.html.md b/website/source/guides/upgrading/index.html.md index 24af3dbd4e53..811f4e09869b 100644 --- a/website/source/guides/upgrading/index.html.md +++ b/website/source/guides/upgrading/index.html.md @@ -63,7 +63,7 @@ active duty. To do this: If you kill Vault without letting it release the lock, a standby node will not be able to take over until the lock's timeout period has expired. This is backend-specific but could be ten seconds or more. -2. Replace the Vault binary with the new version +2. Replace the Vault binary with the new version; ensure that `mlock()` capability is added to the new binary with [setcap](https://www.vaultproject.io/docs/configuration/index.html#disable_mlock) 3. Start the node 4. Unseal the node (it will now be a standby) From effeb02afa0527be9d20a9e7ce4f7ca213ce2832 Mon Sep 17 00:00:00 2001 From: Chris Hoffman Date: Mon, 4 Dec 2017 11:23:58 -0500 Subject: [PATCH 10/18] Expanding on the quick start guide with how to set up an intermediate authority (#3622) --- website/source/docs/secrets/pki/index.html.md | 278 +++++++++++++++--- 1 file changed, 242 insertions(+), 36 deletions(-) diff --git a/website/source/docs/secrets/pki/index.html.md b/website/source/docs/secrets/pki/index.html.md index 1ac49044a9c2..ccf0c4769739 100644 --- a/website/source/docs/secrets/pki/index.html.md +++ b/website/source/docs/secrets/pki/index.html.md @@ -234,15 +234,15 @@ policy used to generate those credentials. For example, let's create an ```text $ vault write pki/roles/example-dot-com \ - allowed_domains="example.com" \ - allow_subdomains="true" max_ttl="72h" + allowed_domains=example.com \ + allow_subdomains=true max_ttl=72h Success! Data written to: pki/roles/example-dot-com ``` -#### Generate credentials +#### Issue Certificates By writing to the `roles/example-dot-com` path we are defining the -`example-dot-com` role. To generate a new set of credentials, we simply write +`example-dot-com` role. To generate a new certificate, we simply write to the `issue` endpoint with that role name: Vault is now configured to create and manage certificates! @@ -250,10 +250,241 @@ and manage certificates! $ vault write pki/issue/example-dot-com \ common_name=blah.example.com Key Value +certificate -----BEGIN CERTIFICATE----- +MIIDbDCCAlSgAwIBAgIUPiAyxq+nIE6xlWf7hrzLkPQxtvMwDQYJKoZIhvcNAQEL +BQAwMzExMC8GA1UEAxMoVmF1bHQgVGVzdGluZyBJbnRlcm1lZGlhdGUgU3ViIEF1 +dGhvcml0eTAeFw0xNjA5MjcwMDA5MTNaFw0xNjA5MjcwMTA5NDNaMBsxGTAXBgNV +BAMTEGJsYWguZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQDJAYB04IVdmSC/TimaA6BbXlvgBTZHL5wBUTmO4iHhenL0eDEXVe2Fd7Yq +75LiBJmcC96hKbqh5rwS8KwN9ElZI52/mSMC+IvoNlYHAf7shwfsjrVx3q7/bTFg +lz6wECn1ugysxynmMvgQD/pliRkxTQ7RMh4Qlh75YG3R9BHy9ZddklZp0aNaitts +0uufHnN1UER/wxBCZdWTUu34KDL9I6yE7Br0slKKHPdEsGlFcMkbZhvjslZ7DGvO +974S0qtOdKiawJZbpNPg0foGZ3AxesDUlkHmmgzUNes/sjknDYTHEfeXM6Uap0j6 +XvyhCxqdeahb/Vtibg0z9I0IusJbAgMBAAGjgY8wgYwwDgYDVR0PAQH/BAQDAgOo +MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU/5oy0rL7 +TT0wX7KZK7qcXqgayNwwHwYDVR0jBBgwFoAUgM37P8oXmA972ztLfw+b1eIY5now +GwYDVR0RBBQwEoIQYmxhaC5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEA +CT2vI6/taeLTw6ZulUhLXEXYXWZu1gF8n2COjZzbZXmHxQAoZ3GtnSNwacPHAyIj +f3cA9Moo552y39LUtWk+wgFtQokWGK7LXglLaveNUBowOHq/xk0waiIinJcgTG53 +Z/qnbJnTjAOG7JwVJplWUIiS1avCksrHt7heE2EGRGJALqyLZ119+PW6ogtCLUv1 +X8RCTw/UkIF/LT+sLF0bXWy4Hn38Gjwj1MVv1l76cEGOVSHyrYkN+6AMnAP58L5+ +IWE9tN3oac4x7jhbuNpfxazIJ8Q6l/Up5U5Evfbh6N1DI0/gFCP20fMBkHwkuLfZ +2ekZoSeCgFRDlHGkr7Vv9w== +-----END CERTIFICATE----- +issuing_ca -----BEGIN CERTIFICATE----- +MIIDijCCAnKgAwIBAgIUB28DoGwgGFKL7fbOu9S4FalHLn0wDQYJKoZIhvcNAQEL +BQAwLzEtMCsGA1UEAxMkVmF1bHQgVGVzdGluZyBJbnRlcm1lZGlhdGUgQXV0aG9y +aXR5MB4XDTE2MDkyNzAwMDgyMVoXDTI2MDkxNjE2MDg1MVowMzExMC8GA1UEAxMo +VmF1bHQgVGVzdGluZyBJbnRlcm1lZGlhdGUgU3ViIEF1dGhvcml0eTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBAOSCiSij4wy1wiMwvZt+rtU3IaO6ZTn9 +LfIPuGsR5/QSJk37pCZQco1LgoE/rTl+/xu3bDovyHDmgObghC6rzVOX2Tpi7kD+ +DOZpqxOsaS8ebYgxB/XJTSxyEJuSAcpSNLqqAiZivuQXdaD0N7H3Or0awwmKE9mD +I0g8CF4fPDmuuOG0ASn9fMqXVVt5tXtEqZ9yJYfNOXx3FOPjRVOZf+kvSc31wCKe +i/KmR0AQOmToKMzq988nLqFPTi9KZB8sEU20cGFeTQFol+m3FTcIru94EPD+nLUn +xtlLELVspYb/PP3VpvRj9b+DY8FGJ5nfSJl7Rkje+CD4VxJpSadin3kCAwEAAaOB +mTCBljAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU +gM37P8oXmA972ztLfw+b1eIY5nowHwYDVR0jBBgwFoAUj4YAIxRwrBy0QMRKLnD0 +kVidIuYwMwYDVR0RBCwwKoIoVmF1bHQgVGVzdGluZyBJbnRlcm1lZGlhdGUgU3Vi +IEF1dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAQEAA4buJuPNJvA1kiATLw1dVU2J +HPubk2Kp26Mg+GwLn7Vz45Ub133JCYfF3/zXLFZZ5Yub9gWTtjScrvNfQTAbNGdQ +BdnUlMmIRmfB7bfckhryR2R9byumeHATgNKZF7h8liNHI7X8tTzZGs6wPdXOLlzR +TlM3m1RNK8pbSPOkfPb06w9cBRlD8OAbNtJmuypXA6tYyiiMYBhP0QLAO3i4m1ns +aAjAgEjtkB1rQxW5DxoTArZ0asiIdmIcIGmsVxfDQIjFlRxAkafMs74v+5U5gbBX +wsOledU0fLl8KLq8W3OXqJwhGLK65fscrP0/omPAcFgzXf+L4VUADM4XhW6Xyg== +-----END CERTIFICATE----- +private_key -----BEGIN RSA PRIVATE KEY----- +MIIEpgIBAAKCAQEAyQGAdOCFXZkgv04pmgOgW15b4AU2Ry+cAVE5juIh4Xpy9Hgx +F1XthXe2Ku+S4gSZnAveoSm6oea8EvCsDfRJWSOdv5kjAviL6DZWBwH+7IcH7I61 +cd6u/20xYJc+sBAp9boMrMcp5jL4EA/6ZYkZMU0O0TIeEJYe+WBt0fQR8vWXXZJW +adGjWorbbNLrnx5zdVBEf8MQQmXVk1Lt+Cgy/SOshOwa9LJSihz3RLBpRXDJG2Yb +47JWewxrzve+EtKrTnSomsCWW6TT4NH6BmdwMXrA1JZB5poM1DXrP7I5Jw2ExxH3 +lzOlGqdI+l78oQsanXmoW/1bYm4NM/SNCLrCWwIDAQABAoIBAQCCbHMJY1Wl8eIJ +v5HG2WuHXaaHqVoavo2fXTDXwWryfx1v+zz/Q0YnQBH3shPAi/OQCTOfpw/uVWTb +dUZul3+wUyfcVmUdXGCLgBY53dWna8Z8e+zHwhISsqtDXV/TpelUBDCNO324XIIR +Cg0TLO4nyzQ+ESLo6D+Y2DTp8lBjMEkmKTd8CLXR2ycEoVykN98qPZm8keiLGO91 +I8K7aRd8uOyQ6HUfJRlzFHSuwaLReErxGTEPI4t/wVqh2nP2gGBsn3apiJ0ul6Jz +NlYO5PqiwpeDk4ibhQBpicnm1jnEcynH/WtGuKgMNB0M4SBRBsEguO7WoKx3o+qZ +iVIaPWDhAoGBAO05UBvyJpAcz/ZNQlaF0EAOhoxNQ3h6+6ZYUE52PgZ/DHftyJPI +Y+JJNclY91wn91Yk3ROrDi8gqhzA+2Lelxo1kuZDu+m+bpzhVUdJia7tZDNzRIhI +24eP2GdochooOZ0qjvrik4kuX43amBhQ4RHsBjmX5CnUlL5ZULs8v2xnAoGBANjq +VLAwiIIqJZEC6BuBvVYKaRWkBCAXvQ3j/OqxHRYu3P68PZ58Q7HrhrCuyQHTph2v +fzfmEMPbSCrFIrrMRmjUG8wopL7GjZjFl8HOBHFwzFiz+CT5DEC+IJIRkp4HM8F/ +PAzjB2wCdRdSjLTD5ph0/xQIg5xfln7D+wqU0QHtAoGBAKkLF0/ivaIiNftw0J3x +WxXag/yErlizYpIGCqvuzII6lLr9YdoViT/eJYrmb9Zm0HS9biCu2zuwDijRSBIL +RieyF40opUaKoi3+0JMtDwTtO2MCd8qaCH3QfkgqAG0tTuj1Q8/6F2JA/myKYamq +MMhhpYny9+7rAlemM8ZJIqtvAoGBAKOI3zpKDNCdd98A4v7B7H2usZUIJ7gOTZDo +XqiNyRENWb2PK6GNq/e6SrxvuclvyKA+zFnXULJoYtsj7tAH69lieGaOCc5uoRgZ +eBU7/euMj/McE6vEO3GgJawaJYCQi3uJMjvA+bp7i81+hehOfU5ZfmmbFaZSBoMh +u+U5Vu3tAoGBANnBIbHfD3E7rqnqdpH1oRRHLA1VdghzEKgyUTPHNDzPJG87RY3c +rRqeXepblud3qFjD60xS9BzcBijOvZ4+KHk6VIMpkyqoeNVFCJbBVCw+JGMp88+v +e9t+2iwryh5+rnq+pg6anmgwHldptJc1XEFZA2UUQ89RP7kOGQF6IkIS +-----END RSA PRIVATE KEY----- +private_key_type rsa +serial_number 3e:20:32:c6:af:a7:20:4e:b1:95:67:fb:86:bc:cb:90:f4:31:b6:f3 +``` + +Vault has now generated a new set of credentials using the `example-dot-com` +role configuration. Here we see the dynamically generated private key and +certificate. + +Using ACLs, it is possible to restrict using the pki backend such that trusted +operators can manage the role definitions, and both users and applications are +restricted in the credentials they are allowed to read. + +If you get stuck at any time, simply run `vault path-help pki` or with a +subpath for interactive help output. + +## Setting Up Intermediate CA + +In the Quick Start guide, certificates were issued directly from the root +certificate authority. As described in the example, this is not a recommended +practice. This guide builds on the previous guide's root certificate authority +and creates an intermediate authority using the root authority to sign the +intermediate's certificate. + +#### Mount the backend + +To add another certificate authority to our Vault instance, we have to mount it +at a different path. + +```text +$ vault mount pki -path=pki_int +Successfully mounted 'pki' at 'pki_int'! +``` + +#### Configure an Intermediate CA + +```text +$ vault mount-tune -max-lease-ttl=43800h pki_int +Successfully tuned mount 'pki_int'! +``` + +That sets the maximum TTL for secrets issued from the mount to 5 years. This +value should be less than or equal to the root certificate authority. + +Now, we generate our intermediate certificate signing request: + +```text +$ vault write pki_int/intermediate/generate/internal common_name="myvault.com Intermediate Authority" ttl=43800h +Key Value +csr -----BEGIN CERTIFICATE REQUEST----- +MIICsjCCAZoCAQAwLTErMCkGA1UEAxMibXl2YXVsdC5jb20gSW50ZXJtZWRpYXRl +IEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJU1Qh8l +BW16WHAu34Fy92FnSy4219WVlKw1xwpKxjd95xH6WcxXozOs6oHFQ9c592bz51F8 +KK3FFJYraUrGONI5Cz9qHbzC1mFCmjnXVXCoeNKIzEBG0Y+ehH7MQ1SvDCyvaJPX +ItFXaGf6zENiGsApw3Y3lFr0MjPzZDBH1p4Nq3aA6L2BaxvO5vczdQl5tE2ud/zs +GIdCWnl1ThDEeiX1Ppduos/dx3gaZa9ly3iCuDMKIL9yK5XTBTgKB6ALPApekLQB +kcUFbOuMzjrDSBe9ytu65yICYp26iAPPA8aKTj5cUgscgzEvQS66rSAVG/unrWxb +wbl8b7eQztCmp60CAwEAAaBAMD4GCSqGSIb3DQEJDjExMC8wLQYDVR0RBCYwJIIi +bXl2YXVsdC5jb20gSW50ZXJtZWRpYXRlIEF1dGhvcml0eTANBgkqhkiG9w0BAQsF +AAOCAQEAZA9A1QvTdAd45+Ay55FmKNWnis1zLjbmWNJURUoDei6i6SCJg0YGX1cZ +WkD0ibxPYihSsKRaIUwC2bE8cxZM57OSs7ISUmyPQAT2IHTHvuGK72qlFRBlFOzg +SHEG7gfyKdrALphyF8wM3u4gXhcnY3CdltjabL3YakZqd3Ey4870/0XXeo5c4k7w +/+n9M4xED4TnXYCGfLAlu5WWKSeCvu9mHXnJcLo1MiYjX7KGey/xYYbfxHSPm4ul +tI6Vf59zDRscfNmq37fERD3TiKP0QZNGTSRvnrxrx2RUQGXFywM8l4doG8nS5BxU +2jP20cdv0lJFvHr9663/8B/+F5L6Yw== +-----END CERTIFICATE REQUEST----- +``` + +Take the signing request from the intermediate authority and sign it using +another certificate authority, in this case the root certificate authority +generated in the first example. + +```text +$ vault write pki/root/sign-intermediate csr=@pki_int.csr format=pem_bundle +Key Value +certificate -----BEGIN CERTIFICATE----- +MIIDZTCCAk2gAwIBAgIUENxQD7KIJi1zE/jEiYqAG1VC4NwwDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAxMLbXl2YXVsdC5jb20wHhcNMTcxMTI4MTcwNzIzWhcNMjIx +MTI3MTcwNzUzWjAtMSswKQYDVQQDEyJteXZhdWx0LmNvbSBJbnRlcm1lZGlhdGUg +QXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5seNV4Yd +uCMX0POUUuSzCBiR3Cyf9b9tGsCX7UfvZmjPs+Fl/X+Ovq6UtHM9RuTGlyfFrCWy +pflO7mc0H8PBzlvhv1WQet5aRyUOXkG6iYmooG9iobIY8z/TZCaCF605pgygfOaS +DIlwOdJkfiXxGpQ00pfIwe/Y2OK2I5e36u0E2EA6kXvcfexLjQGFPbod+H0R29Ro +/GwOJ6MpSHqB77mF025x1y08EtqT1z1kFCiDzFSkzNZEZYWljhDS6ZRY9ctzKufm +5CkUwmvCVRI2CivDJvmfhXyv0DRoq4IhYdJHo179RSObq3BY9f9LQ0balNLiM0Ft +O8f0urTqUAbySwIDAQABo4GTMIGQMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBSQgTfcMrKYzyckP6t/0iVQkl0ZBDAfBgNVHSMEGDAW +gBRccsCARqs3wQDjW7JMNXS6pWlFSDAtBgNVHREEJjAkgiJteXZhdWx0LmNvbSBJ +bnRlcm1lZGlhdGUgQXV0aG9yaXR5MA0GCSqGSIb3DQEBCwUAA4IBAQABNg2HxccY +DwRpsJ+sxA0BgDyF+tYtOlXViVNv6Z+nOU0nNhQSCjfzjYWmBg25nfKaFhQSC3b7 +fIW+e7it/FLVrCgaqdysoxljqhR0gXMAy8S/ubmskPWjJiKauJB5bfB59Uf2GP6j +zimZDu6WjWvvgkKcJqJEbOOS9DWBvCTdmmml1NMXZtcytpod2Y7mxninqNRx3qpx +Pst4vgAbyM/3zLSzkyUD+MXIyRXwxktFlyEYBHvMd9OoHzLO6WLxk22FyQQ+w4by +NfXJY4r5pj6a4lJ6pPuqyfBhidYMTdY3AI7w/QRGk4qQv1iDmnZspk2AxdbR5Lwe +YmChIML/f++S +-----END CERTIFICATE----- +expiration 1669568873 +issuing_ca -----BEGIN CERTIFICATE----- +MIIDNTCCAh2gAwIBAgIUdR44qhhyh3CZjnCtflGKQlTI8NswDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAxMLbXl2YXVsdC5jb20wHhcNMTcxMTI4MTYxODA2WhcNMjcx +MTI2MTYxODM1WjAWMRQwEgYDVQQDEwtteXZhdWx0LmNvbTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBANTPnQ2CUkuLrYT4V6/IIK/gWFZXFG4lWTmgM5Zh +PDquMhLEikZCbZKbupouBI8MOr5i8tycENaTnSs9dBwVEOWAHbLkliVgvCKgLi0F +PfPM87FnBoKVctO2ip8AdmYcAt/wc096dWBG6eKLVP5xsAe7NcYDtF/inHgEZ22q +ZjGVEyC6WntIASgULoHGgHakPp1AHLhGm8nL5YbusWY7RgZIlNeGWLVoneG0pxdV +7W1SPO67dsQyq58mTxMIGVUj5YE1q7/C6OhCTnAHc+sRm0oUehPfO8kY4NHpCJGv +nDRdJi6k6ewk94c0KK2tUUM/TN6ZSRfx6ccgfPH8zNcVPVcCAwEAAaN7MHkwDgYD +VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFxywIBGqzfB +AONbskw1dLqlaUVIMB8GA1UdIwQYMBaAFFxywIBGqzfBAONbskw1dLqlaUVIMBYG +A1UdEQQPMA2CC215dmF1bHQuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQBgvsgpBuVR +iKVdXXpFyoQLImuoaHZgaj5tuUDqnMoxOA1XWW6SVlZmGfDQ7+u5NBkp2cGSDRGm +ARHJTeURvdZIwdFdGkNqfAZjutRjjQOnXgS65ujZd7AnlZq1v0ZOZqVVk9YEOhOe +Rh2MjnHGNuiLBib1YNQHNuRef1mPwIE2Gm/Tz/z3JPHtkKNIKbn60zHrIIM/OT2Z +HYjcMUcqXtKGYfNjVspJm3lSDUoyJdaq80Afmy2Ez1Vt9crGG3Dj8mgs59lEhEyo +MDVhOP116M5HJfQlRPVd29qS8pFrjBvXKjJSnJNG1UFdrWBJRJ3QrBxUQALKrJlR +g5lvTeymHjS/ +-----END CERTIFICATE----- +serial_number 10:dc:50:0f:b2:88:26:2d:73:13:f8:c4:89:8a:80:1b:55:42:e0:dc +``` + +Now set the intermediate certificate authorities signing certificate to the +root-signed certificate. + +```text +$ vault write pki_int/intermediate/set-signed certificate=@signed_certificate.pem +Success! Data written to: pki_int/intermediate/set-signed +``` + +The intermediate certificate authority is now configured and ready to issue +certificates. + +#### Set URL configuration + +Generated certificates can have the CRL location and the location of the +issuing certificate encoded. These values must be set manually, but can be +changed at any time. + +```text +$ vault write pki_int/config/urls issuing_certificates="http://127.0.0.1:8200/v1/pki_int/ca" crl_distribution_points="http://127.0.0.1:8200/v1/pki_int/crl" +Success! Data written to: pki_int/ca/urls +``` + +#### Configure a role + +The next step is to configure a role. A role is a logical name that maps to a +policy used to generate those credentials. For example, let's create an +"example-dot-com" role: + +```text +$ vault write pki_int/roles/example-dot-com \ + allowed_domains=example.com \ + allow_subdomains=true max_ttl=72h +Success! Data written to: pki_int/roles/example-dot-com +``` + +#### Issue Certificates + +By writing to the `roles/example-dot-com` path we are defining the +`example-dot-com` role. To generate a new certificate, we simply write +to the `issue` endpoint with that role name: Vault is now configured to create +and manage certificates! + +```text +$ vault write pki_int/issue/example-dot-com \ + common_name=blah.example.com +Key Value --- ----- -lease_id pki/issue/example-dot-com/6d8ab3e2-ce31-8821-81e4-740a498af51d -lease_duration 259199 -lease_renewable false certificate -----BEGIN CERTIFICATE----- MIIDbDCCAlSgAwIBAgIUPiAyxq+nIE6xlWf7hrzLkPQxtvMwDQYJKoZIhvcNAQEL BQAwMzExMC8GA1UEAxMoVmF1bHQgVGVzdGluZyBJbnRlcm1lZGlhdGUgU3ViIEF1 @@ -316,26 +547,6 @@ BdnUlMmIRmfB7bfckhryR2R9byumeHATgNKZF7h8liNHI7X8tTzZGs6wPdXOLlzR TlM3m1RNK8pbSPOkfPb06w9cBRlD8OAbNtJmuypXA6tYyiiMYBhP0QLAO3i4m1ns aAjAgEjtkB1rQxW5DxoTArZ0asiIdmIcIGmsVxfDQIjFlRxAkafMs74v+5U5gbBX wsOledU0fLl8KLq8W3OXqJwhGLK65fscrP0/omPAcFgzXf+L4VUADM4XhW6Xyg== ------END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIIDejCCAmKgAwIBAgIUDXJyQ1uJPF5ridDOCvGtVF1F8HUwDQYJKoZIhvcNAQEL -BQAwJzElMCMGA1UEAxMcVmF1bHQgVGVzdGluZyBSb290IEF1dGhvcml0eTAeFw0x -NjA5MjcwMDA4MjBaFw0yNjA5MjAyMDA4NTBaMC8xLTArBgNVBAMTJFZhdWx0IFRl -c3RpbmcgSW50ZXJtZWRpYXRlIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAKHsRTw3aShwDTbywK7AeXNvz7IrmdOLAsd+svDdIUn/4kWQ -lAy4uXYncQc/V9bqLjza3tflK7otXT+V5GjbK+WpW5WSp8LkVhKdLRWOnPWJEC+B -nOucmLR0mFQF1W4Bfx0fYYCLdN/YbjSevPmA0UzlIN/pdQQoxUIvraTHPNBar94K -zmlMu06qAvl27LXYUE3nAhQaRGq4M39WbAUtRsNKaTU72qTpMsstpnBB1QBT2m2U -44twFpXZAgfR/hSqcA4NegPWmB5l+E2GhYfihOhVcnFaH2tgXb4MOMUyRH1hNdgZ -28K5G1ILt2+Rp+NSosA0LI3pV490SJfAxuc0tsUCAwEAAaOBlTCBkjAOBgNVHQ8B -Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUj4YAIxRwrBy0QMRK -LnD0kVidIuYwHwYDVR0jBBgwFoAULNIU30rP+wMVelJMFNyDtxgtq04wLwYDVR0R -BCgwJoIkVmF1bHQgVGVzdGluZyBJbnRlcm1lZGlhdGUgQXV0aG9yaXR5MA0GCSqG -SIb3DQEBCwUAA4IBAQCOjH2n8H1Q5KpaWTm378FKd2YY1nzI/nCwjAQX96VcJUrZ -W1ofPsTcCASQKwo3HC2ayV46DMiKoJWI+xOux2N+S9uVd+SC4ZloFzSER8cCDRRk -huVra+cAaljnkJVb4Ojv6vHnXljx9NrcW6KzJzwMf1HzewyG+P1EjD4/kcA5r0Gw -vuzGXMXmjMATf0LZlklDOHkNLtvnLS8axbXI05TlHIj9y9Y+aQyFYebwip+ZXYju -pIJFswrsCk5e2G6+UmhV81JH29IvjBi4POgqm2+mrGz5xS/i6flcs/8pn01jlDpC -knj9MxY9j42z2BKkhHayyuOa0BQm0TTu4S2fhajl -----END CERTIFICATE-----] private_key -----BEGIN RSA PRIVATE KEY----- MIIEpgIBAAKCAQEAyQGAdOCFXZkgv04pmgOgW15b4AU2Ry+cAVE5juIh4Xpy9Hgx @@ -370,15 +581,10 @@ serial_number 3e:20:32:c6:af:a7:20:4e:b1:95:67:fb:86:bc:cb:90:f4:31:b6:f3 Vault has now generated a new set of credentials using the `example-dot-com` role configuration. Here we see the dynamically generated private key and -certificate. The issuing CA certificate and CA trust chain is returned as well. - -Using ACLs, it is possible to restrict using the pki backend such that trusted -operators can manage the role definitions, and both users and applications are -restricted in the credentials they are allowed to read. - -If you get stuck at any time, simply run `vault path-help pki` or with a -subpath for interactive help output. - +certificate. The issuing CA certificate and CA trust chain are returned as well. +The CA Chain returns all the intermediate authorities in the trust chain. The root +authority is not included since that will usually be trusted by the underlying +OS. ## API From a898bd272dc839cbf23eb4ec2264259274852a43 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Mon, 4 Dec 2017 08:25:16 -0800 Subject: [PATCH 11/18] Remove beta notice --- website/source/api/system/policies.html.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/website/source/api/system/policies.html.md b/website/source/api/system/policies.html.md index bf3a3e7c063c..4786830cc47e 100644 --- a/website/source/api/system/policies.html.md +++ b/website/source/api/system/policies.html.md @@ -6,19 +6,12 @@ description: |- The `/sys/policies/` endpoints are used to manage ACL, RGP, and EGP policies in Vault. --- -# NOTE: Only in 0.9 Betas - -Please note that this endpoint is only available in 0.9 beta releases of Vault -at this time. - # `/sys/policies/` The `/sys/policies` endpoints are used to manage ACL, RGP, and EGP policies in Vault. Note: RGPs and EGPs are Vault Enterprise Premium features, and the associated endpoints are not available in Vault Open Source or Vault Enterprise Pro. -In addition, `/sys/policies/acl` will be available in an upcoming Vault Open Source/Vault Enterprise Pro release, but not until Sentinel exits beta. - ## List ACL Policies This endpoint lists all configured ACL policies. From 063f3d575eb9a2fabf754d32ac6bd263d6249d94 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Mon, 4 Dec 2017 12:05:34 -0500 Subject: [PATCH 12/18] Update secrets page Fixes #3623 --- website/source/docs/secrets/index.html.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/website/source/docs/secrets/index.html.md b/website/source/docs/secrets/index.html.md index a4bb48449946..aefb0c6d736c 100644 --- a/website/source/docs/secrets/index.html.md +++ b/website/source/docs/secrets/index.html.md @@ -15,8 +15,7 @@ Some secret backends, such as "kv", simply store and read secrets verbatim. Other secret backends, such as "aws", create _dynamic secrets_: secrets that are made on demand. -Secret backends are part of the -[mount system](#) +Secret backends are part of the mount system in Vault. They behave very similarly to a virtual filesystem: any read/write/delete is sent to the secret backend, and the secret backend can choose to react to that operation however it sees fit. From 61eac778ccade2091e2407854fdfbd1ce136e2b9 Mon Sep 17 00:00:00 2001 From: Brian Shumate Date: Mon, 4 Dec 2017 12:10:26 -0500 Subject: [PATCH 13/18] Docs: Update /sys/policies/ re: beta refs to address #3624 (#3629) --- website/source/api/system/policies.html.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/website/source/api/system/policies.html.md b/website/source/api/system/policies.html.md index 4786830cc47e..4a502864cafb 100644 --- a/website/source/api/system/policies.html.md +++ b/website/source/api/system/policies.html.md @@ -10,7 +10,8 @@ description: |- The `/sys/policies` endpoints are used to manage ACL, RGP, and EGP policies in Vault. -Note: RGPs and EGPs are Vault Enterprise Premium features, and the associated endpoints are not available in Vault Open Source or Vault Enterprise Pro. + +~> **NOTE**: This endpoint is only available in Vault version 0.9+. Please also note that RGPs and EGPs are Vault Enterprise Premium features and the associated endpoints are not available in Vault Open Source or Vault Enterprise Pro. ## List ACL Policies From 291edb9746750075868958db3e659b26105165ed Mon Sep 17 00:00:00 2001 From: Laura Uva Date: Mon, 4 Dec 2017 09:12:58 -0800 Subject: [PATCH 14/18] Update example payload and response for pem_keys field which needs \n after header and before footer in order to be accepted as a valid RSA or ECDSA public key (#3632) --- website/source/api/auth/kubernetes/index.html.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/website/source/api/auth/kubernetes/index.html.md b/website/source/api/auth/kubernetes/index.html.md index 955d587a2eee..8f2f8066f43a 100644 --- a/website/source/api/auth/kubernetes/index.html.md +++ b/website/source/api/auth/kubernetes/index.html.md @@ -46,7 +46,7 @@ access the Kubernetes API. { "kubernetes_host": "https://192.168.99.100:8443", "kubernetes_ca_cert": "-----BEGIN CERTIFICATE-----.....-----END CERTIFICATE-----", - "pem_keys": "-----BEGIN CERTIFICATE-----.....-----END CERTIFICATE-----" + "pem_keys": "-----BEGIN CERTIFICATE-----\n.....\n-----END CERTIFICATE-----" } ``` @@ -83,7 +83,9 @@ $ curl \ "data":{ "kubernetes_host": "https://192.168.99.100:8443", "kubernetes_ca_cert": "-----BEGIN CERTIFICATE-----.....-----END CERTIFICATE-----", - "pem_keys": "-----BEGIN CERTIFICATE-----.....-----END CERTIFICATE-----" + "pem_keys": "-----BEGIN CERTIFICATE----- + ..... + -----END CERTIFICATE-----" }, ... } From ee89aa1e3b6376f280817ccd0ff4a46e879e72cd Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Mon, 4 Dec 2017 12:47:05 -0500 Subject: [PATCH 15/18] allowed/disallowed_policies as TypeCommaStringSlice (#3641) Our docs apparently claim that this is a list, but the code is string-only. This fixes that discrepancy. --- CHANGELOG.md | 10 ++++++++++ vault/token_store.go | 18 ++++++++---------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a4cd4217758..7b572a3310e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,17 @@ ## 0.9.1 (Unreleased) +DEPRECATIONS/CHANGES: + + * Token Auth Backend Roles parameter types: For `allowed_policies` and + `disallowed_policies` in role definitions in the token auth backend, input + can now be a comma-separated string or an array of strings. Reading a role + will now return arrays for these parameters. + IMPROVEMENTS: + * auth/token: `allowed_policies` and `disallowed_policies` can now be + specified as a comma-separated string or an array of strings + BUG FIXES: * database/mysql: Allow the creation statement to use commands that are not diff --git a/vault/token_store.go b/vault/token_store.go index b72fba6fad4c..d989393711c8 100644 --- a/vault/token_store.go +++ b/vault/token_store.go @@ -178,14 +178,12 @@ func NewTokenStore(c *Core, config *logical.BackendConfig) (*TokenStore, error) }, "allowed_policies": &framework.FieldSchema{ - Type: framework.TypeString, - Default: "", + Type: framework.TypeCommaStringSlice, Description: tokenAllowedPoliciesHelp, }, "disallowed_policies": &framework.FieldSchema{ - Type: framework.TypeString, - Default: "", + Type: framework.TypeCommaStringSlice, Description: tokenDisallowedPoliciesHelp, }, @@ -2465,18 +2463,18 @@ func (ts *TokenStore) tokenStoreRoleCreateUpdate( return logical.ErrorResponse(fmt.Sprintf("error registering path suffix: %s", consts.ErrPathContainsParentReferences)), nil } - allowedPoliciesStr, ok := data.GetOk("allowed_policies") + allowedPoliciesRaw, ok := data.GetOk("allowed_policies") if ok { - entry.AllowedPolicies = policyutil.SanitizePolicies(strings.Split(allowedPoliciesStr.(string), ","), policyutil.DoNotAddDefaultPolicy) + entry.AllowedPolicies = policyutil.SanitizePolicies(allowedPoliciesRaw.([]string), policyutil.DoNotAddDefaultPolicy) } else if req.Operation == logical.CreateOperation { - entry.AllowedPolicies = policyutil.SanitizePolicies(strings.Split(data.Get("allowed_policies").(string), ","), policyutil.DoNotAddDefaultPolicy) + entry.AllowedPolicies = policyutil.SanitizePolicies(data.Get("allowed_policies").([]string), policyutil.DoNotAddDefaultPolicy) } - disallowedPoliciesStr, ok := data.GetOk("disallowed_policies") + disallowedPoliciesRaw, ok := data.GetOk("disallowed_policies") if ok { - entry.DisallowedPolicies = strutil.ParseDedupLowercaseAndSortStrings(disallowedPoliciesStr.(string), ",") + entry.DisallowedPolicies = strutil.RemoveDuplicates(disallowedPoliciesRaw.([]string), true) } else if req.Operation == logical.CreateOperation { - entry.DisallowedPolicies = strutil.ParseDedupLowercaseAndSortStrings(data.Get("disallowed_policies").(string), ",") + entry.DisallowedPolicies = strutil.RemoveDuplicates(data.Get("disallowed_policies").([]string), true) } // Store it From 208dc5583050abb694983112370930a9a1a7433c Mon Sep 17 00:00:00 2001 From: Calvin Leung Huang Date: Tue, 5 Dec 2017 12:01:35 -0500 Subject: [PATCH 16/18] Clarify api_addr related errors on VaultPluginTLSProvider (#3620) * Mention api_addr on VaultPluginTLSProvider logs, update docs * Clarify message and mention automatic api_address detection * Change error message to use api_addr * Change error messages to use api_addr --- helper/pluginutil/tls.go | 8 ++++---- website/source/docs/configuration/index.html.md | 8 +++++--- website/source/docs/internals/plugins.html.md | 7 +++++++ website/source/docs/plugin/index.html.md | 7 +++++++ 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/helper/pluginutil/tls.go b/helper/pluginutil/tls.go index 112d33cf0508..99278dba6737 100644 --- a/helper/pluginutil/tls.go +++ b/helper/pluginutil/tls.go @@ -146,19 +146,19 @@ func VaultPluginTLSProvider(apiTLSConfig *api.TLSConfig) func() (*tls.Config, er addrRaw := wt.Claims().Get("addr") if addrRaw == nil { - return nil, errors.New("decoded token does not contain primary cluster address") + return nil, errors.New("decoded token does not contain the active node's api_addr") } vaultAddr, ok := addrRaw.(string) if !ok { - return nil, errors.New("decoded token's address not valid") + return nil, errors.New("decoded token's api_addr not valid") } if vaultAddr == "" { - return nil, errors.New(`no address for the vault found`) + return nil, errors.New(`no vault api_addr found`) } // Sanity check the value if _, err := url.Parse(vaultAddr); err != nil { - return nil, fmt.Errorf("error parsing the vault address: %s", err) + return nil, fmt.Errorf("error parsing the vault api_addr: %s", err) } // Unwrap the token diff --git a/website/source/docs/configuration/index.html.md b/website/source/docs/configuration/index.html.md index 4694f38db20f..97e89063f569 100644 --- a/website/source/docs/configuration/index.html.md +++ b/website/source/docs/configuration/index.html.md @@ -121,9 +121,10 @@ to specify where the configuration is. The following parameters are used on backends that support [high availability][high-availability]. -- `api_addr` `(string: "")` - Specifies the address (full URL) to - advertise to other Vault servers in the cluster for client redirection. This - can also be provided via the environment variable `VAULT_API_ADDR`. +- `api_addr` `(string: "")` - Specifies the address (full URL) to advertise to + other Vault servers in the cluster for client redirection. This value is also + used for [plugin backends][plugins]. This can also be provided via the + environment variable `VAULT_API_ADDR`. - `cluster_addr` `(string: "")` - – Specifies the address to advertise to other Vault servers in the cluster for request forwarding. This can also be provided @@ -141,3 +142,4 @@ The following parameters are used on backends that support [high availability][h [sealwrap]: /docs/enterprise/sealwrap/index.html [telemetry]: /docs/configuration/telemetry.html [high-availability]: /docs/concepts/ha.html +[plugins]: /docs/plugin/index.html \ No newline at end of file diff --git a/website/source/docs/internals/plugins.html.md b/website/source/docs/internals/plugins.html.md index 6f0d8addf73d..bcd4f7f099fb 100644 --- a/website/source/docs/internals/plugins.html.md +++ b/website/source/docs/internals/plugins.html.md @@ -32,6 +32,11 @@ plugin process' environment. This token is single use and has a short TTL. Once unwrapped, it provides the plugin with a uniquely generated TLS certificate and private key for it to use to talk to the original vault process. +The [`api_addr`][api_addr] must be set in order for the plugin process establish +communication with the Vault server during mount time. If the storage backend +has HA enabled and supports automatic host address detection (e.g. Consul), +Vault will automatically attempt to determine the `api_addr` as well. + ~> Note: Reading the original connection's TLS connection state is not supported in plugins. @@ -125,3 +130,5 @@ func main() { And that's basically it! You would just need to change MyPlugin to your actual plugin. + +[api_addr]: /docs/configuration/index.html#api_addr \ No newline at end of file diff --git a/website/source/docs/plugin/index.html.md b/website/source/docs/plugin/index.html.md index 096eb9e3c2d1..066b07a5d505 100644 --- a/website/source/docs/plugin/index.html.md +++ b/website/source/docs/plugin/index.html.md @@ -11,6 +11,11 @@ description: |- Plugin backends are the components in Vault that can be implemented separately from Vault's builtin backends. These backends can be either authentication or secret backends. +The [`api_addr`][api_addr] must be set in order for the plugin process establish +communication with the Vault server during mount time. If the storage backend +has HA enabled and supports automatic host address detection (e.g. Consul), +Vault will automatically attempt to determine the `api_addr` as well. + Detailed information regarding the plugin system can be found in the [internals documentation](https://www.vaultproject.io/docs/internals/plugins.html). @@ -40,3 +45,5 @@ Unmounting a plugin backend is the identical to unmounting internal backends: ``` $ vault unmount my-secrets ``` + +[api_addr]: /docs/configuration/index.html#api_addr \ No newline at end of file From a9e7dbb7b43c9b9a716ead4e69e59d938e0ffca7 Mon Sep 17 00:00:00 2001 From: Calvin Leung Huang Date: Tue, 5 Dec 2017 15:31:01 -0500 Subject: [PATCH 17/18] Support MongoDB session-wide write concern (#3646) * Initial work on write concern support, set for the lifetime of the session * Add base64 encoded value support, include docs and tests * Handle error from json.Unmarshal, fix test and docs * Remove writeConcern struct, move JSON unmarshal to Initialize * Return error on empty mapping of write_concern into mgo.Safe struct --- .../database/mongodb/connection_producer.go | 33 +++++++++++++++ plugins/database/mongodb/mongodb_test.go | 40 +++++++++++++++++++ .../api/secret/databases/mongodb.html.md | 21 +++++++--- 3 files changed, 89 insertions(+), 5 deletions(-) diff --git a/plugins/database/mongodb/connection_producer.go b/plugins/database/mongodb/connection_producer.go index f802dc35e5aa..a9ff64a943fa 100644 --- a/plugins/database/mongodb/connection_producer.go +++ b/plugins/database/mongodb/connection_producer.go @@ -2,6 +2,8 @@ package mongodb import ( "crypto/tls" + "encoding/base64" + "encoding/json" "errors" "fmt" "net" @@ -21,10 +23,12 @@ import ( // interface for databases to make connections. type mongoDBConnectionProducer struct { ConnectionURL string `json:"connection_url" structs:"connection_url" mapstructure:"connection_url"` + WriteConcern string `json:"write_concern" structs:"write_concern" mapstructure:"write_concern"` Initialized bool Type string session *mgo.Session + safe *mgo.Safe sync.Mutex } @@ -42,6 +46,30 @@ func (c *mongoDBConnectionProducer) Initialize(conf map[string]interface{}, veri return fmt.Errorf("connection_url cannot be empty") } + if c.WriteConcern != "" { + input := c.WriteConcern + + // Try to base64 decode the input. If successful, consider the decoded + // value as input. + inputBytes, err := base64.StdEncoding.DecodeString(input) + if err == nil { + input = string(inputBytes) + } + + concern := &mgo.Safe{} + err = json.Unmarshal([]byte(input), concern) + if err != nil { + return fmt.Errorf("error mashalling write_concern: %s", err) + } + + // Guard against empty, non-nil mgo.Safe object; we don't want to pass that + // into mgo.SetSafe in Connection(). + if (mgo.Safe{} == *concern) { + return fmt.Errorf("provided write_concern values did not map to any mgo.Safe fields") + } + c.safe = concern + } + // Set initialized to true at this point since all fields are set, // and the connection can be established at a later time. c.Initialized = true @@ -78,6 +106,11 @@ func (c *mongoDBConnectionProducer) Connection() (interface{}, error) { if err != nil { return nil, err } + + if c.safe != nil { + c.session.SetSafe(c.safe) + } + c.session.SetSyncTimeout(1 * time.Minute) c.session.SetSocketTimeout(1 * time.Minute) diff --git a/plugins/database/mongodb/mongodb_test.go b/plugins/database/mongodb/mongodb_test.go index 95f6e90888c3..4c1eacb66cb5 100644 --- a/plugins/database/mongodb/mongodb_test.go +++ b/plugins/database/mongodb/mongodb_test.go @@ -16,6 +16,8 @@ import ( const testMongoDBRole = `{ "db": "admin", "roles": [ { "role": "readWrite" } ] }` +const testMongoDBWriteConcern = `{ "wmode": "majority", "wtimeout": 5000 }` + func prepareMongoDBTestContainer(t *testing.T) (cleanup func(), retURL string) { if os.Getenv("MONGODB_URL") != "" { return func() {}, os.Getenv("MONGODB_URL") @@ -129,6 +131,44 @@ func TestMongoDB_CreateUser(t *testing.T) { } } +func TestMongoDB_CreateUser_writeConcern(t *testing.T) { + cleanup, connURL := prepareMongoDBTestContainer(t) + defer cleanup() + + connectionDetails := map[string]interface{}{ + "connection_url": connURL, + "write_concern": testMongoDBWriteConcern, + } + + dbRaw, err := New() + if err != nil { + t.Fatalf("err: %s", err) + } + db := dbRaw.(*MongoDB) + err = db.Initialize(connectionDetails, true) + if err != nil { + t.Fatalf("err: %s", err) + } + + statements := dbplugin.Statements{ + CreationStatements: testMongoDBRole, + } + + usernameConfig := dbplugin.UsernameConfig{ + DisplayName: "test", + RoleName: "test", + } + + username, password, err := db.CreateUser(statements, usernameConfig, time.Now().Add(time.Minute)) + if err != nil { + t.Fatalf("err: %s", err) + } + + if err := testCredsExist(t, connURL, username, password); err != nil { + t.Fatalf("Could not connect with new credentials: %s", err) + } +} + func TestMongoDB_RevokeUser(t *testing.T) { cleanup, connURL := prepareMongoDBTestContainer(t) defer cleanup() diff --git a/website/source/api/secret/databases/mongodb.html.md b/website/source/api/secret/databases/mongodb.html.md index 48a8ae2c401d..0d4857b6828b 100644 --- a/website/source/api/secret/databases/mongodb.html.md +++ b/website/source/api/secret/databases/mongodb.html.md @@ -20,10 +20,17 @@ has a number of parameters to further configure a connection. | Method | Path | Produces | | :------- | :--------------------------- | :--------------------- | -| `POST` | `/database/config/:name` | `204 (empty body)` | +| `POST` | `/database/config/:name` | `204 (empty body)` | ### Parameters -- `connection_url` `(string: )` – Specifies the MongoDB standard connection string (URI). + +- `connection_url` `(string: )` – Specifies the MongoDB standard + connection string (URI). +- `write_concern` `(string: "")` - Specifies the MongoDB [write + concern][mongodb-write-concern]. This is set for the entirety of the session, + maintained for the lifecycle of the plugin process. Must be a serialized JSON + object, or a base64-encoded serialized JSON object. The JSON payload values + map to the values in the [Safe][mgo-safe] struct from the mgo driver. ### Sample Payload @@ -31,7 +38,8 @@ has a number of parameters to further configure a connection. { "plugin_name": "mongodb-database-plugin", "allowed_roles": "readonly", - "connection_url": "mongodb://admin:Password!@mongodb.acme.com:27017/admin?ssl=true" + "connection_url": "mongodb://admin:Password!@mongodb.acme.com:27017/admin?ssl=true", + "write_concern": "{ \"wmode\": \"majority\", \"wtimeout\": 5000 }" } ``` @@ -68,7 +76,7 @@ list the plugin does not support that statement type. [MongoDB's documentation](https://docs.mongodb.com/manual/reference/method/db.createUser/). - `revocation_statements` `(string: "")` – Specifies the database statements to - be executed to revoke a user. Must be a serialized JSON object, or a base64-encoded + be executed to revoke a user. Must be a serialized JSON object, or a base64-encoded serialized JSON object. The object can optionally contain a "db" string. If no "db" value is provided, it defaults to the "admin" database. @@ -84,4 +92,7 @@ list the plugin does not support that statement type. } ] } -``` \ No newline at end of file +``` + +[mongodb-write-concern]: https://docs.mongodb.com/manual/reference/write-concern/ +[mgo-safe]: https://godoc.org/gopkg.in/mgo.v2#Safe \ No newline at end of file From f4b2e5269286d29f8903f90095eb7140b12df2e8 Mon Sep 17 00:00:00 2001 From: Calvin Leung Huang Date: Tue, 5 Dec 2017 15:44:08 -0500 Subject: [PATCH 18/18] changelog++ --- CHANGELOG.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b572a3310e8..7815f6cf9f71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,17 +5,21 @@ DEPRECATIONS/CHANGES: * Token Auth Backend Roles parameter types: For `allowed_policies` and `disallowed_policies` in role definitions in the token auth backend, input can now be a comma-separated string or an array of strings. Reading a role - will now return arrays for these parameters. + will now return arrays for these parameters. IMPROVEMENTS: - * auth/token: `allowed_policies` and `disallowed_policies` can now be - specified as a comma-separated string or an array of strings + * auth/token: `allowed_policies` and `disallowed_policies` can now be specified + as a comma-separated string or an array of strings [GH-3641] + * database/mongodb: Add optional `write_concern` parameter, which can be set + during database configuration. This establishes a session-wide [write + concern](https://docs.mongodb.com/manual/reference/write-concern/) for the + lifecycle of the mount [GH-3646] BUG FIXES: - * database/mysql: Allow the creation statement to use commands that are not - yet supported by the prepare statement protocol [GH-3619] + * database/mysql: Allow the creation statement to use commands that are not yet + supported by the prepare statement protocol [GH-3619] * core: Fix potential panic that could occur using plugins when a node transitioned from active to standby [GH-3638]