docs/multiplexing: overhaul plugin documentation (#14509)

* docs/multiplexing: overhaul plugin documentation

* update nav data

* remove dupe nav data

* add external plugin section to index

* move custom plugin backends under internals/plugins

* remove ref to moved page

* revert moving custom plugin backends

* add building plugins from source section to plug dev

* add mux section to plugin arch

* add mux section to custom plugin page

* reorder custom database page

* use 'external plugin' where appropriate

* add link to plugin multiplexing

* fix example serve multiplex func call

* address review comments

* address review comments

* Minor format updates (#14590)

* mv Plugins to top-level; update upgrading plugins

* update links after changing paths

* add section on external plugin scaling characteristics

* add updates on plugin registration in plugin management page

* add plugin learn resource

* be more explicit about mux upgrade steps; add notes on when to avoid db muxing

* add plugin upgrade built-in section

* add caveats to built-in plugin upgrade

* improvements to built-in plugin override

* formatting, add redirects, correct multiplexing use case

* fix go-plugin link

* Apply suggestions from code review

Co-authored-by: Loann Le <84412881+taoism4504@users.noreply.github.com>

* remove single item list; add link to Database interface

Co-authored-by: Yoko Hyakuna <yoko@hashicorp.com>
Co-authored-by: Loann Le <84412881+taoism4504@users.noreply.github.com>
This commit is contained in:
John-Michael Faircloth 2022-03-22 15:07:32 -05:00 committed by GitHub
parent dacb98ec91
commit 15e693bf91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 689 additions and 359 deletions

View File

@ -180,7 +180,7 @@ method as an external plugin. The azure plugin method is integrated into Vault a
a builtin method by default.
Assuming you have saved the binary `vault-plugin-auth-azure` to some folder and
configured the [plugin directory](/docs/internals/plugins#plugin-directory)
configured the [plugin directory](/docs/plugins/plugin-architecture#plugin-directory)
for your server at `path/to/plugins`:
1. Enable the plugin in the catalog:

View File

@ -104,7 +104,7 @@ to specify where the configuration is.
~> Note: Since each plugin runs as a separate process, you need to do the same
for each plugin in your [plugins
directory](/docs/internals/plugins#plugin-directory).
directory](/docs/plugins/plugin-architecture#plugin-directory).
If you use a Linux distribution with a modern version of systemd, you can add
the following directive to the "[Service]" configuration section:

View File

@ -288,7 +288,7 @@ are a function of the alphabet size.
### External plugin limits
The [plugin system](/docs/internals/plugins) launches a separate process
The [plugin system](/docs/plugins) launches a separate process
initiated by Vault that communicates over RPC. For each secret engine and auth
method that's enabled as an external plugin, Vault will spawn a process on the
host system. For the Database Secrets Engines, external database plugins will

View File

@ -1,256 +0,0 @@
---
layout: docs
page_title: Plugin System
description: Learn about Vault's plugin system.
---
# Plugin System
All Vault auth and secret backends are considered plugins. This simple concept
allows both built-in and external plugins to be treated like Legos. Any plugin
can exist at multiple different locations. Different versions of a plugin may
be at each one, with each version differing from Vault's version.
## Built-In Plugins
Built-in plugins are shipped with Vault, often for commonly used implementations,
and require no additional operator intervention to run. Built-in plugins are
just like any other backend code inside Vault.
To use a different or edited version of a built-in plugin, you would first edit
the plugin's code or navigate to the Vault version holding the version of the
plugin you desire. Then, you'd `$ cd` into the `cmd/:plugin-name` directory
contained alongside that plugin's code. For instance, for AppRole, you would:
`$ cd vault/builtin/credential/approle/cmd/approle`. Once in that directory,
you would run `$ go build` to obtain a new binary for the AppRole plugin. Then
you would add it to the plugin catalog as per normal, and enable it.
# Plugin Architecture
Vault's plugins are completely separate, standalone applications that Vault
executes and communicates with over RPC. This means the plugin process does not
share the same memory space as Vault and therefore can only access the
interfaces and arguments given to it. This also means a crash in a plugin can not
crash the entirety of Vault.
It is possible to enable a custom plugin with a name that's identical to a
built-in plugin. In such a situation, Vault will always choose the custom plugin
when enabling it.
## Plugin Lifecycle
Vault plugins are long-running processes that remain running once they are
spawned by Vault, the parent process. Plugin processes can be started by Vault's
active node and performance standby nodes. Additionally, there are cases where
plugin processes may be terminated by Vault. These cases include but are not
limited to:
- Vault active node step-down
- Vault barrier seal
- Vault graceful shutdown
- Disabling a Secrets Engine or Auth method that uses external plugins
- Database configured connection deletion
- Database configured connection update
- Database configured connection reset request
- Database root credentials rotation
- WAL Rollback from a previously failed root credentials rotation operation
The lifecycle of plugin processes are managed automatically by Vault.
Termination of these processes are typical in certain scenarios, such as the
ones listed above. Vault will start plugin processes when needed, typically by
lazily loading the plugin when a request that requires the plugin is received by
Vault. A plugin process may be started or terminated through other internal
processes within Vault as well. Since Vault manages and tracks the lifecycle of
its plugins, these processes should not be terminated by anything other than
Vault.
## Plugin Communication
Vault creates a mutually authenticated TLS connection for communication with the
plugin's RPC server. While invoking the plugin process, Vault passes a [wrapping
token](/docs/concepts/response-wrapping) to the
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 to
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: Prior to Vault version 1.9.2, reading the original connection's TLS
connection state is not supported in plugins.
## Plugin Registration
An important consideration of Vault's plugin system is to ensure the plugin
invoked by Vault is authentic and maintains integrity. There are two components
that a Vault operator needs to configure before external plugins can be run, the
plugin directory and the plugin catalog entry.
### Plugin Directory
The plugin directory is a configuration option of Vault, and can be specified in
the [configuration file](/docs/configuration).
This setting specifies a directory in which all plugin binaries must live;
_this value cannot be a symbolic link_. A plugin
can not be added to Vault unless it exists in the plugin directory. There is no
default for this configuration option, and if it is not set plugins can not be
added to Vault.
~> Warning: A Vault operator should take care to lock down the permissions on
this directory to ensure a plugin can not be modified by an unauthorized user
between the time of the SHA check and the time of plugin execution.
### Plugin Catalog
The plugin catalog is Vault's list of approved plugins. The catalog is stored in
Vault's barrier and can only be updated by a Vault user with sudo permissions.
Upon adding a new plugin, the plugin name, SHA256 sum of the executable, and the
command that should be used to run the plugin must be provided. The catalog will
make sure the executable referenced in the command exists in the plugin
directory. When added to the catalog the plugin is not automatically executed,
it instead becomes visible to backends and can be executed by them. For more
information on the plugin catalog please see the [Plugin Catalog API
docs](/api-docs/system/plugins-catalog).
An example of plugin registration in current versions of Vault:
```shell-session
$ vault plugin register -sha256=<SHA256 Hex value of the plugin binary> \
secret \ # type
myplugin-database-plugin
Success! Registered plugin: myplugin-database-plugin
```
Vault versions prior to v0.10.4 lacked the `vault plugin` operator and the
registration step for them is:
```shell-session
$ vault write sys/plugins/catalog/database/myplugin-database-plugin \
sha256=<SHA256 Hex value of the plugin binary> \
command="myplugin"
Success! Data written to: sys/plugins/catalog/database/myplugin-database-plugin
```
### Plugin Execution
When a backend wants to run a plugin, it first looks up the plugin, by name, in
the catalog. It then checks the executable's SHA256 sum against the one
configured in the plugin catalog. Finally Vault runs the command configured in
the catalog, sending along the JWT formatted response wrapping token and mlock
settings. Like Vault, plugins support [the use of mlock when available](/docs/configuration#disable_mlock).
~> Note: If Vault is configured with `mlock` enabled, then the Vault executable and each
plugin executable in your [plugins directory](/docs/internals/plugins#plugin-directory) must be
given the ability to use the `mlock` syscall.
### Plugin Upgrades
Plugins may be updated by registering and reloading them. More details on the
upgrade procedure can be found in [Upgrading Vault Plugins](/docs/upgrading/plugins).
### Troubleshooting
#### Unrecognized remote plugin message
If the following error is encountered when enabling a plugin secret engine or
auth method:
```sh
Unrecognized remote plugin message:
This usually means that the plugin is either invalid or simply
needs to be recompiled to support the latest protocol.
```
Verify whether the Vault process has `mlock` enabled, and if so run the
following command against the plugin binary:
```sh
sudo setcap cap_ipc_lock=+ep <plugin-binary>
```
# Plugin Development
~> Advanced topic! Plugin development is a highly advanced topic in Vault, and
is not required knowledge for day-to-day usage. If you don't plan on writing any
plugins, we recommend not reading this section of the documentation.
Because Vault communicates to plugins over a RPC interface, you can build and
distribute a plugin for Vault without having to rebuild Vault itself. This makes
it easy for you to build a Vault plugin for your organization's internal use,
for a proprietary API that you don't want to open source, or to prototype
something before contributing it back to the main project.
In theory, because the plugin interface is HTTP, you could even develop a plugin
using a completely different programming language! (Disclaimer, you would also
have to re-implement the plugin API which is not a trivial amount of work.)
Developing a plugin is simple. The only knowledge necessary to write
a plugin is basic command-line skills and basic knowledge of the
[Go programming language](http://golang.org).
Your plugin implementation needs to satisfy the interface for the plugin
type you want to build. You can find these definitions in the docs for the
backend running the plugin.
```go
package main
import (
"os"
myPlugin "your/plugin/import/path"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/sdk/plugin"
)
func main() {
apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:])
tlsConfig := apiClientMeta.GetTLSConfig()
tlsProviderFunc := api.VaultPluginTLSProvider(tlsConfig)
err := plugin.Serve(&plugin.ServeOpts{
BackendFactoryFunc: myPlugin.Factory,
TLSProviderFunc: tlsProviderFunc,
})
if err != nil {
logger := hclog.New(&hclog.LoggerOptions{})
logger.Error("plugin shutting down", "error", err)
os.Exit(1)
}
}
```
And that's basically it! You would just need to change `myPlugin` to your actual
plugin.
[api_addr]: /docs/configuration#api_addr
## Plugin Development - Resources
For more information on how to register and enable your plugin, check out the
[Building Plugin Backends](https://learn.hashicorp.com/vault/developer/plugin-backends)
tutorial.
Other HashiCorp plugin development resources:
* [vault-auth-plugin-example](https://github.com/hashicorp/vault-auth-plugin-example)
### Plugin Development - Resources - Community
Community plugin examples/guides are developed by community members. HashiCorp
does not validate these for correctness.
- [Enigma (good starting point)](https://github.com/ixe013/benigma)
Authors who wish to have their guides or examples listed may file a submission
via a GitHub issue or directly open a pull request with changes to this page.

View File

@ -16,7 +16,7 @@ This program is intended to be largely a self-service process with links and gui
Vault is an Identity-based security solution that leverages trusted sources of identity to keep secrets and application data secured with one centralized, audited workflow for tightly controlling access to secrets across applications, systems, and infrastructure while encrypting data both in flight and at rest. For a full description of the current features please refer to the Vault [website](/).
Vault has a secure [plugin](/docs/internals/plugins) architecture. Vaults plugins are completely separate, standalone applications that Vault executes and communicates with over RPC. This means the plugin process does not share the same memory space as Vault and therefore can only access the interfaces and arguments given to it.
Vault has a secure [plugin](/docs/plugins) architecture. Vaults plugins are completely separate, standalone applications that Vault executes and communicates with over RPC. This means the plugin process does not share the same memory space as Vault and therefore can only access the interfaces and arguments given to it.
Vault plugins can be built-in and bundled with the Vault binary, or be external that has to be manually mounted. Built-in plugins are developed by HashiCorp, while external plugins can be developed by HashiCorp, technology partners, or the community. There is a curated collection of all plugins, both built-in and external, located on the [Plugin Portal](/docs/plugin-portal).

View File

@ -1,54 +0,0 @@
---
layout: docs
page_title: Custom Plugin Backends
description: >-
Plugin backends are mountable backends that are implemented using Vault's
plugin system.
---
# Custom Plugin Backends
Plugin backends are the components in Vault that can be implemented separately from Vault's
builtin backends. These backends can be either authentication or secrets engines.
The [`api_addr`][api_addr] must be set in order for the plugin process to 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](/docs/internals/plugins).
# Enabling/Disabling Plugin Backends
Before a plugin backend can be mounted, it needs to be registered via the
[plugin catalog](/docs/internals/plugins#plugin-catalog). After
the plugin is registered, it can be mounted by specifying the registered plugin name:
```shell-session
$ vault secrets enable -path=my-secrets passthrough-plugin
Success! Enabled the passthrough-plugin secrets engine at: my-secrets/
```
Listing secrets engines will display secrets engines that are mounted as
plugins:
```shell-session
$ vault secrets list
Path Type Accessor Plugin Default TTL Max TTL Force No Cache Replication Behavior Description
my-secrets/ plugin plugin_deb84140 passthrough-plugin system system false replicated
```
Disabling a plugin backend is the identical to disabling internal secrets engines:
```shell-session
$ vault secrets disable my-secrets
```
# Upgrading Plugins
Upgrade instructions can be found in the [Upgrading Plugins - Guides][upgrading_plugins]
page.
[api_addr]: /docs/configuration#api_addr
[upgrading_plugins]: /docs/upgrading/plugins

View File

@ -0,0 +1,39 @@
---
layout: docs
page_title: Plugin System
description: Learn about Vault's plugin system.
---
# Plugin System
All Vault auth methods and secrets engines are considered plugins. This simple concept
allows both built-in and external plugins to be treated like Legos. Any plugin
can exist at multiple different locations. Different versions of a plugin may
be at each location, with each version differing from Vault's version.
## Built-In Plugins
Built-in plugins are shipped with Vault, often for commonly used implementations,
and require no additional operator intervention to run. Built-in plugins are
just like any other backend code inside Vault.
To use a different or edited version of a built-in plugin, the plugin must be
run as an external plugin. See [Overriding Built-in Plugins](/docs/upgrading/plugins#overriding-built-in-plugins)
for details on how to override a built-in plugin in-place.
## External Plugins
External plugins are not shipped with Vault and require additional operator
intervention to run.
To run an external plugin, a binary of the plugin is required. Plugin
binaries can be obtained from [releases.hashicorp.com](https://releases.hashicorp.com/)
or they can be [built from source](/docs/plugins/plugin-development#building-a-plugin-from-source).
Vault's external plugins are completely separate, standalone applications that
Vault executes and communicates with over RPC. Each time a Vault secret engine
or auth method is mounted, a new process is spawned. However, database plugins
can be made to implement [plugin multiplexing](/docs/plugins/plugin-architecture#plugin-multiplexing)
which allows a single plugin process to be used for multiple database
connections.

View File

@ -0,0 +1,190 @@
---
layout: docs
page_title: External Plugin Architecture
description: Learn about Vault's plugin architecture.
---
# External Plugin Architecture
Vault's external plugins are completely separate, standalone applications that Vault
executes and communicates with over RPC. This means the plugin process does not
share the same memory space as Vault and therefore can only access the
interfaces and arguments given to it. This also means a crash in a plugin can not
crash the entirety of Vault.
It is possible to enable a custom plugin with a name that's identical to a
built-in plugin. In such a situation, Vault will always choose the custom plugin
when enabling it.
## External Plugin Lifecycle
Vault external plugins are long-running processes that remain running once they are
spawned by Vault, the parent process. Plugin processes can be started by Vault's
active node and performance standby nodes. Additionally, there are cases where
plugin processes may be terminated by Vault. These cases include, but are not
limited to:
- Vault active node step-down
- Vault barrier seal
- Vault graceful shutdown
- Disabling a Secrets Engine or Auth method that uses external plugins
- Database configured connection deletion
- Database configured connection update
- Database configured connection reset request
- Database root credentials rotation
- WAL Rollback from a previously failed root credentials rotation operation
The lifecycle of plugin processes are managed automatically by Vault.
Termination of these processes are typical in certain scenarios, such as the
ones listed above. Vault will start plugin processes when needed, typically by
lazily loading the plugin when a request that requires the plugin is received by
Vault. A plugin process may be started or terminated through other internal
processes within Vault as well. Since Vault manages and tracks the lifecycle of
its plugins, these processes should not be terminated by anything other than
Vault.
### External Plugin Scaling Characteristics
External plugins are able to leverage [Performance Standbys](/docs/enterprise/performance-standby)
without any explicit action by a plugin author. The default behavior of Vault
Enterprise is to attempt to handle all requests, including requests to plugins,
on performance standbys. If the plugin request makes any attempt to modify
storage, the request will receive a readonly error, and the request routing
code will then forward the request to the active node. In other words, plugins
can scale horizontally on Vault Enterprise without any effort on the plugin
author's part.
## Plugin Communication
Vault creates a mutually authenticated TLS connection for communication with
the plugin's RPC server. Database secrets engines make use of the AutoMTLS
feature of [go-plugin](https://www.github.com/hashicorp/go-plugin) which will
automatically negotiate mTLS for transport authentication. For all other
plugins, Vault passes a [wrapping token](/docs/concepts/response-wrapping) to
the 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`](/docs/configuration#api_addr) must be set in order for the
plugin process to 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: Prior to Vault version 1.9.2, reading the original connection's TLS
connection state is not supported in plugins.
## Plugin Registration
An important consideration of Vault's plugin system is to ensure the plugin
invoked by Vault is authentic and maintains integrity. There are two components
that a Vault operator needs to configure before external plugins can be run- the
plugin directory and the plugin catalog entry.
### Plugin Directory
The plugin directory is a configuration option of Vault and can be specified in
the [configuration file](/docs/configuration).
This setting specifies a directory in which all plugin binaries must live;
_this value cannot be a symbolic link_. A plugin
cannot be added to Vault unless it exists in the plugin directory. There is no
default for this configuration option, and if it is not set, plugins cannot be
added to Vault.
~> Warning: A Vault operator should take caution and lock down the permissions on
this directory to ensure a plugin cannot be modified by an unauthorized user
between the time of the SHA check and the time of plugin execution.
### Plugin Catalog
The plugin catalog is Vault's list of approved plugins. The catalog is stored in
Vault's barrier and can only be updated by a Vault user with sudo permissions.
Upon adding a new plugin, the plugin name, SHA256 sum of the executable, and the
command that should be used to run the plugin must be provided. The catalog will
ensure the executable referenced in the command exists in the plugin
directory. When added to the catalog, the plugin is not automatically executed,
but becomes visible to backends and can be executed by them. For more
information on the plugin catalog please see the [Plugin Catalog API
docs](/api-docs/system/plugins-catalog).
An example of plugin registration in current versions of Vault:
```shell-session
$ vault plugin register -sha256=<SHA256 Hex value of the plugin binary> \
secret \ # type
myplugin-database-plugin
Success! Registered plugin: myplugin-database-plugin
```
Vault versions prior to v0.10.4 lacked the `vault plugin` operator and the
registration step for them is:
```shell-session
$ vault write sys/plugins/catalog/database/myplugin-database-plugin \
sha256=<SHA256 Hex value of the plugin binary> \
command="myplugin"
Success! Data written to: sys/plugins/catalog/database/myplugin-database-plugin
```
### Plugin Execution
When a backend wants to run a plugin, it first looks up the plugin, by name, in
the catalog. It then checks the executable's SHA256 sum against the one
configured in the plugin catalog. Finally Vault runs the command configured in
the catalog, sending along the JWT formatted response wrapping token and mlock
settings. Like Vault, plugins support [the use of mlock when available](/docs/configuration#disable_mlock).
~> Note: If Vault is configured with `mlock` enabled, then the Vault executable
and each plugin executable in your [plugins directory](/docs/plugins/plugin-architecture#plugin-directory)
must be given the ability to use the `mlock` syscall.
### Plugin Upgrades
External plugins may be updated by registering and reloading them. More details
on the upgrade procedure can be found in
[Upgrading Vault Plugins](/docs/upgrading/plugins).
## Plugin Multiplexing
Database plugins can be made to implement plugin multiplexing,
allowing a single plugin process to be used for multiple database
connections. This single process, per database plugin, will be multiplexed
across all Vault namespaces for mounts of this type. Multiplexing a plugin
does not affect the current behavior of existing plugins.
To enable multiplexing, the plugin must be compiled with the `ServeMultiplex`
function call from Vault's `dbplugin` package. At this time, there is no
opt-out capability for plugins that implement multiplexing. To use a
non-multiplexed plugin, run an older version of the plugin, i.e., the
plugin calls the `dbplugin.Serve` function. More details
on implementing plugin multiplexing can be found in
[Upgrading Vault Plugins](/docs/secrets/databases/custom#serving-a-plugin-with-multiplexing).
## Troubleshooting
### Unrecognized remote plugin message
If the following error is encountered when enabling a plugin secret engine or
auth method:
<CodeBlockConfig hideClipboard>
```sh
Unrecognized remote plugin message:
This usually means that the plugin is either invalid or simply
needs to be recompiled to support the latest protocol.
```
</CodeBlockConfig>
Verify whether the Vault process has `mlock` enabled, and if so, run the
following command against the plugin binary:
```shell-session
$ sudo setcap cap_ipc_lock=+ep <plugin-binary>
```

View File

@ -0,0 +1,91 @@
---
layout: docs
page_title: Plugin Development
description: Learn about Vault plugin development.
---
# Plugin Development
~> Advanced topic! Plugin development is a highly advanced topic in Vault, and
is not required knowledge for day-to-day usage. If you don't plan on writing any
plugins, we recommend not reading this section of the documentation.
Because Vault communicates to plugins over a RPC interface, you can build and
distribute a plugin for Vault without having to rebuild Vault itself. This makes
it easy for you to build a Vault plugin for your organization's internal use,
for a proprietary API that you don't want to open source, or to prototype
something before contributing it back to the main project.
In theory, because the plugin interface is HTTP, you could even develop a plugin
using a completely different programming language! (Disclaimer, you would also
have to re-implement the plugin API which is not a trivial amount of work.)
Developing a plugin is simple. The only knowledge necessary to write
a plugin is basic command-line skills and basic knowledge of the
[Go programming language](http://golang.org).
Your plugin implementation needs to satisfy the interface for the plugin
type you want to build. You can find these definitions in the docs for the
backend running the plugin.
```go
package main
import (
"os"
myPlugin "your/plugin/import/path"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/sdk/plugin"
)
func main() {
apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:])
tlsConfig := apiClientMeta.GetTLSConfig()
tlsProviderFunc := api.VaultPluginTLSProvider(tlsConfig)
err := plugin.Serve(&plugin.ServeOpts{
BackendFactoryFunc: myPlugin.Factory,
TLSProviderFunc: tlsProviderFunc,
})
if err != nil {
logger := hclog.New(&hclog.LoggerOptions{})
logger.Error("plugin shutting down", "error", err)
os.Exit(1)
}
}
```
And that's basically it! You would just need to change `myPlugin` to your actual
plugin.
[api_addr]: /docs/configuration#api_addr
## Building a Plugin from Source
To build a plugin from source, first navigate to the location holding the
desired plugin version. Next, run `go build` to obtain a new binary for the
plugin. Finally,
[register](/docs/plugins/plugin-architecture#plugin-registration) the
plugin and enable it.
## Plugin Development - Resources
For more information on how to register and enable your plugin, refer to the
[Building Plugin Backends](https://learn.hashicorp.com/vault/developer/plugin-backends)
tutorial.
Other HashiCorp plugin development resources:
* [vault-auth-plugin-example](https://github.com/hashicorp/vault-auth-plugin-example)
* [Custom Secrets Engines](https://learn.hashicorp.com/collections/vault/custom-secrets-engine)
### Plugin Development - Resources - Community
See the [Plugin Portal](/docs/plugins/plugin-portal#community) to find
Community plugin examples/guides developed by community members. HashiCorp does
not validate these for correctness.

View File

@ -0,0 +1,69 @@
---
layout: docs
page_title: Plugin Management
description: >-
External Plugins are mountable backends that are implemented using Vault's
plugin system.
---
# Plugin Management
External plugins are the components in Vault that can be implemented separately
from Vault's built-in plugins. These plugins can be either authentication or
secrets engines.
The [`api_addr`][api_addr] must be set in order for the plugin process to
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](/docs/plugins).
## Registering External Plugins
Before an external plugin can be mounted, it needs to be
[registered](/docs/plugins/plugin-architecture#plugin-registration) in the
plugin catalog to ensure the plugin invoked by Vault is authentic and maintains
integrity:
```shell-session
$ vault plugin register -sha256=<SHA256 Hex value of the plugin binary> \
secret \ # type
my-secrets
Success! Registered plugin: myplugin-database-plugin
```
## Enabling/Disabling External Plugins
After the plugin is registered, it can be mounted by specifying the registered
plugin name:
```shell-session
$ vault secrets enable -path=my-secrets passthrough-plugin
Success! Enabled the passthrough-plugin secrets engine at: my-secrets/
```
Listing secrets engines will display secrets engines that are mounted as
plugins:
```shell-session
$ vault secrets list
Path Type Accessor Plugin Default TTL Max TTL Force No Cache Replication Behavior Description
my-secrets/ plugin plugin_deb84140 passthrough-plugin system system false replicated
```
Disabling an external plugins is identical to disabling a built-in plugin:
```shell-session
$ vault secrets disable my-secrets
```
## Upgrading Plugins
Upgrade instructions can be found in the [Upgrading Plugins - Guides][upgrading_plugins]
page.
[api_addr]: /docs/configuration#api_addr
[upgrading_plugins]: /docs/upgrading/plugins

View File

@ -7,10 +7,10 @@ description: A curated collection of official, partner, and community Vault plug
# Plugin Portal
This page contains a curated collection of official, partner, and community
[Vault plugins](/docs/internals/plugins).
[Vault plugins](/docs/plugins).
For more information about plugin development, refer to this [documentation
section](/docs/internals/plugins#plugin-development) and this [Learn
section](/docs/plugins/plugin-development) and this [Learn
Guide](https://learn.hashicorp.com/vault/developer/plugin-backends).
## Official
@ -23,7 +23,7 @@ if necessary.
If a plugin exists separately under its own repository, follow the instructions
within that repository to develop, test, and build the plugin. If a repository
exists within the Vault repository, the plugin can be built as instructed in
[here](/docs/internals/plugins#built-in-plugins).
[here](/docs/plugins#built-in-plugins).
### Auth

View File

@ -3,7 +3,7 @@ layout: docs
page_title: Custom - Database - Secrets Engines
description: |-
The database secrets engine allows new functionality to be added through a
plugin interface without needing to modify vault's core code. This allows you
plugin interface without needing to modify Vault's core code. This allows you
write your own code to generate credentials in any database you wish. It also
allows databases that require dynamically linked libraries to be used as
plugins while keeping Vault itself statically linked.
@ -19,18 +19,25 @@ for more details.
~> **Advanced topic!** Plugin development is a highly advanced topic in Vault,
and is not required knowledge for day-to-day usage. If you don't plan on writing
any plugins, we recommend not reading this section of the documentation.
any plugins, feel free to skip this section of the documentation.
The database secrets engine allows new functionality to be added through a
plugin interface without needing to modify vault's core code. This allows you
plugin interface without needing to modify Vault's core code. This allows you
write your own code to generate credentials in any database you wish. It also
allows databases that require dynamically linked libraries to be used as plugins
while keeping Vault itself statically linked.
Please read the [Plugins internals](/docs/internals/plugins) docs for more
Please read the [Plugins internals](/docs/plugins) docs for more
information about the plugin system before getting started building your
Database plugin.
Database plugins can be made to implement
[plugin multiplexing](/docs/plugins/plugin-architecture#plugin-multiplexing)
which allows a single plugin process to be used for multiple database
connections. To enable multiplexing, the plugin must be compiled with the
`ServeMultiplex` function call from Vault's `dbplugin` package.
## Plugin Interface
All plugins for the database secrets engine must implement the same interface. This interface
@ -100,12 +107,19 @@ the configuration is valid and able to connect to the database in question. If t
false, no connection should be made during the `Initialize` call, but subsequent calls to the
other functions will need to open a connection.
## Serving your plugin
## Serving A Plugin
The plugin runs as a separate binary outside of Vault, so the plugin itself will need a `main`
function. Use the `Serve` function within `sdk/database/dbplugin/v5` to serve your plugin. You
will also need to pass some TLS configuration information that Vault uses when initializing the
plugin. Below is an example setup:
### Serving A Plugin with Multiplexing
~> Plugin multiplexing requires `github.com/hashicorp/vault/sdk v0.4.0` or above.
The plugin runs as a separate binary outside of Vault, so the plugin itself
will need a `main` function. Use the `ServeMultiplex` function within
`sdk/database/dbplugin/v5` to serve your multiplexed plugin. You will also need
to pass some TLS configuration information that Vault uses when initializing
the plugin.
Below is an example setup:
```go
package main
@ -128,12 +142,7 @@ func main() {
}
func Run() error {
dbType, err := New()
if err != nil {
return err
}
dbplugin.Serve(dbType.(dbplugin.Database))
dbplugin.ServeMultiplex(dbType.(dbplugin.New))
return nil
}
@ -172,6 +181,29 @@ func (db *MyDatabase) secretValues() map[string]string {
Replacing `MyDatabase` with the actual implementation of your database plugin.
### Serving A Plugin without Multiplexing
Serving a plugin without multiplexing requires calling the `Serve` function
from `sdk/database/dbplugin/v5` to serve your plugin. You will also need to
pass some TLS configuration information that Vault uses when initializing the
plugin.
The setup is exactly the same as the multiplexed case above, except for the
`Run` function:
```go
func Run() error {
dbType, err := New()
if err != nil {
return err
}
dbplugin.Serve(dbType.(dbplugin.Database))
return nil
}
```
## Running your plugin
The above main package, once built, will supply you with a binary of your
@ -179,7 +211,7 @@ plugin. We also recommend if you are planning on distributing your plugin to
build with [gox](https://github.com/mitchellh/gox) for cross platform builds.
To use your plugin with the database secrets engine you need to place the binary in the
plugin directory as specified in the [plugin internals](/docs/internals/plugins) docs.
plugin directory as specified in the [plugin internals](/docs/plugins) docs.
You should now be able to register your plugin into the vault catalog. To do
this your token will need sudo permissions.
@ -200,7 +232,36 @@ $ vault write database/config/mydatabase \
myplugins_connection_details="..."
```
## Upgrading database plugins
## Upgrading database plugins to leverage plugin multiplexing
### Background
Scaling many external plugins can become resource intensive. To address
performance problems with scaling external plugins, database plugins can be
made to implement [plugin multiplexing](/docs/plugins/plugin-architecture#plugin-multiplexing)
which allows a single plugin process to be used for multiple database
connections. To enable multiplexing, the plugin must be compiled with the
`ServeMultiplex` function call from Vault's `dbplugin` package.
### Upgrading your database plugin to leverage plugin multiplexing
There is only one step required to upgrade from a non-multiplexed to a
multiplexed database plugin: Change the `Serve` function call to `ServeMultiplex`.
This will run the RPC server for the plugin just as before. However, the
`ServeMultiplex` function takes the factory function directly as its argument.
This factory function is a function that returns an object that implements the
[`dbplugin.Database` interface](/docs/secrets/databases/custom#plugin-interface).
### When should plugin multiplexing be avoided?
Some use cases that should avoid plugin multiplexing might include:
* Plugin process level separation is required
* Avoiding restart across all mounts/database connections for a plugin type on
crashes or plugin reload calls
## Upgrading database plugins to the V5 interface
### Background

View File

@ -24,7 +24,7 @@ workloads are the primary focus of the Venafi secrets engine. As such,
revocation is not currently supported.
The Venafi secrets engine makes use of HashiCorp Vault's
[plugin system](/docs/internals/plugins)
[plugin system](/docs/plugins)
and Venafi's [VCert Client SDK](https://github.com/Venafi/vcert). If you have
questions about the Venafi secrets engine, have an issue to report, or have
developed improvements that you want to contribute, visit the
@ -104,7 +104,7 @@ and any other dependencies that appear in the Venafi Cloud documentation.
Before certificates can be issued, you must complete these steps to configure the
Venafi secrets engine:
1. Create the [directory](/docs/internals/plugins#plugin-directory)
1. Create the [directory](/docs/plugins/plugin-architecture#plugin-directory)
where your Vault server will look for plugins (e.g. /etc/vault/vault_plugins).
The directory must not be a symbolic link. On macOS, for example, /etc is a
link to /private/etc. To avoid errors, choose an alternative directory such
@ -138,7 +138,7 @@ Venafi secrets engine:
```
1. Register the `venafi-pki-backend` plugin in the Vault
[system catalog](/docs/internals/plugins#plugin-catalog):
[system catalog](/docs/plugins/plugin-architecture#plugin-catalog):
```text
$ vault write sys/plugins/catalog/secret/venafi-pki-backend \

View File

@ -6,11 +6,11 @@ description: These are general upgrade instructions for Vault plugins.
# Upgrading Vault Plugins
The following procedure details steps for upgrading a plugin that has already
been registered to the catalog on a running server. This procedure is applicable
to secret, auth, and database plugins.
## External Plugin Upgrade Procedure
## Upgrade Procedure
The following procedure details steps for upgrading an external plugin that has
been registered to the catalog on a running server. This procedure is
applicable to secret engines, auth methods, and database plugins.
Vault executes plugin binaries when they are configured and roles are established
around them. The binary cannot be modified or replaced while running, so
@ -21,16 +21,41 @@ Instead, you can restart or reload a plugin with the
`sys/plugins/reload/backend` [API][plugin_reload_api]. Follow these steps to
replace or upgrade a Vault plugin binary:
1. Register plugin_v1 to the catalog
2. Mount the plugin backend
3. Register plugin_v2 to the catalog under the same plugin name, but with
updated command to run plugin_v2 and updated sha256 of plugin_v2
4. Trigger a plugin reload with `sys/plugins/reload/backend` to reload all
1. [Register][plugin_registration] version 1 of `my-db-plugin` to the catalog
```shell-session
$ vault plugin register -sha256=<SHA256 Hex value of the plugin binary> \
database \ # type
my-db-plugin
```
2. [Mount][plugin_management] the plugin backend
```shell-session
$ vault secrets enable database
```
3. Register version 2 of `my-db-plugin` to the catalog under the same plugin
name, but with updated command to run version 2 of `my-db-plugin` and updated
sha256 of the new binary
```shell-session
$ vault plugin register -sha256=<SHA256 Hex value of the plugin binary> \
database \ # type
my-db-plugin
```
4. Trigger a [plugin reload][/docs/commands/plugin/reload] to reload all
mounted backends using that plugin or a subset of the mounts using that plugin
with either the `plugin` or `mounts` parameter respectively.
Until step 4, the mount will still use plugin_v1, and when the reload is
triggered, Vault will kill plugin_v1s process and start a plugin_v2 process.
```shell-session
$ vault plugin reload -plugin my-db-plugin
```
Until step 4, the mount will still use version 1 of `my-db-plugin`, and when
the reload is triggered, Vault will kill `my-db-plugin`s process and start the
new plugin process for `my-db-plugin` version 2.
-> **Important:** Plugin reload of a new plugin binary must be
performed on each Vault instance. Performing a plugin upgrade on a single
@ -38,4 +63,147 @@ instance or through a load balancer can result in mismatched
plugin binaries within a cluster. On a replicated cluster this may be accomplished
by setting the 'scope' parameter of the reload to 'global'.
## Overriding Built-in Plugins
### Background
Vault's auth methods and secrets engines are structured as plugins, but this
design is not obvious since many of them are built into Vault.
You can see them with the Vault plugin list command, for example, the list of
Secrets engines:
```shell-session
$ vault plugin list secret
Plugins
-------
ad
alicloud
aws
azure
cassandra
consul
gcp
gcpkms
kv
mongodb
mongodbatlas
mssql
mysql
nomad
openldap
pki
postgresql
rabbitmq
ssh
terraform
totp
transit
```
This will list all Secrets engines, internal (built-in) or external. To find
out if a plugin is built-in, we can query its info:
```shell-session
$ vault plugin info secret azure
Key Value
--- -----
args []
builtin true
command n/a
name azure
sha256 n/a
```
Because these built-in engines are plugins, they can be overridden. This can be
a useful way to leverage features or bug fixes in plugins that are newer than
the version of Vault you're using, without updating or even restarting Vault,
and while retaining the data for your existing mount.
Assume you have a new version of Azure Secrets and the binary is called
"azure_new". The binary needs to be in the [plugin directory](/docs/plugins/plugin-architecture#plugin-directory)
and can then be registered as either a distinct plugin, or overriding the
current one.
~> **Important:** do not disable (`vault secrets disable ...`) any mount that has
data you're interested in; that would erase storage. For the in-place update,
register a new plugin atop the built-in one and leave any mounts alone.
### Procedure for Overriding Built-in Plugins
The syntax is the same as an external plugin, with the difference being you
name it the same as a built-in:
```shell-session
$ vault plugin register \
-sha256=<SHA256 Hex value of the plugin binary> \
-command=azure_new \
secret \
azure
```
"-command=azure_new" is the name of the binary, "secret" is the plugin type,
and "azure" is the name of the built-in plugin that we're overriding. We can
verify that the override is in place:
```shell-session
$ vault plugin info secret azure
Key Value
--- -----
args []
builtin false
command azure_new
name azure
sha256 f6f6ec45d37484c257aa9ff80444b9f244aaef1c650edf8a42a2a1d3f00db2c5
```
At this point we've overridden the built-in, but it is not yet actively
handling requests. For that we run:
```shell-session
$ vault plugin reload -plugin=azure
```
### Procedure for Reverting After Overriding A Built-in Plugin
To revert the override, first deregister the plugin:
```shell-session
$ vault plugin deregister secret azure
```
Next, verify the override has been reverted and we are now using the built-in
plugin:
```shell-session
$ vault plugin info secret azure
Key Value
--- -----
args []
builtin true
command n/a
name azure
sha256 n/a
```
Finally, reload the plugin:
```shell-session
$ vault plugin reload -plugin=azure
```
### Caveats to Overriding Built-in Plugins
* As mentioned earlier, disabling existing mounts will wipe the existing data.
* This type of upgrade affects all uses of the plugin. So if you have 5
different Azure Secrets mounts, they'll all change after the replacement. If
you don't want that, you'll need to register the plugin under a different name
and start with a fresh mount.
* In most cases, data upgrade and downgrade is not an issue. If the "new" version
introduces new data and you downgrade, the "old" version will ignore the
extraneous data. In some cases upgrading changes existing data in non-backwards
compatible ways, so it is good to check whether this is an issue.
[plugin_reload_api]: /api-docs/system/plugins-reload-backend
[plugin_registration]: /docs/plugins/plugin-architecture#plugin-registration
[plugin_management]: /docs/plugins/plugin-management#enabling-disabling-external-plugins

View File

@ -76,10 +76,6 @@
"title": "Replication",
"path": "internals/replication"
},
{
"title": "Plugins",
"path": "internals/plugins"
},
{
"title": "Limits and Maximums",
"path": "internals/limits"
@ -1285,14 +1281,30 @@
]
},
{
"title": "Plugin Backends",
"path": "plugin"
"title": "Plugins",
"routes": [
{
"title": "Overview",
"path": "plugins"
},
{
"title": "Plugin Architecture",
"path": "plugins/plugin-architecture"
},
{
"title": "Plugin Development",
"path": "plugins/plugin-development"
},
{
"title": "Plugin Management",
"path": "plugins/plugin-management"
},
{
"title": "Plugin Portal",
"path": "plugins/plugin-portal"
}
]
},
{
"title": "Plugin Portal",
"path": "plugin-portal"
},
{
"title": "Vault Integration Program",
"path": "partnerships"

View File

@ -230,6 +230,16 @@ module.exports = [
destination: '/docs/plugin',
permanent: true,
},
{
source: '/docs/internals/plugins',
destination: '/docs/plugin',
permanent: true,
},
{
source: '/docs/plugin-portal',
destination: '/docs/plugins/plugin-portal',
permanent: true,
},
{
source: '/docs/secrets/generic',
destination: '/docs/secrets/kv',