Platform

Identity & auth

OIDC, SAML, OAuth2, passkeys, magic link, password — vendor-neutral identity surface across Auth0, Clerk, WorkOS, Okta, Cognito, custom.

Vadyl's identity plane is a vendor-neutral abstraction over the major identity providers. You declare what you want — an OIDC connection, a SAML flow, a passkey challenge, an OAuth2 federation — and bind to whichever provider you're using. Application code never sees the vendor.

Provider registry

IIdentityProviderFactoryRegistry resolves identity provider implementations from canonical type names. Built-in: Auth0, Clerk, WorkOS, Okta, Cognito, Microsoft Entra, Google Workspace, Apple, custom OIDC, custom SAML.

bindings: {
  identity: {
    type:     "auth0",
    domain:   process.env.AUTH0_DOMAIN,
    clientId: process.env.AUTH0_CLIENT_ID,
    clientSecret: secret.ref("AUTH0_CLIENT_SECRET"),
  },
},

Identity entities

Vadyl persists eight identity entities under the canonical model:IdentitySubject (the canonical user / agent / service), IdentityCredential, IdentityMembership, AuthSession, AuthChallenge, AuthRevocation, IdentityConnectorBinding, RefreshTokenFamily.

Sessions and refresh tokens

Sessions are first-class entities — revocable, queryable, durable. Refresh-token families implement secure rotation: each refresh produces a new family member and invalidates the previous one. Token-replay attacks are detected and the entire family is revoked.

MFA challenges

Step-up auth is a typed challenge: TOTP, WebAuthn, SMS code, email code, push notification. The capability resolver (IIdentityChallengeCapabilityResolver) is consulted by both Discovery and ChallengeStart so the available challenge types match what the user has actually enrolled.

// Step up to a higher auth strength before sensitive operation
await ctx.identity.challenge.start({
  subjectId: ctx.actor.userId,
  requireStrength: "mfa-totp",
});

JIT provisioning

First-time SSO sign-ins create a canonical IdentitySubjectkeyed by the provider's subject identifier. Subsequent sign-ins resolve to the same subject. Multiple credentials (Google + Auth0 + password) can attach to the same subject through explicit account linking.

Federation flows

OAuth2 / OIDC flows are first-class:

// Start an OIDC flow
const challenge = await ctx.identity.federation.start({
  provider: "google",
  redirectUri: "https://app.example.com/auth/callback",
});

// Complete it on the callback handler
const session = await ctx.identity.federation.complete({
  provider: "google",
  code:     req.query.code,
  state:    req.query.state,
});

Auth strength

Every authentication carries a typed AuthStrength:weak, basic, mfa-sms, mfa-totp, mfa-webauthn, passkey. Access models can require a minimum strength per facet via ctx.authStrengthAtLeast(level).

Switch providers

Migrate from Auth0 to Clerk: change the binding, run the migration script that maps existing subjects, deploy. Application code doesn't change. Existing sessions remain valid until they expire (or are explicitly revoked).