Zuplo
Authentication

Every auth method, validated at the edge

API keys, JWT, OAuth 2.0, OpenID Connect, mutual TLS, and TypeScript-based custom auth — composable per route, no SDK to install, no centralized auth service to operate.

Why this matters

Auth shouldn't live in 30 different services

Authentication is the most-implemented, most-broken, most-scary code in your codebase. Centralizing it at the gateway isn't just an aesthetic choice — it's how you stop shipping the same JWT-validation bug into production every quarter.

×

Auth code in every microservice

Each backend re-implements JWT validation. Each gets it slightly wrong. Each ships its own bug. Multiplied across 30 services, you have 30 places to patch when the next CVE drops.

×

API keys stored in a spreadsheet

The free tier shipped with API keys six months ago. The keys live in a Notion page. Rotation is a Slack DM. Revocation requires a deploy. You haven't slept well since.

×

Provider lock-in

Switching from Cognito to Auth0 means a months-long migration because validation is bolted into every service. Picking the right IdP is a one-way door, and the door is always locked.

×

Auth latency in the data path

Every request makes a round-trip to a centralized auth service before it can do useful work. P99 has three more nines than it should. Customers feel the cold-call.

What you get

Consistently enforced authentication across every endpoint

One auth surface, every backend

Validate JWTs, API keys, mTLS certs at the edge — once. Backends trust the gateway and skip re-validation. Stop reimplementing the same auth logic in every service.

Plug in any IdP

Auth0, Okta, Cognito, Azure AD, Firebase, Supabase, Clerk, your own. All you need is a JWKS URL. Switching providers is a config change, not a migration project.

Self-serve, leak-detected API keys

Edge-replicated, hashed at rest, with a self-serve portal for your customers and GitHub leak detection that catches committed keys before attackers do.

Auth methods

Every auth method, on the same gateway

API keys, JWT (any OIDC provider), Clerk JWT, mutual TLS, basic auth, and custom TypeScript — all configured per route, all enforced at the edge before traffic reaches your origin. Compose them per route, chain them across routes, or write your own.

Authentication Pipeline
EDGE-VALIDATED

API Key

api-key-inbound

active

JWT / OAuth 2.0

open-id-jwt-auth-inbound

ready

Clerk JWT

clerk-jwt-auth-inbound

ready

Mutual TLS

Mutual TLS · client cert

ready

Basic Auth

Basic Auth · RFC 7617

ready

Custom RBAC / ABAC

custom-code-inbound

ready
TimeMethodConsumer / scopeStatusLatency
6+ methods, composable
No SDK — all edge policies
Custom RBAC in TypeScript
API keys (api-key-inbound)
JWT / OAuth 2.0 (any OIDC IdP)
Clerk JWT (clerk-jwt-auth-inbound)
Mutual TLS (client cert)
Basic Auth (RFC 7617)
Custom TypeScript (RBAC / ABAC)
API key lifecycle

Issue, validate, and revoke without writing the auth service

Hashed-at-rest, edge-replicated API keys with a developer portal for self-serve, a Management API for programmatic issuance, an open-source React component for embedding into your own dashboard — and GitHub leak detection so a committed key gets noticed before an attacker exploits it.

Issue

Self-serve developer portal

Customers log in, create keys, attach metadata, and get the documentation in one flow. Branded to your domain.

Issue an API key
POST /v1/api-keys
Content-Type: application/json

{
  "consumer": "acme",
  "metadata": { "plan": "pro" }
}

Validate

api-key-inbound at the edge

Hashed-at-rest keys replicated to 300+ data centers. Validation in single-digit ms — no round-trip to a central DB.

Hit

~5ms

Revoked

401

Revoke

Leak detection + one-click rotate

GitHub scan catches committed keys before attackers do. Customers can roll their own without filing a ticket.

Leaked key detected · acme-prod-pk-2
Rotated · acme-prod-pk-3 issued
Hashed at rest
Edge-replicated · ~5ms validation
Self-serve developer portal
Custom metadata per key
Expiration + rotation
GitHub leak detection
What makes Zuplo different

Auth that fits how teams actually ship

Most gateways model auth as a single dropdown per route. Zuplo treats it as composable code — because real teams have employees, partners, machines, and migrations all happening at once.

Composable methods, not exclusive ones

Most gateways force you to pick one auth method per route. Zuplo lets you chain them — accept either an API key OR a Bearer token, fall through to a custom check, and feed all of them into the same RBAC policy.

Authorization at the gateway, your way

Write authorization checks as TypeScript policies — full access to request.user, headers, body, env vars, and ZoneCache, testable with Vitest. Or wire in the OpenFGA integration for relationship-based access control without operating a rules engine yourself. Either way, the decision lands at the gateway, not duplicated across every backend service.

Validation runs in the gateway, not over the network

Token validation and policy decisions happen inside the gateway runtime across 300+ edge data centers — not against a remote auth service. No separate service to scale, no round-trip per request, no single point of failure for a system every request needs.

Per-customer attribution, automatic

Because Zuplo issues API keys, every authenticated request is attributed to its consumer. Logs, analytics, rate limits, and monetization all key off identity without instrumentation code in your services.

Real questions, real answers

What teams use this for

“Our customers want API keys; our employees use SSO.”

Stack two policies on the same route: api-key-inbound for partner traffic, open-id-jwt-auth-inbound pointed at your Okta JWKS for employee traffic. The first method that succeeds populates request.user. Done.

“We're switching from Cognito to Auth0.”

Run both for 90 days. Update one config field — the JWKS URL — when you're ready to cut over. No service-by-service migration, no client SDK rewrites, no scheduled downtime.

“We need MFA for admin endpoints only.”

Apply your standard auth on every route, then add a custom-code-inbound policy on /admin/* that checks for an MFA claim in request.user.data. Reject with HttpProblems.forbidden() if it's missing.

“A customer just committed their API key to a public repo.”

Zuplo's GitHub leak detector finds it before they do. You get an email; the customer's portal shows a banner; one click revokes and issues a new one. Customers love it the way you'd expect them to love an alert that prevented a breach.

Frequently Asked Questions

Common questions about authentication with Zuplo.

Stop reimplementing auth in every service

Spin up a free Zuplo project, drop in any auth method, and consolidate the most-broken code in your stack.