2017-05-02 08:59:36 +00:00
---
2020-01-18 00:18:09 +00:00
layout: docs
page_title: Plugin System
description: Learn about Vault's plugin system.
2017-05-02 08:59:36 +00:00
---
# Plugin System
2020-01-18 00:18:09 +00:00
2018-11-14 17:17:12 +00:00
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
2020-01-18 00:18:09 +00:00
2018-11-14 17:17:12 +00:00
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.
2017-05-02 08:59:36 +00:00
# Plugin Architecture
2020-01-18 00:18:09 +00:00
2017-05-02 08:59:36 +00:00
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.
2019-10-07 13:59:34 +00:00
It is possible to enable a custom plugin with a name that's identical to a
2018-11-14 17:17:12 +00:00
built-in plugin. In such a situation, Vault will always choose the custom plugin
2019-10-07 13:59:34 +00:00
when enabling it.
2018-11-14 17:17:12 +00:00
2021-10-01 18:59:13 +00:00
## 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.
2017-05-02 08:59:36 +00:00
## Plugin Communication
2020-01-18 00:18:09 +00:00
2017-05-02 08:59:36 +00:00
Vault creates a mutually authenticated TLS connection for communication with the
2017-08-08 16:39:19 +00:00
plugin's RPC server. While invoking the plugin process, Vault passes a [wrapping
2020-01-22 20:05:41 +00:00
token](/docs/concepts/response-wrapping) to the
2017-05-02 08:59:36 +00:00
plugin process' environment. This token is single use and has a short TTL. Once
2017-08-08 16:39:19 +00:00
unwrapped, it provides the plugin with a uniquely generated TLS certificate and
2018-04-24 17:41:37 +00:00
private key for it to use to talk to the original Vault process.
2017-08-08 16:39:19 +00:00
2021-07-20 13:21:24 +00:00
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.
2017-12-05 17:01:35 +00:00
2017-08-08 16:39:19 +00:00
~> Note: Reading the original connection's TLS connection state is not supported
in plugins.
2017-05-02 08:59:36 +00:00
## Plugin Registration
2020-01-18 00:18:09 +00:00
2017-05-02 09:22:06 +00:00
An important consideration of Vault's plugin system is to ensure the plugin
2018-04-24 17:41:37 +00:00
invoked by Vault is authentic and maintains integrity. There are two components
2017-05-02 23:20:07 +00:00
that a Vault operator needs to configure before external plugins can be run, the
plugin directory and the plugin catalog entry.
2017-05-02 08:59:36 +00:00
### Plugin Directory
2020-01-18 00:18:09 +00:00
2017-05-02 08:59:36 +00:00
The plugin directory is a configuration option of Vault, and can be specified in
2020-01-22 20:05:41 +00:00
the [configuration file](/docs/configuration).
2019-10-07 13:59:34 +00:00
This setting specifies a directory in which all plugin binaries must live;
_this value cannot be a symbolic link_. A plugin
2018-04-24 17:41:37 +00:00
can not be added to Vault unless it exists in the plugin directory. There is no
2017-05-02 08:59:36 +00:00
default for this configuration option, and if it is not set plugins can not be
2018-04-24 17:41:37 +00:00
added to Vault.
2017-05-02 08:59:36 +00:00
2018-04-24 17:41:37 +00:00
~> Warning: A Vault operator should take care to lock down the permissions on
2017-05-02 08:59:36 +00:00
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
2020-01-18 00:18:09 +00:00
2017-05-02 08:59:36 +00:00
The plugin catalog is Vault's list of approved plugins. The catalog is stored in
2018-04-24 17:41:37 +00:00
Vault's barrier and can only be updated by a Vault user with sudo permissions.
2017-05-02 23:20:07 +00:00
Upon adding a new plugin, the plugin name, SHA256 sum of the executable, and the
2017-05-02 09:22:06 +00:00
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,
2017-06-06 13:49:49 +00:00
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
2020-01-22 20:05:41 +00:00
docs](/api/system/plugins-catalog).
2017-06-06 13:49:49 +00:00
2021-03-17 23:04:51 +00:00
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
```
2021-04-06 17:49:04 +00:00
Vault versions prior to v0.10.4 lacked the `vault plugin` operator and the
2021-03-17 23:04:51 +00:00
registration step for them is:
2017-06-06 13:49:49 +00:00
2020-05-21 17:18:17 +00:00
```shell-session
2018-11-14 17:17:12 +00:00
$ vault write sys/plugins/catalog/database/myplugin-database-plugin \
2021-03-17 23:04:51 +00:00
sha256=<SHA256 Hex value of the plugin binary> \
command="myplugin"
2018-11-14 17:17:12 +00:00
Success! Data written to: sys/plugins/catalog/database/myplugin-database-plugin
2017-06-06 13:49:49 +00:00
```
2017-05-02 08:59:36 +00:00
### Plugin Execution
2020-01-18 00:18:09 +00:00
2017-05-02 09:22:06 +00:00
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
2018-04-24 17:41:37 +00:00
configured in the plugin catalog. Finally Vault runs the command configured in
2017-05-02 09:22:06 +00:00
the catalog, sending along the JWT formatted response wrapping token and mlock
2020-06-22 17:05:15 +00:00
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.
2017-05-02 08:59:36 +00:00
2021-08-03 22:58:17 +00:00
### 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).
2021-06-14 19:50:43 +00:00
### 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>
```
2017-05-02 08:59:36 +00:00
# Plugin Development
2017-08-08 16:39:19 +00:00
~> 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.
2017-05-02 08:59:36 +00:00
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).
2017-05-18 18:06:44 +00:00
Your plugin implementation needs to satisfy the interface for the plugin
2017-05-02 08:59:36 +00:00
type you want to build. You can find these definitions in the docs for the
backend running the plugin.
```go
package main
import (
2017-08-09 18:41:17 +00:00
"os"
2018-03-16 13:05:01 +00:00
2019-07-05 22:35:36 +00:00
myPlugin "your/plugin/import/path"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/sdk/plugin"
2017-05-02 08:59:36 +00:00
)
func main() {
2019-07-05 22:35:36 +00:00
apiClientMeta := &api.PluginAPIClientMeta{}
2017-08-09 18:41:17 +00:00
flags := apiClientMeta.FlagSet()
2019-07-05 22:35:36 +00:00
flags.Parse(os.Args[1:])
2018-03-16 13:05:01 +00:00
2019-07-05 22:35:36 +00:00
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)
}
2017-05-02 08:59:36 +00:00
}
```
2019-07-05 22:35:36 +00:00
And that's basically it! You would just need to change `myPlugin` to your actual
plugin. 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.
2017-12-05 17:01:35 +00:00
2020-01-22 20:05:41 +00:00
[api_addr]: /docs/configuration#api_addr