From a7a20ae3bbc2ea45d3c536e51ec36538d3d42fd2 Mon Sep 17 00:00:00 2001 From: swayne275 Date: Tue, 9 Nov 2021 15:43:17 -0700 Subject: [PATCH] Namespace API Lock docs (#13064) * add api lock doc * add docs nav data * Update website/content/api-docs/system/namespaces.mdx Co-authored-by: Chris Capurso * update command doc * clarify locked http status code * add example exempt path * further exempt clarification * link api locked response * add x-vault-namespace api example * Update website/content/docs/concepts/namespace-api-lock.mdx Co-authored-by: Loann Le <84412881+taoism4504@users.noreply.github.com> * review suggestions * few other small tweaks Co-authored-by: Chris Capurso Co-authored-by: Loann Le <84412881+taoism4504@users.noreply.github.com> --- .../content/api-docs/system/namespaces.mdx | 117 +++++++++++++++++- website/content/docs/commands/namespace.mdx | 34 ++++- .../docs/concepts/namespace-api-lock.mdx | 85 +++++++++++++ website/data/docs-nav-data.json | 4 + 4 files changed, 235 insertions(+), 5 deletions(-) create mode 100644 website/content/docs/concepts/namespace-api-lock.mdx diff --git a/website/content/api-docs/system/namespaces.mdx b/website/content/api-docs/system/namespaces.mdx index 140cacc487..edb7f30ac8 100644 --- a/website/content/api-docs/system/namespaces.mdx +++ b/website/content/api-docs/system/namespaces.mdx @@ -72,7 +72,7 @@ $ curl \ ## Read Namespace Information -This endpoint get the metadata for the given namespace path. +This endpoint gets the metadata for the given namespace path. | Method | Path | | :----- | :---------------------- | @@ -94,3 +94,118 @@ $ curl \ "path": "ns1/" } ``` + +## Lock Namespace + +This endpoint locks the API for the current namespace path or optional subpath. +The behavior when interacting with Vault from a locked namespace is described in +[API Locked Response](/docs/concepts/namespace-api-lock#api-locked-response). + +| Method | Path | +| :----- | :---------------------- | +| `POST` | `/sys/namespaces/api-lock/lock/:subpath` | + +### Sample Request - Current Namespace + +```shell-session +$ curl \ + --header "X-Vault-Token: ..." \ + --request POST \ + http://127.0.0.1:8200/v1/sys/namespaces/api-lock/lock +``` + +### Sample Response - Current Namespace + +```json +{ + "unlock_key": "" +} +``` + +### Sample Request - X-Vault-Namespace + +```shell-session +$ curl \ + --header "X-Vault-Token: ..." \ + --header "X-Vault-Namespace: some/path + --request POST \ + http://127.0.0.1:8200/v1/sys/namespaces/api-lock/lock +``` + +### Sample Response - X-Vault-Namespace + +```json +{ + "unlock_key": "" +} +``` + +### Sample Request - Descendant of Current Namespace + +```shell-session +$ curl \ + --header "X-Vault-Token: ..." \ + --request POST \ + http://127.0.0.1:8200/v1/sys/namespaces/api-lock/lock/some/descendant/subpath +``` + +### Sample Response - Descendant of Current Namespace + +```json +{ + "unlock_key": "" +} +``` + +## Unlock Namespace + +This endpoint unlocks the api for the current namespace path or optional subpath. + +| Method | Path | +| :----- | :---------------------- | +| `POST` | `/sys/namespaces/api-lock/unlock/:subpath` | + +### Sample Payload - Current Namespace Non-Root + +```json +{ + "unlock_key": "" +} +``` + +### Sample Request - Current Namespace Non-Root + +```shell-session +$ curl \ + --header "X-Vault-Token: ..." \ + --request POST \ + --data @payload.json \ + http://127.0.0.1:8200/v1/sys/namespaces/api-lock/unlock +``` + +### Sample Request - Current Namespace Root + +```shell-session +$ curl \ + --header "X-Vault-Token: " \ + --request POST \ + http://127.0.0.1:8200/v1/sys/namespaces/api-lock/unlock +``` + +### Sample Payload - Descendant Namespace Non-Root + +```json +{ + "unlock_key": "" +} +``` + +### Sample Request - Descendant Namespace Non-Root + +```shell-session +$ curl \ + --header "X-Vault-Token: ..." \ + --request POST \ + --data @payload.json \ + http://127.0.0.1:8200/v1/sys/namespaces/api-lock/unlock/some/descendant/path +``` diff --git a/website/content/docs/commands/namespace.mdx b/website/content/docs/commands/namespace.mdx index 37c3cf817b..4786549fe8 100644 --- a/website/content/docs/commands/namespace.mdx +++ b/website/content/docs/commands/namespace.mdx @@ -34,6 +34,30 @@ Lookup the namespace information at path `ns1/`: $ vault namespace lookup ns1/ ``` +Lock the API for the current namespace: + +```shell-session +$ vault namespace lock +``` + +Lock the API for a descendant namespace at path `current/namespace/ns1/`: + +```shell-session +$ vault namespace lock ns1/ +``` + +Unlock the API for the current namespace: + +```shell-session +$ vault namespace unlock -unlock-key +``` + +Unlock the API for a descendant namespace at path `current/namespacens1/`: + +```shell-session +$ vault namespace unlock -unlock-key ns1/ +``` + ## Usage ```text @@ -44,10 +68,12 @@ Usage: vault namespace [options] [args] current logged in token belongs to. Subcommands: - create Create a new namespace - delete Delete an existing namespace - list List child namespaces - lookup Look up an existing namespace + create Create a new namespace + delete Delete an existing namespace + list List child namespaces + lookup Look up an existing namespace + lock Lock the API for a namespace + unlock Unlock the API for a namespace ``` For more information, examples, and usage about a subcommand, click on the name diff --git a/website/content/docs/concepts/namespace-api-lock.mdx b/website/content/docs/concepts/namespace-api-lock.mdx new file mode 100644 index 0000000000..3a92adea6a --- /dev/null +++ b/website/content/docs/concepts/namespace-api-lock.mdx @@ -0,0 +1,85 @@ +--- +layout: docs +page_title: Namespace API Lock +description: Lock the Vault API on a per-namespace basis. +--- + +# Namespace Lock and Unlock + +Vault makes the API available (unlocked) by default for all namespaces. In +this state, Vault can respond to all API/CLI ('API' from here on out) requests +as normal. + +A Vault administrator can lock the API for particular namespaces. In this state, +Vault blocks all but a selected few API endpoints from responding to clients +operating in a locked namespace (or a descendant of a locked namespace). The +endpoints that do respond, the exempt paths, are largely the same as the Vault +unauthenticated paths. They are mainly used for checking the status of various +systems (e.g., `sys/health`), or for unlocking the API. + +When the API is locked for a particular namespace, it is also locked for all +descendants of that namespace. If the API was already locked for a descendant, +that lock will remain, but Vault must be unlocked for the parent before +unlocking the descendant. + +## Why? + +Blocking access to much of Vault can be an important break-glass tool in the +event of unexpected behavior. + +For HCP Vault, this provides functionality analogous to sealing Vault, without +the Vault administrator requesting that the Managed Service Provider seal/unseal +Vault. + +This feature also becomes valuable for secure multitenancy in a variety of Vault +deployment strategies. You can restrict Vault access for just part of an +organization, without affecting adjacent parts of the business. If unexpected +behavior is detected in sub-organization A, an administrator can disable Vault +access for any entity under sub-organization A, without disabling access for +sub-organization B. Once the cause has been identified and resolved, the API can +be unlocked for sub-organization A. + +## Locking + +The API can be locked by running `vault namespace lock` (or via the API) while +operating in the namespace to lock. Optionally, a subpath can be provided to +lock a descendant of the current namespace. + +An unlock key will be returned, which can be used to unlock the API for that +namespace. Preserve this key to unlock the API in the future. + +When the API is locked for a namespace, it will also be locked for all +descendants of that namespace. If an authenticated client attempts to access +Vault from a locked namespace, the returned error will inform that client of the +locking namespace. + +## Unlocking + +The API can be unlocked by running `vault namespace unlock` (or via the API) +while operating in the namespace to unlock. Optionally, a subpath can be +provided to lock a descendant of the current namespace. + +In general, an unlock key is required to unlock the API. This is the same as the +unlock key provided when the namespace was locked. + +The unlock key requirement can be overriden by using a root token with the +unlock request. In this case, the unlock key does not need to be provided. + +When the API is unlocked, it will also be unlocked for all descendants that were +locked with it. If a descendant namespace was previously locked, that lock will +remain in place. + +## API Locked Response + +If a request is made to a non-exempt path from a locked namespace, e.g. `nsA`, +Vault responds with an HTTP 503: Service Unavailable. It will also produce the +following error: + +`API access to this namespace has been locked by an administrator - "nsA" must be unlocked to gain access.` + +Similarly, the same error will return if a request is made in a descendant of +`nsA`. + +## How does this work with replication? + +API Lock status is replicated to all clusters, and observed at all nodes. diff --git a/website/data/docs-nav-data.json b/website/data/docs-nav-data.json index cb8461ce85..4edccce7a9 100644 --- a/website/data/docs-nav-data.json +++ b/website/data/docs-nav-data.json @@ -83,6 +83,10 @@ "title": "Seal/Unseal", "path": "concepts/seal" }, + { + "title": "Namespace API Lock", + "path": "concepts/namespace-api-lock" + }, { "title": "Lease, Renew, and Revoke", "path": "concepts/lease"