diff --git a/website/content/docs/plugins/containerized-plugins/add-a-containerized-plugin.mdx b/website/content/docs/plugins/containerized-plugins/add-a-containerized-plugin.mdx new file mode 100644 index 0000000000..3eea8cbf7a --- /dev/null +++ b/website/content/docs/plugins/containerized-plugins/add-a-containerized-plugin.mdx @@ -0,0 +1,339 @@ +--- +layout: docs +page_title: Add a containerized secrets plugin +description: >- + Add a containerized secrets plugin to your Vault instance. +--- + +# Add a containerized secrets plugin to Vault + +@include 'alerts/beta.mdx' + +Run your external secrets plugins in containers to increases the isolation +between the plugin and Vault. + +## Before you start + +- **Your Vault instance must be running on Linux**. +- **Your Vault instance must have local access to the Docker Engine API**. + Vault uses the [Docker SDK](https://pkg.go.dev/github.com/docker/docker) to + manage containerized plugins. +- **You must have [gVisor](https://gvisor.dev/docs/user_guide/install/) + installed**. Vault uses `runsc` as the entrypoint to your container runtime. +- **If you are using a container runtime other than gVisor, you must have a + `runsc`-compatible container runtime installed**. + +## Step 1: Install your container engine + +Install one of the supported container engines: + + - [Docker](https://docs.docker.com/engine/install/) + - [Rootless Docker](https://docs.docker.com/engine/security/rootless/) + +## Step 2: Configure your container runtime + +Update your container engine to use `runsc` for Unix sockets between the host +and plugin binary. + + + + + + 1. Add `runsc` to your + [Docker daemon configuration](https://docs.docker.com/config/daemon): + + ```shell-session + $ sudo tee PATH_TO_DOCKER_DAEMON_CONFIG_FILE < + + + + 1. Create a configuration directory if it does not exist already: + + ```shell-session + $ mkdir -p ~/.config/docker + ``` + + 1. Add `runsc` to your Docker configuration: + + ```shell-session + $ tee ~/.config/docker/daemon.json < + + + +## Step 3: Update the HashiCorp `go-plugin` library + +You must build your plugin locally with v1.5.0+ of the HashiCorp +[`go-plugin`](https://github.com/hashicorp/go-plugin) library to ensure the +finished binary is compatible with containerization. + +Use `go install` to pull the latest version of the plugin library from the +`hashicorp/go-plugin` repo on GitHub: + +```shell-session +$ go install github.com/hashicorp/go-plugin@latest +``` + + + + If you build with the Vault SDK, you can update `go-plugin` with `go install` + by pulling the latest SDK version from the `hashicorp/vault` repo: + + `go install github.com/hashicorp/vault/sdk@latest` + + + + +## Step 4: Build the plugin container + +Containerized plugins must run as a binary in the finished container and +behave the same whether run in a container or as a standalone application: + +1. Build your plugin binary so it runs on Linux. +1. Create a container file for your plugin with the compiled binary as the + entry-point. +1. Build the image with a unique tag. + +For example, to build a containerized version of the built-in key-value (KV) +secrets plugin for Docker: + +1. Clone the latest version of the KV secrets plugin from + `hashicorp/vault-plugin-secrets-kv`. + ```shell-session + $ git clone https://github.com/hashicorp/vault-plugin-secrets-kv.git + ``` +1. Build the Go binary for Linux. + ```shell-session + $ cd vault-plugin-secrets-kv ; CGO_ENABLED=0 GOOS=linux \ + go build -o kv cmd/vault-plugin-secrets-kv/main.go + ``` +1. Create an empty Dockerfile. + ```shell-session + $ touch Dockerfile + ``` +1. Update the empty `Dockerfile` with your infrastructure build details and the + compiled binary as the entry-point. + ```Dockerfile + FROM gcr.io/distroless/static-debian12 + COPY kv /bin/kv + ENTRYPOINT [ "/bin/kv" ] + ``` +1. Build the container image and assign an identifiable tag. + ```shell-session + $ docker build -t hashicorp/vault-plugin-secrets-kv:mycontainer . + ``` + +## Step 5: Register the plugin + +Registering a containerized plugin with Vault is similar to registering any +other external plugin that is available locally to Vault. + +1. Store the SHA256 of the plugin image: + ```shell-session + $ export SHA256=$(docker images \ + --no-trunc \ + --format="{{ .ID }}" \ + YOUR_PLUGIN_IMAGE_TAG | cut -d: -f2) + ``` + For example: + + + + ```shell-session + $ export SHA256=$(docker images \ + --no-trunc \ + --format="{{ .ID }}" \ + hashicorp/vault-plugin-secrets-kv:mycontainer | cut -d: -f2) + ``` + + + +1. Register the plugin with `vault plugin register` and specify your plugin + image with the `oci_image` flag: + ```shell-session + $ vault plugin register \ + -sha256="${SHA256}" \ + -oci_image=YOUR_PLUGIN_IMAGE_TAG \ + NEW_PLUGIN_TYPE NEW_PLUGIN_ID + ``` + For example: + + + + ```shell-session + $ vault plugin register \ + -sha256="${SHA256}" \ + -oci_image=hashicorp/vault-plugin-secrets-kv:mycontainer \ + secret my-kv-container + ``` + + + +1. Enable the new plugin for your Vault instance with `vault secrets enable` and + the new plugin ID: + ```shell-session + $ vault secrets enable NEW_PLUGIN_ID + ``` + For example: + + + + ```shell-session + $ vault secrets enable my-kv-container + ``` + + + + + + + You can provide additional information about the image entrypoint, command, + and environment with the `-command`, `-args`, and `-env` flags for + `vault plugin register`. + + + +## Step 6: Test your plugin + +Now that the container is registered with Vault, you should be able to interact +with it like any other plugin. Try writing then fetching a new secret with your +new plugin. + + +1. Use `vault write` to store a secret with your containerized plugin: + ```shell-session + $ vault write NEW_PLUGIN_ID/SECRET_PATH SECRET_KEY=SECRET_VALUE + ``` + For example: + + + + ```shell-session + $ vault write my-kv-container/testing subject=containers + Success! Data written to: my-kv-container/testing + ``` + + + +1. Fetch the secret you just wrote: + ```shell-session + $ vault read NEW_PLUGIN_ID/SECRET_PATH + ``` + For example: + + + + ```shell-session + $ vault read my-kv-container/testing + ===== Data ===== + Key Value + --- ----- + subject containers + ``` + + + +## Use alternative runtimes ((#alt-runtimes)) + +You can force Vault to use alternative runtimes provided the runtime is +installed locally. + +To use an alternative runtime: + +1. Register and name the runtime with `vault plugin runtime register`. For + example, to register the default Docker runtime (`runc`) as `docker-rt`: + ```shell-session + $ vault plugin runtime register \ + -oci_runtime=runc \ + -type=container docker-rt + ``` + +1. Use the `--runtime` flag during plugin registration to tell Vault what + runtime to use: + ```shell-session + $ vault plugin register \ + -runtime=RUNTIME_NAME \ + -sha256="${SHA256}" \ + -oci_image=YOUR_PLUGIN_IMAGE_TAG \ + NEW_PLUGIN_TYPE NEW_PLUGIN_ID + ``` + For example: + + + + ```shell-session + $ vault plugin register \ + -runtime=docker-rt \ + -sha256="${SHA256}" \ + -oci_image=hashicorp/vault-plugin-secrets-kv:mycontainer \ + secret my-kv-container + ``` + + + +## Troubleshooting + +### Invalid backend version error + +If you run into the following error while registering your plugin: + + + +```plaintext +invalid backend version error: 2 errors occurred: + * error creating container: Error response from daemon: error while looking up the specified runtime path: exec: " /usr/bin/runsc": stat /usr/bin/runsc: no such file or directory + * error creating container: Error response from daemon: error while looking up the specified runtime path: exec: " /usr/bin/runsc": stat /usr/bin/runsc: no such file or directory +``` + + + +it means that Vault cannot find the executable for `runsc`. Confirm the +following is true before trying again: + +1. You have gVisor installed locally to Vault. +1. The path to `runsc` is correct in you your Docker configuration. +1. Vault has permission to run the `runsc` executable. + +If you still get errors when registering a plugin, the recommended workaround is +to use the default Docker runtime (`runc`) as an +[alternative runtime](#alt-runtimes). \ No newline at end of file diff --git a/website/content/docs/plugins/containerized-plugins.mdx b/website/content/docs/plugins/containerized-plugins/index.mdx similarity index 80% rename from website/content/docs/plugins/containerized-plugins.mdx rename to website/content/docs/plugins/containerized-plugins/index.mdx index 748d6d6809..02a3115d3b 100644 --- a/website/content/docs/plugins/containerized-plugins.mdx +++ b/website/content/docs/plugins/containerized-plugins/index.mdx @@ -1,10 +1,10 @@ --- layout: docs -page_title: Containerized plugins -description: External Vault plugins can be run in containers. +page_title: Containerized plugins overview +description: Learn about running external Vault plugins in containers. --- -# Containerized plugins +# Containerized plugins overview @include 'alerts/beta.mdx' @@ -14,10 +14,17 @@ description: External Vault plugins can be run in containers. -By default, external plugins run as subprocesses that share Vault's user and -environment variables. Administrators managing Vault instances on Linux can -choose to run external plugins in containers. Running plugins in containers -increases the isolation between plugins, and between plugins and Vault. +Vault has a wide selection of builtin plugins to support integrating with other +systems. For example, you can use plugins to exchange app identity information +with an authentication service to receive a Vault token, or manage database +credentials. You can also register **external** plugins with your Vault instance +to extend the capabilities of your Vault server. + +By default, external plugins run as subprocesses that share the user and +environment variables of your Vault instance. Administrators managing Vault +instances on Linux can choose to run external plugins in containers. Running +plugins in containers increases the isolation between individual plugins and +between the plugins and Vault. ## System requirements diff --git a/website/data/docs-nav-data.json b/website/data/docs-nav-data.json index d9e56f9b67..4b1cb9ea69 100644 --- a/website/data/docs-nav-data.json +++ b/website/data/docs-nav-data.json @@ -1754,13 +1754,27 @@ "path": "plugins/plugin-management" }, { - "title": "Containerized Plugins", - "path": "plugins/containerized-plugins", - "badge": { - "text": "BETA", - "type": "outlined", - "color": "highlight" - } + "title": "Containerized plugins", + "routes": [ + { + "title": "Overview", + "path": "plugins/containerized-plugins", + "badge": { + "text": "BETA", + "type": "outlined", + "color": "highlight" + } + }, + { + "title": "Add a containerized plugin", + "path": "plugins/containerized-plugins/add-a-containerized-plugin", + "badge": { + "text": "BETA", + "type": "outlined", + "color": "highlight" + } + } + ] }, { "title": "Integrations Library",