{"id":13481583,"url":"https://github.com/hashicorp/go-plugin","last_synced_at":"2025-09-09T20:11:49.708Z","repository":{"id":38311094,"uuid":"50128165","full_name":"hashicorp/go-plugin","owner":"hashicorp","description":"Golang plugin system over RPC.","archived":false,"fork":false,"pushed_at":"2025-03-27T10:39:50.000Z","size":482,"stargazers_count":5480,"open_issues_count":88,"forks_count":476,"subscribers_count":353,"default_branch":"main","last_synced_at":"2025-05-05T14:19:03.329Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hashicorp.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-01-21T18:33:57.000Z","updated_at":"2025-05-05T07:15:50.000Z","dependencies_parsed_at":"2023-10-16T21:06:47.766Z","dependency_job_id":"213dcff2-1918-4efe-87f9-a0d017b1b992","html_url":"https://github.com/hashicorp/go-plugin","commit_stats":{"total_commits":253,"total_committers":61,"mean_commits":4.147540983606557,"dds":0.691699604743083,"last_synced_commit":"edcdee4bf2988be29bef88954e2b053f443a26b0"},"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hashicorp%2Fgo-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hashicorp%2Fgo-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hashicorp%2Fgo-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hashicorp%2Fgo-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hashicorp","download_url":"https://codeload.github.com/hashicorp/go-plugin/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253775076,"owners_count":21962284,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T17:00:53.076Z","updated_at":"2025-05-12T16:25:32.505Z","avatar_url":"https://github.com/hashicorp.png","language":"Go","funding_links":[],"categories":["Go","Misc"],"sub_categories":[],"readme":"# Go Plugin System over RPC\n\n`go-plugin` is a Go (golang) plugin system over RPC. It is the plugin system\nthat has been in use by HashiCorp tooling for over 4 years. While initially\ncreated for [Packer](https://www.packer.io), it is additionally in use by\n[Terraform](https://www.terraform.io), [Nomad](https://www.nomadproject.io),\n[Vault](https://www.vaultproject.io),\n[Boundary](https://www.boundaryproject.io),\nand [Waypoint](https://www.waypointproject.io).\n\nWhile the plugin system is over RPC, it is currently only designed to work\nover a local [reliable] network. Plugins over a real network are not supported\nand will lead to unexpected behavior.\n\nThis plugin system has been used on millions of machines across many different\nprojects and has proven to be battle hardened and ready for production use.\n\n## Features\n\nThe HashiCorp plugin system supports a number of features:\n\n**Plugins are Go interface implementations.** This makes writing and consuming\nplugins feel very natural. To a plugin author: you just implement an\ninterface as if it were going to run in the same process. For a plugin user:\nyou just use and call functions on an interface as if it were in the same\nprocess. This plugin system handles the communication in between.\n\n**Cross-language support.** Plugins can be written (and consumed) by\nalmost every major language. This library supports serving plugins via\n[gRPC](http://www.grpc.io). gRPC-based plugins enable plugins to be written\nin any language.\n\n**Complex arguments and return values are supported.** This library\nprovides APIs for handling complex arguments and return values such\nas interfaces, `io.Reader/Writer`, etc. We do this by giving you a library\n(`MuxBroker`) for creating new connections between the client/server to\nserve additional interfaces or transfer raw data.\n\n**Bidirectional communication.** Because the plugin system supports\ncomplex arguments, the host process can send it interface implementations\nand the plugin can call back into the host process.\n\n**Built-in Logging.** Any plugins that use the `log` standard library\nwill have log data automatically sent to the host process. The host\nprocess will mirror this output prefixed with the path to the plugin\nbinary. This makes debugging with plugins simple. If the host system\nuses [hclog](https://github.com/hashicorp/go-hclog) then the log data\nwill be structured. If the plugin also uses hclog, logs from the plugin\nwill be sent to the host hclog and be structured.\n\n**Protocol Versioning.** A very basic \"protocol version\" is supported that\ncan be incremented to invalidate any previous plugins. This is useful when\ninterface signatures are changing, protocol level changes are necessary,\netc. When a protocol version is incompatible, a human friendly error\nmessage is shown to the end user.\n\n**Stdout/Stderr Syncing.** While plugins are subprocesses, they can continue\nto use stdout/stderr as usual and the output will get mirrored back to\nthe host process. The host process can control what `io.Writer` these\nstreams go to to prevent this from happening.\n\n**TTY Preservation.** Plugin subprocesses are connected to the identical\nstdin file descriptor as the host process, allowing software that requires\na TTY to work. For example, a plugin can execute `ssh` and even though there\nare multiple subprocesses and RPC happening, it will look and act perfectly\nto the end user.\n\n**Host upgrade while a plugin is running.** Plugins can be \"reattached\"\nso that the host process can be upgraded while the plugin is still running.\nThis requires the host/plugin to know this is possible and daemonize\nproperly. `NewClient` takes a `ReattachConfig` to determine if and how to\nreattach.\n\n**Cryptographically Secure Plugins.** Plugins can be verified with an expected\nchecksum and RPC communications can be configured to use TLS. The host process\nmust be properly secured to protect this configuration.\n\n## Architecture\n\nThe HashiCorp plugin system works by launching subprocesses and communicating\nover RPC (using standard `net/rpc` or [gRPC](http://www.grpc.io)). A single\nconnection is made between any plugin and the host process. For net/rpc-based\nplugins, we use a [connection multiplexing](https://github.com/hashicorp/yamux)\nlibrary to multiplex any other connections on top. For gRPC-based plugins,\nthe HTTP2 protocol handles multiplexing.\n\nThis architecture has a number of benefits:\n\n  * Plugins can't crash your host process: A panic in a plugin doesn't\n    panic the plugin user.\n\n  * Plugins are very easy to write: just write a Go application and `go build`.\n    Or use any other language to write a gRPC server with a tiny amount of\n    boilerplate to support go-plugin.\n\n  * Plugins are very easy to install: just put the binary in a location where\n    the host will find it (depends on the host but this library also provides\n    helpers), and the plugin host handles the rest.\n\n  * Plugins can be relatively secure: The plugin only has access to the\n    interfaces and args given to it, not to the entire memory space of the\n    process. Additionally, go-plugin can communicate with the plugin over\n    TLS.\n\n## Usage\n\nTo use the plugin system, you must take the following steps. These are\nhigh-level steps that must be done. Examples are available in the\n`examples/` directory.\n\n  1. Choose the interface(s) you want to expose for plugins.\n\n  2. For each interface, implement an implementation of that interface\n     that communicates over a `net/rpc` connection or over a\n     [gRPC](http://www.grpc.io) connection or both. You'll have to implement\n     both a client and server implementation.\n\n  3. Create a `Plugin` implementation that knows how to create the RPC\n     client/server for a given plugin type.\n\n  4. Plugin authors call `plugin.Serve` to serve a plugin from the\n     `main` function.\n\n  5. Plugin users use `plugin.Client` to launch a subprocess and request\n     an interface implementation over RPC.\n\nThat's it! In practice, step 2 is the most tedious and time consuming step.\nEven so, it isn't very difficult and you can see examples in the `examples/`\ndirectory as well as throughout our various open source projects.\n\nFor complete API documentation, see [GoDoc](https://godoc.org/github.com/hashicorp/go-plugin).\n\n## Roadmap\n\nOur plugin system is constantly evolving. As we use the plugin system for\nnew projects or for new features in existing projects, we constantly find\nimprovements we can make.\n\nAt this point in time, the roadmap for the plugin system is:\n\n**Semantic Versioning.** Plugins will be able to implement a semantic version.\nThis plugin system will give host processes a system for constraining\nversions. This is in addition to the protocol versioning already present\nwhich is more for larger underlying changes.\n\n## What About Shared Libraries?\n\nWhen we started using plugins (late 2012, early 2013), plugins over RPC\nwere the only option since Go didn't support dynamic library loading. Today,\nGo supports the [plugin](https://golang.org/pkg/plugin/) standard library with\na number of  limitations. Since 2012, our plugin system has stabilized \nfrom tens of millions of users using it, and has many benefits we've come to \nvalue greatly.\n\nFor example, we use this plugin system in\n[Vault](https://www.vaultproject.io) where dynamic library loading is\nnot acceptable for security reasons. That is an extreme\nexample, but we believe our library system has more upsides than downsides\nover dynamic library loading and since we've had it built and tested for years,\nwe'll continue to use it.\n\nShared libraries have one major advantage over our system which is much\nhigher performance. In real world scenarios across our various tools,\nwe've never required any more performance out of our plugin system and it\nhas seen very high throughput, so this isn't a concern for us at the moment.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhashicorp%2Fgo-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhashicorp%2Fgo-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhashicorp%2Fgo-plugin/lists"}