Envoy extension
Synapse implements the Envoy external authorization API natively and its behaviour can be configured either declratively or programmatically.
A typical Envoy configuration to use Synapse as the external authorization service is as follows.
static_resources:
listeners:
- name: listener_0
address:
socket_address:
address: 0.0.0.0
port_value: 8080
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
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: synapse
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
route_config:
...
clusters:
- name: synapse
type: STATIC
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: synapse
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 3594
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
sni: synapse.localhost
common_tls_context:
validation_context:
trust_chain_verification: ACCEPT_UNTRUSTED
Declarative mapping
Map Envoy Check requests to Cerbos CheckResources and back using CEL expressions.
extensions:
envoyExternalAuthz:
enabled: true (1)
mapping: (2)
request:
requestID: 'request.attributes.request.http.headers["x-request-id"]'
principal:
id: 'request.attributes.request.http.headers["x-user-id"]'
roles: '["user"]'
resource:
id: '"foo"'
kind: '"request"'
action: "request.attributes.request.http.method"
| 1 | Enable the Envoy Check endpoint on the server |
| 2 | Declarative mapping of request and response. See below for mapping reference. |
Mapping reference
Documentation about Cerbos request and response formats can be found at https://docs.cerbos.dev/cerbos/latest/api/#_request_and_response_formats. For Envoy Check request and response formats, refer to https://buf.build/envoyproxy/envoy/docs/main:envoy.service.auth.v3#envoy.service.auth.v3.CheckRequest.
|
-
request(required):-
requestID: a CEL expression returning a string. -
principal(required):-
id(required): a CEL expression returning a string. -
roles(required): a CEL expression returning a list of strings, or a list of CEL expressions each returning a string. -
attr: a CEL expression returning a map of strings to values, or a map of strings to CEL expressions each returning a value. -
policyVersion: a CEL expression returning a string. -
scope: a CEL expression returning a string.
-
-
resource(required):-
kind(required): a CEL expression returning a string. -
id(required): a CEL expression returning a string. -
attr: a CEL expression returning a map of strings to values, or a map of strings to CEL expressions each returning a value. -
policyVersion: a CEL expression returning a string. -
scope: a CEL expression returning a string.
-
-
action(required): a CEL expression returning a string. -
auxData:-
jwt:-
token: a CEL expression returning a string. -
keySetID: a CEL expression returning a string.
-
-
-
-
response:-
status: a CEL expression returning an HTTP status code as an integer. Defaults to 200 when allowed and 403 when denied. -
headers: a CEL expression returning a map of strings to strings, or a map of strings to CEL expressions each returning a string. -
body: a CEL expression returning bytes or a string.
-
Request expressions have access to the incoming HTTP request in the CEL variable request, which has the following fields:
-
method: the request’s HTTP method as an uppercase string. -
header: map of HTTP request headers. Keys are header names in canonical form and values are strings (comma-separated when multiple headers with the same name are present in the request). -
headers: map of HTTP request headers. Keys are header names in canonical form and values are lists of strings. -
body: object with the following fields:-
bytes: the raw request body -
text: the request body as a string -
json: the JSON-decoded request body
-
Response expressions have access to the CheckResources result in the CEL variable check which has the following fields:
-
requestId,principal,resource, andaction: the inputs produced by the request expressions. -
cerbosCallId: the ID for audit logging as a string. -
allow: whether the action is allowed as a boolean. -
outputs: the output from the policy as a map of source (policy-id#rule-name) to value. -
validationErrors: errors encountered when validating the principal and resource against the corresponding schemas as a list ofcerbos.schema.v1.ValidationErrormessages.
Using the YAML scalar block syntax > for CEL expressions is recommended to avoid quoting issues. action: "view" would be interpreted as the CEL expression view (which would fail to compile because a variable named view is not defined), when the desired setting was the CEL expression "view" (which just returns the intended string literal).
extensions:
envoyExternalAuthz:
enabled: true
mapping:
request:
requestID: 'request.attributes.request.http.headers["x-request-id"]'
principal:
id: 'request.attributes.request.http.headers["x-user-id"]'
roles: '["user"]'
resource:
id: '"foo"'
kind: '"request"'
action: "request.attributes.request.http.method"
extensions:
envoyExternalAuthz:
enabled: true
mapping:
request:
requestID: 'request.attributes.request.http.headers["x-request-id"]'
principal:
id: 'request.attributes.request.http.headers["x-user-id"]'
roles: '["user"]'
resource:
id: '"foo"'
kind: '"request"'
action: "request.attributes.request.http.method"
response: >
check.allow ? {"status": {"code": google.rpc.Code.OK }} : {
"status": {"code": google.rpc.Code.OK },
"deniedResponse": {
"status": {"code": 401 },
"body": json.encode(check.outputs["resource.example.v1#route"].body)
}
}
Programmatic mapping
extensions:
envoyExternalAuthz:
enabled: true (1)
extension:
extensionURL: /extensions/envoy.wasm (2)
configuration: (3)
environment: staging
| 1 | Enable the Envoy Check endpoint. |
| 2 | URL to fetch the extension from. See extension URL format for more information. |
| 3 | Configuration values needed by the extension. [Optional] |