RPP Authorization: Build vs Buy, Grounded

Generated 2026-07-17 · Diligence on 8 authorization engines for RevParPro (Supabase RLS + JWT claims, ~39 Deno edge functions, going multi-tenant B2B). Repo stats pulled live from the GitHub API; each engine's fit claim adversarially verified. Follow-on to the access-controls audit.
Recommendation

Stay on the incumbent and harden it now. None of the 8 engines is right-sized for RPP's flat 12-roles by properties model today, and not one has a real, maintained Supabase integration. The actual open flank is an enforcement gap, not a policy-modeling gap, and a shared JWT-claims guard closes it with zero new infrastructure. Pre-qualify Cerbos (embedded WASM path) as a trigger-gated future move for when customer-defined per-tenant roles land, but do not adopt it now.

Method note. 8 research agents each pulled hard repo stats from api.github.com and read the engine's docs plus any Supabase page, then a second adversarial agent tried to refute each engine's fit claim. That layer earned its keep: it caught the Cerbos research agent citing evidence that does not exist ("the SDK README names Deno directly", which it does not) and refuted the rosy read with dated sources. All 8 engines were refuted on the compound claim "callable from a Supabase Deno edge function today, with a real maintained Supabase integration, and right-sized for RPP." Every figure below is what the GitHub API returned on 2026-07-17.

Section 1The engines, side by side

Sorted by how they landed. "Deno fit" means callable from a Supabase edge function today. "Supabase integration" asks whether a real, maintained integration exists or just a marketing or stale page. Stars and latest release are from the GitHub API; for Casbin and Permit.io the star count shown is the SDK repo RPP would actually use, with the platform repo noted in the row.

EngineStarsLatest releaseLicenseDeploy modelDeno fitSupabase integ.Verdict
Incumbent
Supabase RLS + JWT RBAC, hardened
n/an/an/a In-DB + in-function, no new service NATIVE IS SUPABASE RECOMMENDED
Cerbos
cerbos/cerbos
4,497v0.53.0
2026-05-05
Apache-2.0 Embeddable WASM PDP (in-process) or self-host sidecar INFERRED MARKETING LATER
Casbin
casbin/node-casbin (Go core 20,251)
2,908v5.51.1
2026-06-25
Apache-2.0 Embedded library, pure TypeScript, no hop YES NONE LATER
OpenFGA
openfga/openfga
5,448v1.18.1
2026-06-29
Apache-2.0 Self-host Go server + its own datastore YES (REST) NONE AVOID
SpiceDB
authzed/spicedb
6,871v1.54.0
2026-06-18
Apache-2.0 Self-host server + DB, or SaaS from $2/hr YES (HTTP) NONE AVOID
Permify
Permify/permify
5,921v1.7.2
2026-07-07
AGPL-3.0 Self-host server + DB, or cloud YES (REST) NONE AVOID
OPA
open-policy-agent/opa
11,992v1.18.2
2026-07-02
Apache-2.0 Self-host sidecar, or Rego to WASM pipeline WASM ONLY NONE AVOID
Oso / Oso Cloud
osohq/oso (lib deprecated)
3,494v0.27.1
2023-12-18
SaaS proprietary Hosted SaaS only (OSS lib deprecated) HTTP ONLY NONE AVOID
Permit.io
permitio/permit-node (OPAL 5,484)
47v2.7.6
2026-06-24
MIT SDK / SaaS Hosted cloud PDP (sidecar impossible on edge) CLOUD ONLY STALE 2024 AVOID

Section 2The case for switching, and against

Strongest honest case FOR switching

It is forward-looking, not present-tense. The external multi-tenant B2B pivot at $299/mo is committed, and with it come customer-defined custom roles and editable permission matrices, the exact workload where a central versioned role-to-permission map earns its keep instead of role logic scattered across 112 migrations and 12 edge functions. Adopting the discipline of one authoritative policy before the rot deepens is cheaper than retrofitting after you have paying tenants. Cerbos is the one engine where the usual killer objection dissolves: its embedded WASM PDP evaluates in-process inside the Deno function, so there is no network hop and no sidecar to self-host. If custom per-tenant roles are 6 to 12 months out and you want policy-as-code you can hand a customer as an auditable artifact, starting the Cerbos embedded path is defensible.

Why staying still wins today

