140 lines
4.8 KiB
Plaintext
140 lines
4.8 KiB
Plaintext
---
|
|
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.
|
|
|
|
~> Note: Plugins should be prepared to handle multiple concurrent requests
|
|
from Vault.
|
|
|
|
## Serving A Plugin
|
|
|
|
### Serving A Plugin with Multiplexing
|
|
|
|
~> Plugin multiplexing requires `github.com/hashicorp/vault/sdk v0.5.4` or above.
|
|
|
|
The following code exhibits an example main package for a Vault plugin using
|
|
the Vault SDK for a secrets engine or auth method:
|
|
|
|
```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.ServeMultiplex(&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.
|
|
|
|
## Plugin Backwards Compatibility with Vault
|
|
|
|
Let's take a closer look at a snippet from the above main package.
|
|
|
|
```go
|
|
err := plugin.ServeMultiplex(&plugin.ServeOpts{
|
|
BackendFactoryFunc: myPlugin.Factory,
|
|
TLSProviderFunc: tlsProviderFunc,
|
|
})
|
|
```
|
|
|
|
The call to `plugin.ServeMultiplex` ensures that the plugin will use
|
|
Vault's [plugin
|
|
multiplexing](/vault/docs/plugins/plugin-architecture#plugin-multiplexing) feature.
|
|
However, this plugin will not be multiplexed if it is run by a version of Vault
|
|
that does not support multiplexing. Vault will simply fall back to a plugin
|
|
version that it can run. Additionally, we set the `TLSProviderFunc` to ensure
|
|
that our plugin is backwards compatible with versions of Vault that do not
|
|
support automatic mutual TLS for secure [plugin
|
|
communication](/vault/docs/plugins/plugin-architecture#plugin-communication). If you
|
|
are certain your plugin does not need backwards compatibility, this field can
|
|
be omitted.
|
|
|
|
[api_addr]: /vault/docs/configuration#api_addr
|
|
|
|
## Leveraging plugin versioning
|
|
|
|
@include 'plugin-versioning.mdx'
|
|
|
|
Auth and secrets plugins based on `framework.Backend` from the SDK should set the
|
|
[`RunningVersion`](https://github.com/hashicorp/vault/blob/sdk/v0.6.0/sdk/framework/backend.go#L95-L96)
|
|
variable, and the framework will implement the version interface.
|
|
|
|
Database plugins have a smaller API than `framework.Backend` exposes, and should
|
|
instead implement the
|
|
[`PluginVersioner`](https://github.com/hashicorp/vault/blob/sdk/v0.6.0/sdk/logical/logical.go#L150-L154)
|
|
interface directly.
|
|
|
|
## 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](/vault/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](/vault/tutorials/app-integration/plugin-backends)
|
|
tutorial.
|
|
|
|
Other HashiCorp plugin development resources:
|
|
|
|
* [vault-auth-plugin-example](https://github.com/hashicorp/vault-auth-plugin-example)
|
|
* [Custom Secrets Engines](/vault/tutorials/custom-secrets-engine)
|
|
|
|
### Plugin Development - Resources - Community
|
|
|
|
See the [Vault Integrations](/vault/integrations) page to find Community
|
|
plugin examples/guides developed by community members. HashiCorp does not
|
|
validate these for correctness.
|