Environment (web):
NEXT_PUBLIC_CONVEX_URL=https://<deployment>.convex.cloud
EA_WEBAUTHN_RP_ID=auth.example.com # optional override for native apps
EA_WEBAUTHN_ALLOWED_ORIGINS=https://foo.example,https://bar.example # optional extra origins
API endpoints:
- POST
/api/auth/webauthn/begin/registration - POST
/api/auth/webauthn/finish/registration - POST
/api/auth/webauthn/begin/authentication - POST
/api/auth/webauthn/finish/authentication
JS SDK usage:
import { SDK } from "@entityauth/auth-client";
// Register a passkey for current user (rpId/origins derived server-side)
await SDK.passkeys.register({
workspaceTenantId: "default",
userId: "entities:1",
});
// Sign-in with passkey (discoverable)
const result = await SDK.passkeys.signIn({ workspaceTenantId: "default" });
console.log(result.accessToken);
RP ID and origins (web):
- RP ID is derived from request host as eTLD+1 (e.g.,
sub.example.co.uk->example.co.uk). - Expected origins are computed as the current origin plus any
originentities linked to the workspace. - These are stored on the challenge and enforced at finish.
Swift (EntityKit) usage:
let config = EntityAuthConfig(baseURL: URL(string: "https://api.example.com")!)
let facade = EntityAuthFacade(config: config)
// Register a passkey for the current user via native APIs
let _ = try await facade.registerPasskey(userId: userId, rpId: host, origins: [origin])
// Sign in with a passkey (discoverable)
try await facade.signInWithPasskey(userId: nil, rpId: host, origins: [origin])
Apple AASA and entitlements (native):
- Keep
/.well-known/apple-app-site-associationlisting bundle IDs. - iOS/macOS apps must include Associated Domains with
webcredentials:example.com.