A Go-based extensible external processing server for Envoy Proxy, designed to handle HTTP request/response processing through Envoy's External Processing API.
Originally based on envoy-extproc-sdk-go
This server implements Envoy's External Processing service to intercept and modify HTTP requests and responses. It supports a plugin architecture that allows for both built-in Go plugins and WebAssembly modules.
- Plugin Architecture: Extensible filter chain system supporting multiple plugin types
- Built-in Plugins: Ready-to-use filters for common processing tasks
- Go Plugin Support: Dynamic loading of Go shared object plugins
- WebAssembly Support: Execute Wasm modules for custom processing logic
- Configuration-Driven: YAML-based configuration for easy deployment
- Docker Support: Containerized deployment with Docker Compose
- Go 1.21+
- just (for build automation)
- Docker & Docker Compose (for containerized deployment)
# Build all components
just build
# Run with default configuration
go run main.go -c ext-server.yaml
# Or using just
just run# Build and start with Docker Compose
just up
# Test the setup
just call /
# Stop services
just downThe server is configured via YAML files. Example configuration (ext-server.yaml):
filter_chains:
- filters:
- name: timer
type: built-in
- name: wasm
type: go-plugin
path: plugins/wasm/goplugin/wasm.so
config:
name: hello
path: plugins/wasm/wasm/hello.wasm
- name: trivial
type: built-in- listen: Server listen address (default:
tcp://:50051) - filter_chains: Array of filter chain configurations
- filters: Array of filter definitions
- name: Plugin identifier
- type: Plugin type (
built-in,go-plugin) - path: Path to plugin shared object (for
go-plugintype) - config: Plugin-specific configuration
- filters: Array of filter definitions
- noop: No-operation filter for testing
- timer: Adds timing information to requests
- trivial: Simple request/response modification example
- wasm: WebAssembly module executor
- hello: Example Wasm module demonstrating basic functionality
├── main.go # Application entry point
├── ext-server.yaml # Default configuration
├── extproc/ # Envoy external processing implementation
├── pluginapi/ # Plugin API and interfaces
├── plugins/ # Plugin implementations
│ ├── noop/ # No-operation plugin
│ ├── timer/ # Timer plugin
│ ├── trivial/ # Trivial example plugin
│ └── wasm/ # WebAssembly plugin
├── e2e/ # End-to-end tests
└── justfile # Build automation
# Development
just format # Format Go code
just test # Run unit tests
just build # Build all components
just clean # Clean build artifacts
# Running
just run # Run server with default config
# Docker
just up # Build and start with Docker Compose
just down # Stop Docker services
just call # Make test HTTP requests
# Maintenance
just update # Update dependencies
just tidy # Clean up Go modules- Create a new directory under
plugins/ - Implement the
Plugininterface frompluginapi - Register the plugin in the filter chain factory
- Create a
gopluginsubdirectory in your plugin directory - Implement a
main.gowith aNewfunction returning aPluginFactory - Build as a shared object:
go build -buildmode=plugin
- Write your Wasm module in Go (or any WASM-compatible language)
- Compile to Wasm (TinyGo is generally preferred)
- Configure the Wasm plugin to load your module
The server exposes Envoy's External Processing gRPC service on port 50051 (configurable). It implements the following service methods:
Process: Stream processing of HTTP requests/responsesHealthCheck: Health checking endpoint
just test# Start the full stack
just up
# Make test requests
just call /
just call /health
# Check Envoy admin interface
curl localhost:9901/statsThe system follows a modular architecture:
- Server Layer: gRPC server implementing Envoy's External Processing API
- Processing Layer: Request/response context management
- Plugin Layer: Configurable filter chain with plugin support
- Configuration Layer: YAML-based configuration management