Golang

The HTTP Golang filter allows Golang to be run during both the request and response flows and makes it easier to extend Envoy.

Go plugins used by this filter can be recompiled independently of Envoy.

See the Envoy’s Golang extension proposal documentation for more details on the filter’s implementation.

Developing a Go plugin

Envoy’s Go plugins must implement the StreamFilter API.

Attention

The Go plugin API is not yet stable, you are strongly recommended to use the same version of Go plugin SDK and Envoy.

When you are using a release version of Envoy, i.e. 1.26.x, you should use github.com/envoyproxy/envoy v1.26.x in the go.mod file.

When you are not using a release, i.e. the latest main branch of Envoy, you could use go get -u github.com/envoyproxy/envoy@SHA to get the same version of Go plugin SDK, the SHA is the latest commit sha.

Building a Go plugin

Attention

When building a Go plugin dynamic library, you must use a Go version consistent with Envoy’s version of glibc.

One way to ensure a compatible Go version is to use the Go binary provided by Envoy’s bazel setup:

$ bazel run @go_sdk//:bin/go -- version
...
go version goX.YZ linux/amd64

For example, to build the .so for a foo plugin, you might run:

$ bazel run @go_sdk//:bin/go build -- --buildmode=c-shared  -v -o path/to/output/libfoo.so path/to/src/foo

Configuration

Tip

This filter should be configured with the type URL type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config.

A prebuilt Golang HTTP filter my_plugin.so might be configured as follows:

16          http_filters:
17          - name: envoy.filters.http.golang
18            typed_config:
19              "@type": type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config
20              library_id: my-plugin-id
21              library_path: "lib/my_plugin.so"
22              plugin_name: my_plugin
23          - name: envoy.filters.http.header_to_metadata

An HttpConnectionManager can have multiple Go plugins in its http_filters:

16          http_filters:
17          - name: envoy.filters.http.golang
18            typed_config:
19              "@type": type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config
20              library_id: my-plugin-id
21              library_path: "lib/my_plugin.so"
22              plugin_name: my_plugin
23          - name: envoy.filters.http.header_to_metadata
24            typed_config:
25              "@type": type.googleapis.com/envoy.extensions.filters.http.header_to_metadata.v3.Config
26          - name: envoy.filters.http.golang
27            typed_config:
28              "@type": type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config
29              library_id: my-other-plugin-id
30              library_path: "lib/my_other_plugin.so"
31              plugin_name: my_other_plugin
32          - name: envoy.filters.http.router
33            typed_config:

This can be useful if, for example, you have one plugin that provides authentication, and another that provides connection limiting.

Extensible plugin configuration

Envoy’s Go plugins can specify and use their own configuration.

Below is a very simple example of how such a plugin might be configured in Envoy:

17          - name: envoy.filters.http.golang
18            typed_config:
19              "@type": type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config
20              library_id: my-configurable-plugin-id
21              library_path: "lib/my_configurable_plugin.so"
22              plugin_name: my_configurable_plugin
23              plugin_config:
24                "@type": type.googleapis.com/xds.type.v3.TypedStruct
25                value:
26                  foo: bar
27          - name: envoy.filters.http.router

See the StreamFilter API for more information about how the plugin’s configuration data can be accessed.

Per-route plugin configuration

Go plugins can be configured on a per-route basis, as in the example below:

16          http_filters:
17          - name: envoy.filters.http.golang
18            typed_config:
19              "@type": type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config
20              library_id: my-configurable-plugin-id
21              library_path: "lib/my_configurable_plugin.so"
22              plugin_name: my_configurable_plugin
23              plugin_config:
24                "@type": type.googleapis.com/xds.type.v3.TypedStruct
25                value:
26                  foo: default_foo
27          - name: envoy.filters.http.router
28            typed_config:
29              "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
30          route_config:
31            name: route_0
32            virtual_hosts:
33            - name: service_0
34              domains: ["*"]
35              routes:
36              - match:
37                  prefix: "/"
38                route:
39                  cluster: cluster_0
40            typed_per_filter_config:
41              envoy.filters.http.golang:
42                "@type": type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.ConfigsPerRoute
43                plugins_config:
44                  my_configurable_plugin:

Per-virtualhost plugin configuration

Go plugins can also be configured on a per-virtualhost basis:

 1          http_filters:
 2          - name: envoy.filters.http.golang
 3            typed_config:
 4              "@type": type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config
 5              library_id: my-configurable-plugin-id
 6              library_path: "lib/my_configurable_plugin.so"
 7              plugin_name: my_configurable_plugin
 8              plugin_config:
 9                "@type": type.googleapis.com/xds.type.v3.TypedStruct
10                value:
11                  foo: default_foo
12          - name: envoy.filters.http.router
13            typed_config:
14              "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
15          route_config:
16            name: route_0
17            virtual_hosts:
18            - name: service_0
19              domains: ["*"]
20              routes:
21              - match:
22                  prefix: "/"
23                route:
24                  cluster: cluster_0
25                typed_per_filter_config:
26                  envoy.filters.http.golang:
27                    "@type": type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.ConfigsPerRoute
28                    plugins_config:
29                      my_configurable_plugin:

Complete example

Learn more about building and running a plugin for the Envoy Go filter in the step by step Envoy Go Sandbox.