Envoy is a cloud native opensource proxy server. The Envoy proxy offers a variety of http filters to handle incoming requests.
Out of them External authorisation is a filter type that directs an incoming request to an external service and waits for its authorisation to continue the request.The external service, which has the ability to modify or suspend the incoming request, can be either a grpc_service or a http_service.
Working example: prakashchokalingam/envoy_ext_auth_grpc_go
Let's look at connecting a GRPC-based Golang service using the Envoy external auth filter.
Create a golang grpc based server:
main.go
package main
import (
"fmt"
"net"
"google.golang.org/grpc"
)
func main() {
endPoint := fmt.Sprintf("localhost:%d", 3001)
listen, err := net.Listen("tcp", endPoint)
grpcServer := grpc.NewServer()
grpcServer.Serve(listen)
}
Extend with go-control-plane protobuf
The above server should be extended and registered with the envoyproxy go-control-plane protobuf server with a check function defined struct.
main.go
package main
import (
"fmt"
"net"
auth_pb "github.com/envoyproxy/go-control-plane/envoy/service/auth/v3"
"google.golang.org/grpc"
)
func main() {
// struct with check method
type AuthServer struct {}
func (server *AuthServer) Check(
ctx context.Context,
request *auth_pb.CheckRequest,
) (*auth_pb.CheckResponse, error) {
fmt.println("All request goes through me")
// block if path is /private
path = request.Attributes.Request.Http.Path[1:]
if path == 'private' {
return nil, fmt.Errorf('private request not allowed')
}
// allow all other requests
return &auth_pb.CheckResponse{}, nil
}
endPoint := fmt.Sprintf("localhost:%d", 3001)
listen, err := net.Listen("tcp", endPoint)
grpcServer := grpc.NewServer()
// register envoy proto server
server := &AuthServer{}
auth_pb.RegisterAuthorizationServer(grpcServer, server)
grpcServer.Serve(listen)
}
If nil is returned in the check method rather than &auth_pb.CheckResponse, the request will be suspended with a 403 error code.
Note: Envoy will also return 403 if the service is offline or unreachable.
Last but not least, set up your Envoy
In your envoy config add the filter envoy.filters.http.ext_authz
and point it to the Go service cluster
envoy.yml
static_resources:
listeners:
- name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 80 }
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
codec_type: auto
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
...
http_filters:
- name: envoy.filters.http.ext_authz
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
transport_api_version: v3
grpc_service:
envoy_grpc:
cluster_name: go_grpc_cluster
include_peer_certificate: true
...
clusters:
- name: go_grpc_cluster
connect_timeout: 0.25s
type: LOGICAL_DNS
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
"@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicit_http_config:
http2_protocol_options: {}
load_assignment:
cluster_name: go_grpc_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 3001
To see an example snippet for customising headers, click here
Check out this repository for a fully functional code sample
prakashchokalingam / envoy_ext_auth_grpc_go
Working example of envoy external auth filter with go lang grpc service
Example repo to demonstrate Envoy External Authorization with Golang GRPC service
This repository provides an envoy configuration file with an external auth filter activated for all incoming routes at port 8080
The envoy is configured with two clusters,
The filter envoy.filters.http.ext_authz
in envoy is pointed at this go grpc cluster. All incoming requests will be forwarded to this cluster.
The Check method will be called during a request; it then adds a custom header to all other requests and rejects requests with the path '/private'.
Request
grpc_filter
status
http_server_response
/
x-custom-header = "Hello World"
200
Hello World
/ private
403
-
-
It is a straightforward Golang HTTP server that merely emits the custom header value x-custom-header
added via the go_grpc_filter cluster.
To run this example
- Start the envoy server
envoy -c envoy.yml
- start the go_grpc_filter & go_simple_http servers by navigating to the cluster root.
go run main.go
- …
Top comments (0)