Choosing an integration pattern
Two ways to wire the SDK into your stack. The decision tree is short.
The two patterns
Pattern 1 — Sidecar HTTP service (recommended)
Your app talks to the SDK over HTTP. Either runs as a separate process (Docker container, Fargate task, etc.) or is mounted as a Rust module in your Axum app.
[browser] ──► [your app] ──► [auth backend] ──► [Postgres]
│ ▲
└──────────────┘
proxied auth calls + session cookie shuttling
Pros:
- Every endpoint in the API reference is reachable.
- Session revocation is instant (the auth backend reads from the DB on every request).
- Audit, sessions, MFA enrollment — all work out of the box.
Cons:
- Your app needs to proxy POST
/auth/login,/auth/logout, etc. (@identsphere/reactdoes this automatically for the frontend; backend hosts build a thin proxy.) - Slightly higher latency per authenticated request (extra HTTP hop OR in-process DB query).
Pattern 2 — Local JWT validation (the standard model)
IdentSphere runs as a service; the auth backend stays public-facing. On the per-request hot path your app NEVER talks to it directly — its only job is to validate the RS256 JWT locally against the published JWKS, with no network hop per request. This is the same model every major auth provider uses (Auth0, Clerk, Keycloak, Supabase GoTrue, Ory, SuperTokens). See Validating tokens in your backend for the per-language verifier snippets.
[browser] ──► [auth backend] ──► [Postgres]
│
│ cookie set
▼
[browser] ──► [your app] (validates JWT in middleware)
Pros:
- Zero coupling at runtime — your app and the auth backend are independent services.
- Lowest possible latency: JWT validation is local, no DB hit.
- Easy to scale across many backends in different languages.
Cons:
- Revocation lag. A revoked session keeps working until its access token expires (default 15 min) — you can't check the session table on every request because that defeats the latency win.
- The host app cannot call SDK endpoints on behalf of the user (the JWT is validated locally; the host doesn't proxy through the SDK).
- For sensitive operations, you need to re-route through the SDK anyway (step-up, MFA disable, etc.).
The decision tree
Does your app NEED instant session revocation?
├─ Yes ──► Pattern 1
└─ No
│
Do you need to call SDK-managed endpoints (sessions, MFA,
passkeys) from your backend?
├─ Yes ──► Pattern 1
└─ No
│
Is your stack a Rust app and you want the SDK to look like
a library?
├─ Yes ──► Pattern 1 (in-process)
└─ No ──► Pattern 2
Tightening Pattern 2's revocation lag
If you want Pattern 2's latency but tighter revocation:
- Shorten
IDENTSPHERE_ACCESS_EXPIRY_SECSfrom 900 to 60. Now revocation lag is ≤ 60s. - Shorten the JWKS cache TTL in your JWT-validating middleware.
- Tradeoff: more
POST /v1/auth/refreshcalls. Roughly 15× more.
What @identsphere/react does
The React SDK is Pattern 1 from the frontend's perspective. It calls SDK
endpoints directly (with credentials: 'include') and reads back cookies.
Your backend can do whatever it wants — Pattern 2 is fine for the API
layer of a React app that's already on Pattern 1 for auth.
Mixing patterns
The patterns aren't exclusive. Common setups:
- Frontend → SDK directly (Pattern 2-ish, with browser doing the cookie dance). Backend validates JWTs (Pattern 2).
- Frontend → app backend → SDK (Pattern 1 throughout).
- Frontend → SDK directly. Backend validates JWTs. Backend also makes API
calls to the SDK for specific operations (
GET /v1/users/me,DELETE /v1/auth/sessions/:id).
Pick what matches your operational shape.
Next steps
- Validating tokens in your backend — the service + local-validation model and per-language verifier snippets
- Rust — in-process integration with Axum
- TypeScript / React —
@identsphere/react - Python, Node, Go, Ruby, Java, PHP — Pattern 1 sidecar examples
- REST — for any language without a dedicated guide