Service Extensions lets you make a callout from networking proxies. Callout extensions are supported by most Application Load Balancers. Callout extensions are also supported by Secure Web Proxy (in Preview).
Callouts data flow
A networking proxy communicates with a callout by using one of the following Envoy gRPC protocols:
The External Processing or
ext_procprotocol.This protocol is supported for route, traffic, and authorization extensions and is used by default.
The
ext_procprotocol lets the extension service respond to events in the lifecycle of an HTTP request by examining and modifying the headers or the body of the request.The External Authorization or
ext_authzprotocol.This protocol is supported only for authorization extensions.
The
ext_authzprotocol delegates authorization decisions for incoming requests to an external, independent service. This API lets the extension service respond to events in the lifecycle of an HTTP request for complex authorization decision by examining the headers or metadata of the request.You can specify this protocol with the
wireFormatoption when you configure an authorization extension.
You can deploy these extension services on virtual machine (VM) instances or on GKE and configure an instance group or network endpoint group (NEG) to represent the endpoints for these services.
Sample deployment scenario
The following diagram shows a sample deployment scenario. You can deploy the callout backend service with a gRPC server on a user-managed compute resource—such as a VM instance or Google Kubernetes Engine (GKE) cluster—and represent it to the load balancer as a regular backend service.
How callouts work with ext_proc
An abbreviated version of the ext_proc gRPC API is as follows.
// The gRPC API to be implemented by the external processing server service ExternalProcessor { rpc Process(stream ProcessingRequest) returns (stream ProcessingResponse) { } } // Envoy sets one of these fields depending on the processing stage. message ProcessingRequest { oneof request { HttpHeaders request_headers = 2; HttpHeaders response_headers = 3; HttpBody request_body = 4; HttpBody response_body = 5; } } message ProcessingResponse { oneof response { HeadersResponse request_headers = 1; HeadersResponse response_headers = 2; BodyResponse request_body = 3; BodyResponse response_body = 4; ImmediateResponse immediate_response = 7; } }
After receiving the headers for an HTTP request, Application Load Balancer
and Secure Web Proxy proxies send the ProcessingRequest message to the
extension service with the request_headers field set to the HTTP headers from
the client.
The extension service must respond to the ProcessingRequest message with a
corresponding ProcessingResponse message that contains any configured changes
to the headers or body of the ProcessingRequest message. Alternatively, the
service can set the immediate_response field to make the networking
proxy end request processing and send the specified response back to the
client.
For REQUEST_HEADER and RESPONSE_HEADER events, the extension service can
manipulate the HTTP headers in the request or response. The service can add,
modify, or delete headers by setting the request_headers or response_headers
field in the ProcessingResponse message appropriately. Use the raw_value
field for headers.
Traffic extensions allow changing the headers and the body of both requests and responses. The extension server can override the processing mode dynamically and allow it to enable or disable the extension for subsequent phases of request processing. Load balancers don't reevaluate route rules after calling a traffic extension.
Edge, authorization, and route extensions support only HTTP headers. These extensions can't inspect or mutate HTTP bodies.
For route and traffic extensions, callouts can execute asynchronously when
observabilityMode for the extension is set to true and the body processing mode
is STREAMED (default). Calls to the extension backend are performed
asynchronously, without pausing the processing of the ongoing request.
Responses, if any, are ignored.
Access attributes in callouts
For callout extensions that use the ext_proc protocol, the configured
attributes are sent in the ProcessingRequest message. The attributes are
stored in a map field, typically under a key such as
envoy.filters.http.ext_proc.
The keys in the map correspond to the attribute names that you specified in the
forwardAttributes field of your extension configuration.
The following example shows the structure of ProcessingRequest.attributes:
attributes { key: "envoy.filters.http.ext_proc" value { fields { key: "request.host" value { string_value: "example.com" } } fields { key: "source.client_region" value { string_value: "US" } } // ... other forwarded attributes } }
Your gRPC service implementation can access these values from the map in the
ProcessingRequest messages that you received.
How callouts work with ext_authz
The ext_authz API supports only authorization callout extensions.
An abbreviated version of the API is as follows.
// A generic interface for performing authorization checks on incoming // requests to a networked service. service Authorization { // Performs an authorization check based on the attributes associated with // the incoming request and return status. rpc Check(CheckRequest) returns (CheckResponse) { } } message CheckRequest { // The request attributes. AttributeContext attributes = 1; } message CheckResponse { google.rpc.Status status = 1; oneof http_response { DeniedHttpResponse denied_response = 2; OkHttpResponse ok_response = 3; } google.protobuf.Struct dynamic_metadata = 4; }
After receiving the headers for an HTTP request, the load balancer sends the
CheckRequest message to the extension service.
The extension service must respond to the CheckRequest message with a
corresponding CheckResponse message that contains the following information: