Route extensions :: Cerbos Authorization Management Platform // Documentation

Route extensions

Route extensions are a way to register arbitrary HTTP handlers on Synapse to provide external authorization endpoints. Many systems such as gateways, proxies, query engines and queues have support for delegating access control to another system by calling into a specific endpoint with information about the access decision to be made. Route extensions enable using Cerbos policies to make those decisions by defining how to map the requests and responses to the format required by each component.

Synapse route extensions can be defined in two ways.

Route definitions

Regardless of the mapping type used, the routes to which they should apply are defined as a map of paths to allowed HTTP methods.

All route extensions are served under the /ext/ prefix of Synapse server. This is implicitly prepended to the paths defined in the routes section.
extensions:
  routeExtensions:
    foo:
      routes:
        "/team-a/foo": [] (1)
        "/team-b/{baz}": ["GET"] (2)
1 Activate the extension for requests sent via any HTTP method to /ext/team-a/foo. This is an exact match.
2 Activate the extension for GET requests to /ext/team-b/<ANY VALUE>. The curly braces around the second path component define a wildcard that matches any value.

Declarative mapping

This extension allows users to define mappings for the request/response conversion using CEL expressions.

extensions:
  routeExtensions:
    foo: (1)
      mapping:
        request: (2)
          requestID: 'request.header["X-Request-Id"]'
          principal:
            id: '"abc"'
            roles: '["user"]'
            attr: "request.body.json"
          resource:
            id: '"test"'
            kind: '"request"'
          action: "request.method"
        response: (3)
          status: "check.allow ? 200 : 403"
          body: "check.requestID"
      routes: (4)
        "/bar": ["GET", "POST"]
        "/baz/{baz}": []
1 Unique name for the instance
2 Section for defining how to map the incoming HTTP request into a Cerbos CheckResources request
3 Section for defining how to map the Cerbos response into the HTTP response expected by the caller
4 Routes to which this mapping applies. See the pop-out section above for more information about defining routes.

Mapping reference

Documentation about Cerbos request and response formats can be found at https://docs.cerbos.dev/cerbos/latest/api/#_request_and_response_formats.

Request expressions have access to the incoming HTTP request in the CEL variable request, which has the following fields:

Response expressions have access to the CheckResources result in the CEL variable check which has the following fields:

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).

Minimal configuration

extensions:
  routeExtensions:
    foo:
      mapping:
        request:
          principal:
            id: >
              request.header["X-User-Id"]
            roles:
              - >
                request.header["X-User-Role"]
          resource:
            kind: >
              request.body.json.kind
            id: >
              request.body.json.id
          action: >
            "view"

Customizing the response

extensions:
  routeExtensions:
    foo:
      mapping:
        request:
          # ...
        response:
          status: >
            check.allow ? 204 : 404
          headers:
            X-Cerbos-Call-Id: >
              check.cerbosCallId
          body: >
            json.encode({"outputs": check.outputs})

Programmatic mapping

extensions:
  routeExtensions:
    infra: (1)
      extension:
        extensionURL: "/extensions/infra.wasm?checksum=sha256:2b2e0ddc150e8563127ba9bd13199519b357c85ca5b3de598c4bcd5729599c6c" (2)
        configuration: (3)
          environment: staging
      routes: (4)
        "/team-a/foo": []
        "/team-b/{baz}": ["GET"]
1 Unique name for the extension
2 URL to fetch the extension from. See extension URL format for more information.
3 Configuration values needed by the extension. [Optional]
4 Routes to which this mapping applies. See the pop-out section above for more information about defining routes.

Building route extensions

See Building custom Synapse extensions.