All 8 engines were refuted on the same three facts. First, no real maintained Supabase integration exists for any of them: Cerbos's page is marketing (its only dated tutorial stands up a Node/Express server plus a Docker PDP, the opposite of the edge path), Permit.io's is a 2-year-stale 2024-05-14 blog, and the rest have nothing. Second, the actual gap is enforcement, not modeling: the 12 service-role functions have no caller check, closed by a 30 to 50 line shared guard reading claims the token hook already stamps. Third, the model is flat and two-dimensional, so the Zanzibar engines would have you run a new stateful service plus datastore plus a dual-write sync to model a graph you do not have. And no engine can govern the browser-to-PostgREST path, so RLS stays regardless: an engine adds a second system rather than replacing one.

The reversal from my earlier answer: last round I argued for adopting Cerbos on the edge layer "now, not later." The diligence does not support that. Even Cerbos's Supabase story is a marketing page with no Deno code, its edge fit is inferred rather than demonstrated, and the embedded path couples you to paid Cerbos Hub (Dev $25/mo, Prod $933/mo). The edge-function P0 is real, but it is closed by a helper function, not by buying an engine. I was right that the gap is urgent and wrong that the fix is an engine.

Section 3Recommended plan

  1. Phase 0, days. Write one shared TypeScript guard that reads app_role, tenant_id, and assigned_properties from the verified JWT, and assert it at the top of all 12 uncontrolled service-role edge functions. This closes the real open flank with zero new infrastructure, zero network hop, zero new bill. Pair it with the DB-side follow-up from the access audit: extend the finance and deal role gates to the balance-sheet and deal-period tables that migration 259 missed.
  2. Phase 1, weeks, before external launch. Centralize the role-to-permission source of truth in Postgres using Supabase's own documented RBAC pattern: a role_permissions table plus a single authorize() SQL helper, collapsing the logic currently smeared across 112 migrations into one canonical definition that both the RLS policies and the edge guard read. Kill the tenant_id='default' rot by making tenant a real enforced column on both paths.
  3. Phase 2, trigger-gated, not now. When customer-defined custom per-tenant roles become a committed, scheduled requirement, adopt Cerbos via its @cerbos/embedded WASM PDP (in-process, no hop), never the self-hosted sidecar path. Re-verify Cerbos Hub bundle-build pricing against the $299/mo unit economics before committing. Pre-qualify now, build only when a trigger fires.

Section 4What would flip the decision to switch

Section 5One line each on why the rest fell out

EngineWhy not (today)
OpenFGAProduction-grade (CNCF Incubating since 2025-10-28, v1.18.1) but a Zanzibar ReBAC graph engine for relationships RPP does not have. Needs a new stateful Go service plus its own datastore plus continuous tuple-sync plus a network hop on the hot path. The only Supabase trace is a 2.5-year-old unanswered wishlist discussion.
SpiceDBReference Zanzibar engine, genuinely Deno-reachable via its native HTTP API since 2022. Same overkill: new stateful DB plus dual-write sync, no embeddable mode, no Supabase integration, and AuthZed Cloud lists from $2/hr always-on (authzed.com/pricing) against a $299/mo product. Recent v1.53 and v1.54 carried regressions worth pinning around.
PermifyReBAC graph engine, REST-callable from Deno, but overkill for flat RBAC and AGPL-3.0 network-copyleft on the server is a real legal-review item for commercial SaaS. Acquired by FusionAuth on 2025-11-20 with a unified product and new pricing landing in 2026 and no standalone-maintenance commitment.
OPACNCF Graduated and battle-tested, but its sidecar model does not map to serverless Deno (self-host an always-on server or own a Rego-to-WASM pipeline), it forces a whole new language (Rego), has no Supabase integration, and Styra's core team was hired away by Apple in 2025 with Styra DAS sunset. The engine lives on under CNCF, but its corporate steward and managed control plane evaporated.
Oso / Oso CloudWorst structural fit here: the OSS library is deprecated (last release 2023-12-18), so you are committed to the proprietary hosted SaaS with fact-sync plus a per-check network hop, and the company has visibly pivoted its go-to-market to "Oso for Agents" (AI-agent security), demoting the app-authz product RPP would depend on.
Permit.ioDeno support is real but structurally forces you onto the eventually-consistent managed Cloud PDP (a Deno isolate cannot run the low-latency sidecar), so it is an external SaaS in the critical path on every check with no read-your-own-writes. Its Supabase integration is a stale 2024-05-14 blog, and the free tier's 20-tenant cap collides with the B2B multi-tenant plan.