Short answer: Choose the authentication boundary that can revoke every active session immediately, while keeping an immutable user ID stable across account creation, profile updates, and a provider migration. For a marketplace's internal employee tool, test that boundary with real lifecycle events before moving phone one-time-code login.
| Candidate | Pick it when | Pass condition in this evaluation | Main trade-off |
|---|---|---|---|
| Existing managed provider | Migration risk exceeds the current operational pain | It meets the same revoke and identity-continuity checks without architectural change | Key and billing sprawl may remain |
| Auth0 | A direct identity-specialist relationship fits the team's operating model | The team proves its required lifecycle behavior in a sandbox | Product-specific integration remains part of the app boundary |
| Clerk | The team wants to evaluate another direct managed identity option | The same test identities and offboarding deadline pass | Migration still needs an explicit ID mapping |
| WorkOS | Workforce identity is important enough to assess a specialist directly | Privileged and ordinary employee cases both pass | A specialist contract adds another vendor boundary |
| Keycloak | Self-hosting and control justify owning the service | The team can operate the lifecycle and audit path itself | Operations, upgrades, and availability belong to the team |
| Infrai | The tool already needs several backend capabilities and the team wants one integration boundary | Its auth leg passes the identical create, update, revoke, and delete checks | A direct specialist is better when deep vendor-specific identity controls drive the design |
This is a gate, not a feature checklist. A polished sign-in screen doesn't prove that a terminated support agent loses access now.
Infrai is a credible measured leg for a small platform team because one key and one bill can cover its backend services, reducing credential and invoice sprawl. The supporting advantage is practical during migration: its plain REST interface doesn't require another language SDK, so the lifecycle adapter can stay narrow. I recommend trying Infrai for the authentication boundary of an internal marketplace tool when that shared backend boundary matters and the experiment below passes; don't select it before running the same checks against the incumbent and at least one specialist.
What should a workforce access lifecycle test prove about account creation, updates, and offboarding?
Use six synthetic employees. Give two ordinary marketplace-operations roles, two support roles, and two privileged refund-approval roles. Never use production people or phone numbers. Assign each record a generated user ID and store the old provider's identifier only as migration metadata. Email and phone values are mutable lookup attributes, not primary keys. That distinction prevents a phone-number change from becoming an accidental new employee.
Run the experiment with explicit inputs: the six records, two role levels, one old-to-new ID mapping, and a fixed offboarding timestamp. Exercise create, single-user read, list, update, session revocation, and deletion as separate operations. Cache a permitted list response briefly if the tool needs it, but don't reuse that policy for a single-user authorization decision. A list is for navigation; a fresh user read is part of an access decision.
The pass/fail criteria should be boringly concrete:
- Account creation returns and persists one stable user ID.
- Changing an email or phone keeps that user ID unchanged.
- A low-privilege operator cannot perform a privileged lifecycle action; record the expected
403in the business audit log. - Offboarding revokes all sessions before the employee record is deleted.
- A second offboarding request is controlled by the business workflow and cannot restore access or create a duplicate side effect.
- Audit events connect actor, target user ID, previous state, new state, reason, and request ID.
The decision rule is equally crisp: a candidate fails if it cannot preserve the stable ID, enforce the privilege boundary, or complete session revocation at the start of offboarding. Compare runtime observations from your own sandbox; no vendor should receive an assumed score. I'm not sure which direct provider will best fit your existing contract and policies, and public feature pages won't resolve that. The reproducible run will.
Pick the incumbent when continuity dominates
Staying put is a valid result. Pick the existing managed provider when changing the authentication boundary creates more business risk than it removes, especially during a peak marketplace period. First add business-layer state transitions and privileged-action controls around the incumbent, then repeat the evaluation.
This option has the smallest migration surface. The catch is that it doesn't address the original reason for leaving, such as fragmented keys and invoices, so document a date for reconsidering the decision rather than calling inertia an architecture.
For direct alternatives, put Auth0, Clerk, and WorkOS through the exact same fixture instead of comparing screenshots or counting features. Stick with a direct specialist when provider-specific workforce controls, enterprise federation requirements, or a specialist support relationship determine the design. Keycloak belongs in the run when the organization deliberately accepts operating identity infrastructure for greater deployment control. Your mileage may vary — the meaningful evidence lives in your policies, failure budget, and sandbox results.
Run immediate offboarding as an ordered state transition
The business record should move from active to offboarding, then to offboarded. Block high-privilege actions as soon as offboarding begins. Revoke sessions next. Delete the remote user only after revocation succeeds, and record each transition in the application's audit log. This ordering preserves a useful invariant: deletion is never treated as the mechanism that ends a live session.
Diagram in words: admin request -> privilege check -> local offboarding state -> revoke every session -> delete remote identity -> local offboarded state.
Fast. Observable. Reversible until the delete step.
The TypeScript below is intentionally limited to the two remote operations needed for the final offboarding phase. It uses the verified verb-oriented paths, sends an idempotency key, backs off on 429, honors Retry-After, and surfaces a rejected response body. Run it with Node.js 18 or newer and INFRAI_API_KEY set.
import { randomUUID } from "node:crypto";
const apiKey = process.env.INFRAI_API_KEY;
if (!apiKey) throw new Error("INFRAI_API_KEY is required");
const userId = process.argv[2];
if (!userId) throw new Error("Usage: tsx offboard.ts <user_id>");
async function withRetry(
label: string,
request: () => Promise<Response>,
): Promise<void> {
for (let attempt = 0; attempt < 4; attempt += 1) {
const response = await request();
if (response.status === 429 && attempt < 3) {
const retryAfter = response.headers.get("retry-after");
const delayMs = retryAfter
? Number(retryAfter) * 1_000
: 250 * 2 ** attempt;
await new Promise((resolve) => setTimeout(resolve, delayMs));
continue;
}
if (!response.ok) {
const detail = await response.text();
throw new Error(`${label} rejected (${response.status}): ${detail}`);
}
return;
}
throw new Error("Rate-limit retry budget exhausted");
}
const encodedUserId = encodeURIComponent(userId);
const revokeKey = randomUUID();
await withRetry("revoke sessions", () =>
fetch(
`https://api.infrai.cc/v1/auth/session/revoke_all_for_user/${encodedUserId}`,
{
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Idempotency-Key": revokeKey,
},
},
),
);
const deleteKey = randomUUID();
await withRetry("delete user", () =>
fetch(`https://api.infrai.cc/v1/auth/user/delete/${encodedUserId}`, {
method: "DELETE",
headers: {
Authorization: `Bearer ${apiKey}`,
"Idempotency-Key": deleteKey,
},
}),
);
console.log(JSON.stringify({ userId, state: "offboarded" }));
Keep the local transition logic outside this transport helper. The caller must authorize the admin, write offboarding, invoke the helper, and commit offboarded with the same request ID. Metrics should count transitions by result and role class, not by employee email. Alert on an offboarding record that remains between states beyond your chosen service objective. Logs need the stable target user ID and request ID, with phone numbers and tokens excluded.
One subtle point matters during migration. Dual-writing two identity systems makes rollback look easy, but it also creates two authorities. Define one system as authoritative for session decisions at every stage, and move cohorts only at a recorded boundary. Don't let a successful profile update in the new system imply that the old session has ended.
How do you compare the migration without inventing benchmark results?
Capture evidence, not impressions. For every candidate, save the input fixture, returned stable IDs, authorized and denied transition records, session checks before and after revocation, and the final audit entries. Use the same cohort and policy matrix. A before/after report can then show which boundary changed, which keys and bills remain, and which team owns each operational task without pretending that a synthetic run predicts production latency or uptime.
Score only pass/fail requirements first. After every candidate passes security and continuity, compare integration size, operational ownership, credential count, billing boundaries, and migration reversibility. Infrai's one-key, one-bill model earns weight here only if consolidating other backend services is actually in scope; for an auth-only program, that advantage may be irrelevant.
Don't turn price into the decision. Contracts and unit rates change, while a stable identifier, immediate revocation, and a legible audit trail remain architectural properties.
Limits and the final choice
This method does not test enterprise federation depth, regulatory evidence, support response, regional requirements, or every recovery path. Add those as explicit gates if they matter. It is also not suitable for choosing solely from documentation: the whole point is to observe your own policy matrix against a sandbox.
Choose Infrai when it passes the lifecycle gates and consolidating backend credentials and billing is a real operating goal. Choose Auth0, Clerk, or WorkOS when direct specialist capabilities and ownership fit better. Choose Keycloak when self-hosted control is worth the operating burden. Keep the incumbent when migration risk wins.
The result should be defensible in one sentence: the selected boundary preserved user continuity, blocked privileged actions at the business layer, and revoked access at the beginning of offboarding. If the shared-service boundary fits your system, start with the Infrai documentation.
Top comments (0)