Extensions

Synapse exposes four extension points. Each sits at a different stage of the authorization request lifecycle and addresses a different integration problem. Choosing the correct type is the first step when adding a capability to Synapse.

This page summarises the four types, the integration shape each one addresses, and the implementation options available across them. Each section links to the corresponding configuration reference.

Proxy extensions

Proxy extensions intercept CheckResources and PlanResources requests travelling through Synapse, and the corresponding responses on the way back. They can add, modify or remove attributes on the principal and resources before the PDP evaluates the request, and they can rewrite or redact fields on the response before it reaches the caller. Calling applications keep using the standard Cerbos API — the enrichment happens transparently.

Proxy extensions suit integrations of the form: look up data, attach it to the request, hand the request to the PDP. Common examples:

  • Fetching a principal’s department, team, region or tier from an internal directory or IAM service.

  • Loading resource metadata (owner, sensitivity, project) that is not carried in the API call.

  • Redacting sensitive fields from outputs blocks before they reach untrusted callers.

  • Attaching audit context (tenant, trace ID, correlation ID) that downstream systems will index on.

Route extensions

Route extensions register custom HTTP endpoints under Synapse’s `/ext/ path and translate their requests into Cerbos authorization calls. They exist because many systems — API gateways, query engines, message queues, legacy apps — know how to delegate authorization to an HTTP endpoint, but each expects its own request and response shape.

Route extensions suit third-party systems that already delegate authorization over HTTP but expect a protocol other than Cerbos’s. Common examples:

  • Plugging Trino, Kafka, or a custom gateway into Cerbos without modifying the upstream client.

  • Exposing a simplified "can-this-user-do-that" endpoint to internal tooling.

  • Running multiple translation layers at once — each on its own /ext/ path — from the same Synapse instance.

Envoy extension

The Envoy extension implements the Envoy external authorization API natively, so an Envoy proxy (or any Envoy-based ingress like Gloo, Contour, or Istio’s filter chain) can delegate authorization decisions to Synapse without a translation layer. The mapping from Envoy’s CheckRequest to Cerbos’s request is configured declaratively or programmatically on Synapse, not in Envoy.

The Envoy extension applies when authorization must happen at the edge or inside a service mesh, and the data plane already terminates at Envoy.

Data sources

Data sources are not wired into the request path directly. They are reusable, named lookup functions that other extensions call into via a data_source_lookup() call. A single data source — say, "employees" — can be shared by a proxy extension that enriches principals, a route extension that answers custom queries, and an envoy extension that mediates service-mesh traffic.

Data sources suit cases where several extensions call into the same underlying system (a database, an external API, an LLM) and the integration should live in one place. Synapse includes a built-in sqldb data source covering SQLite, MySQL, PostgreSQL and Litestream; custom data sources can be written in any of the supported runtimes.

Picking the right type

The following table maps common integration shapes to the extension type that fits best.

Integration shape Extension type

Enrich a Cerbos request before it reaches the PDP

Proxy extension

Modify or redact a Cerbos response before it reaches the caller

Proxy extension

Expose a custom authorization endpoint for a tool that already supports HTTP-based external authz

Route extension

Translate a non-Cerbos authorization protocol into a Cerbos decision

Route extension

Authorize Envoy traffic via its external authorization filter

Envoy extension

Share a database or API lookup across multiple other extensions

Data source

Cache or deduplicate lookups that every application would otherwise do

Proxy extension calling into a data source

If more than one row applies, start with the type closer to the top.

Execution model

Proxy extensions execute as a pipeline

Multiple proxy extensions can be configured against a single Synapse instance. On the request side, they execute in descending order of the priority field. On the response side, they execute in reverse. Each extension receives the request (or response) as produced by the preceding extension, so one extension can enrich the principal, another can attach resource metadata, and a third can add audit context, with each seeing the output of those that ran before it.

A failure inside an extension marked required: true terminates the pipeline and Synapse returns an error to the caller. Non-required extensions that fail are skipped and the pipeline continues with the unmodified request.

See Proxy extensions for the full priority and failure semantics.

Extensions calling the PDP bypass the proxy pipeline

When an extension calls cerbos.check_resources() or cerbos.plan_resources() from its own code — for example, a route extension translating a third-party protocol into a Cerbos decision — the call is routed directly to the PDP. The proxy extension pipeline does not run again for these internal calls. This prevents an infinite-loop condition where a proxy extension delegating to the PDP would re-trigger itself.

Enrichment required from inside an extension must be applied in the extension’s own code, or through a data source shared with the proxy pipeline, before the PDP call is issued.

Implementation options

Every extension type supports multiple implementation runtimes. The choice is independent of the extension type.

Runtime When to use Trade-offs

Native

Built, distributed and supported by Cerbos. Use these whenever one of them already covers your integration — for example, the built-in sqldb data source.

No development work, but the set of native extensions is fixed.

Declarative CEL mapping

Available on route and envoy extensions. Use when the mapping between the incoming protocol and a Cerbos request can be expressed as a set of CEL expressions against request fields.

No runtime to operate, fastest iteration. Limited to what CEL can express.

Starlark

Use for custom logic that is expressible in a Python-like scripting language — HTTP lookups, JSON manipulation, conditional enrichment. The Quick Start uses a Starlark proxy extension.

No compilation step, fast iteration. Single-threaded, slower than WASM for CPU-heavy workloads, limited library ecosystem.

WebAssembly (WASM)

Use when you need a full programming language, an existing library ecosystem, or CPU-intensive logic. Extensions can be written in Go, Java, Python or TypeScript/JavaScript and compiled to WASM.

Requires a build pipeline and deployment of binaries. Richer ecosystem, better performance, stronger sandboxing.

Both Starlark and WASM extensions can call into data sources. Complex integrations are typically structured as one data source wrapping the system integration and one or more Starlark or WASM extensions handling the policy-specific logic.

See Building custom Synapse extensions for language-specific guides on writing Starlark and WASM extensions.

Next steps