open-vault/website/content/docs/plugins/plugin-architecture.mdx

189 lines
7.9 KiB
Plaintext
Raw Normal View History

2022-03-22 20:07:32 +00:00
---
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 full original request transparently to the active
node. In other words, plugins can scale horizontally on Vault Enterprise
without any effort on the plugin author's part.
2022-03-22 20:07:32 +00:00
## 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.
2022-05-27 22:08:19 +00:00
@include 'plugin-file-permissions-check.mdx'
2022-03-22 20:07:32 +00:00
### 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
[Serving a Multiplexed Plugin](/docs/secrets/databases/custom#serving-a-plugin-with-multiplexing).
2022-03-22 20:07:32 +00:00
## 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>
```