1---2name: cerbos-synapse-extension3description: Builds, scaffolds, tests, debugs, and troubleshoots Cerbos Synapse extensions — call mappers, data sources, proxy extensions, route extensions, Envoy ext_authz extensions — in declarative YAML/CEL, Starlark, or WASM (Go, TypeScript/extism-js, Python/extism-py). Covers principal enrichment, attribute lookup, AuthZEN, protocol adapters, custom /ext/ endpoints, system://sqldb and system://aperture, synapse test suites (*_test.star), the Starlark REPL, config.yaml extension wiring, and docker-compose local dev. Use when the user mentions Synapse extensions, "add custom logic to Synapse", enriching principals/resources, mapping HTTP or Envoy traffic to Cerbos checks, writing or running Synapse extension tests, or an extension not loading/firing.4---56# Cerbos Synapse Extension78Synapse extends the Cerbos authorization pipeline. Five extension **kinds** × multiple **runtimes**. Pick kind → runtime → load the matching reference.910## Extension Kinds1112| Kind | Purpose | Entry points |13|------|---------|--------------|14| **Call mapper** | HTTP ↔ Cerbos mapping. CEL only, no code. | `routeExtensions.builtinRouteExtension` routes or `envoyExternalAuthz` in `config.yaml` |15| **Data source** | Attribute lookups for other extensions. | Export `lookup`; consumed via `cerbos.data_source_lookup()` (Starlark) / `dataSourceLookup` (WASM) |16| **Proxy extension** | Modify CheckResources / PlanResources / AuthZEN requests+responses. | `augment{Check,Plan,AuthzenEvaluation,AuthzenEvaluationBatch}{Request,Response}` (Starlark: `snake_case`) |17| **Route extension** | Custom HTTP endpoints under `/ext/`. | `handleHTTPRoute`, optional `handleCerbosResponse` callback (Starlark: `handle_http_route` / `handle_cerbos_response`) |18| **Envoy extension** | Envoy ext_authz → Cerbos. | `envoyCheck`, optional `envoyMapCerbosResponse` callback (Starlark: `envoy_check` / `map_cerbos_response` — **not** `envoy_map_cerbos_response`) |1920## Runtimes2122| Runtime | Build | Perf | Libraries | Best for |23|---------|-------|------|-----------|----------|24| **Declarative (CEL in YAML)** | None | High | CEL stdlib | Call mapper only |25| **Starlark** | None — `.star` file | Lower (interpreter) | Built-in modules (`http`, `json`, `base64`, `time`, `re`, `hashlib`, `csv`, `random`, `string`) | Prototyping, simple lookups, no build step |26| **WASM (Go / TS / Python)** | Compile to `.wasm` | High | npm, Go modules, pure-Python | Compiled perf, library deps, production adapters |2728## Decision flow29301. **Static HTTP → Cerbos mapping, CEL enough** (headers, JWT claims, JSON body, ternaries)? → call mapper, no code. → `references/call-mapper.md`312. Else pick kind: data source / proxy / route / envoy.323. Pick runtime:33 - **Starlark** — built-in modules suffice; iteration speed > peak perf34 - **WASM** — compiled perf, third-party libs, existing codebase. Language: **Go** (`tidwall/gjson`/`sjson`, typing) · **TS** (`@extism/js-pdk` + esbuild; no `btoa`/`atob` — `Host.arrayBufferToBase64()`) · **Python** (`extism-py`; pure-Python only; `wasm-merge` shim step)3536| Kind | CEL | Starlark | WASM Go | WASM JS | WASM Py |37|------|:---:|:---:|:---:|:---:|:---:|38| Call mapper | ✓ | — | — | — | — |39| Data source | — | ✓ | ✓ | ✓ | ✓ |40| Proxy | — | ✓ | ✓ | ✓ | ✓ |41| Route | — | ✓ | ✓ | ✓ | ✓ |42| Envoy | ✓ (`envoyExternalAuthz`) | ✓ | ✓ | ✓ | — |4344Before writing custom: `system://sqldb` (SQL data source), `system://aperture` (Tailscale Aperture → Cerbos) and `system://claude` (Claude Code hooks → Cerbos) may already fit → `references/shared/system-extensions.md`.4546## References4748Per-implementation (pick one):4950| Reference | When |51|-----------|------|52| `references/call-mapper.md` | Declarative call mapper |53| `references/starlark-{data-source,proxy-extension,route-extension,envoy-extension}.md` | Starlark, by kind |54| `references/wasm-data-source-{go,javascript,python}.md` | WASM data source |55| `references/wasm-proxy-extension-{go,javascript,python}.md` | WASM proxy |56| `references/wasm-route-extension-{go,javascript,python}.md` | WASM route |57| `references/wasm-envoy-extension-{go,javascript}.md` | WASM Envoy (no Python) |5859Shared (load alongside):6061| Reference | When |62|-----------|------|63| `references/shared/run-and-test.md` | **Always, before authoring a demo.** Layout, `config.yaml`, compose, curl, iteration loop, REPL, failure modes. |64| `references/shared/testing-framework.md` | **When writing tests.** `synapse test`, `*_test.star` suites, `test_suite` struct, `testing` module, `context` helpers, test data. |65| `references/shared/patterns-and-gotchas.md` | **Always, before writing extension code.** Caching, data source lookup, enrichment, proxy chain + route match ordering, callback mode, lifecycle, runtime gotchas, runtime context facts. |66| `references/shared/starlark-environment.md` | All Starlark — host functions, modules, proto-map gotchas. |67| `references/shared/go-wasm-common.md` | All Go WASM — `extism/go-pdk` host imports. |68| `references/shared/typescript-wasm-common.md` | All TS WASM — d.ts rules, base64 workaround. |69| `references/shared/python-wasm-common.md` | All Python WASM — build pipeline, PDK shim, memory helpers. |70| `references/shared/system-extensions.md` | Using `system://sqldb` / `system://aperture`. |71| `references/shared/call-mapper-cel-reference.md` | Call mapper CEL functions/variables. |72| `references/shared/call-mapper-examples.md` | Call mapper examples (REST, Envoy). |7374## Running and testing (quick facts)7576- **Distribution repo — ask first.** The Synapse image lives in a licensed Cerbos distribution repository. **Before running any `docker` / `docker compose` / `synapse test` command, ask the user for their distribution repository URL** and substitute it for `CERBOS_DISTRIBUTION_REPO` everywhere. No licence yet → sign up at https://cerbos.dev/workshop; credentials are issued with the repo URL. Log in (`docker login CERBOS_DISTRIBUTION_REPO --username=YOUR_LICENCE_USER --password=YOUR_LICENCE_KEY`) before pulling.77- Image `CERBOS_DISTRIBUTION_REPO/synapse/synapse:<version>`, port `3594`, distroless. Subcommands: `server`, `test`, `starlark repl`.78- Local dev: embedded PDP (`pdp.inProcess`, `disk` storage, `watchForChanges: true` hot-reloads policies); extensions under `extensions.{proxyExtensions,routeExtensions,dataSources}.<name>` in `config.yaml`; bind-mount `config.yaml`, `policies/`, `extensions/`.79- WASM: `make build` before start — mount the built `.wasm`, not source. `.star`/`.wasm`/config edits need container restart.80- Drive: `/api/check/resources`, `/api/plan/resources`, `/ext/<path>`, Envoy ext_authz gRPC. Wait on `GET /_cerbos/ready` before driving.81- Tests: `synapse test <paths>` runs `*_test.star` suites — fresh instance per suite, no restart cycle. Details: `references/shared/testing-framework.md`.