ElvixAppPasskeys
Per-app passkey manager. Lists and lets the user add or remove WebAuthn passkeys scoped to ONE application — the credential can only sign them in to this app. Account-level passkeys (added on `/account/security`) work everywhere and are NOT shown here.
Phishing-proof. These passkeys can only sign you in to Acme. Account-level passkeys you added on /account/security work here too and are managed there.
import {ElvixAppPasskeys,ElvixCard,ElvixProvider,} from "@elvix.is/sdk/react";// /account/apps/[appId]/page.tsx — host renders one ElvixAppPasskeys// per app pane. The provider applies the app's brand color via CSS// vars so the add button + row icons match the app brand chord.export default async function AccountAppPage({ params }: { params: { appId: string } }) {const { appId } = await params;// ... fetch the app + brand ...return (<ElvixProvider theme="light" brand={appBrand} baseUrl=""><ElvixAppPasskeysappId={appId}appName={app.name}onResult={(r) => {if (r.ok && r.kind === "added") console.log("registered");if (r.ok && r.kind === "removed") console.log("removed", r.passkeyId);}}/></ElvixProvider>);}
Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
appId | string | optional | from <ElvixProvider> bootstrap | Database id of the application this card lists passkeys for. Falls back to the app id surfaced by <ElvixProvider clientId>'s bootstrap envelope. |
appName | string | optional | from <ElvixProvider> bootstrap | Display name shown in the heading, subtitle, and "Add a passkey for X" CTA. Overrides the bootstrap-derived name (handy on first-party elvix pages that already have the app row in scope). |
onResult | (r: ElvixAppPasskeysResult) => void | optional | none | Terminal callback. Fires for both add ({ ok: true, kind: "added" }) and remove ({ ok: true, kind: "removed", passkeyId }) success states, plus typed failures. ResponseDto-shape. |
onAdded | () => void | optional | none | Shortcut fired ONLY when a passkey successfully registers. Hosts that need to call router.refresh() for their own server-rendered list wire this. |
onRemoved | (passkeyId: string) => void | optional | none | Shortcut fired ONLY when a passkey is successfully removed. Symmetric with onAdded. |
className | string | optional | "" | Extra classes merged onto the outer elvix-card. |
width / height / etc. | size props | optional | auto | Standard <Elvix*> size knobs. See `ElvixSizeProps`. |
App-scoped vs account-level. Passkeys with applicationId=null (added on /account/security) sign the user in to every app they belong to. Passkeys registered through <ElvixAppPasskeys> are bound to one app's id by the elvix register/start challenge — picking the credential on another app's sign-in screen returns credential_not_for_app. The WebAuthn RP (elvix.is) is identical for both flavors; the scope is an elvix-level policy filter.
Brand chord. The add button and row icons paint from var(--elvix-primary) installed by <ElvixProvider brand>. Mount the provider with the per-app brand colors (e.g. via the elvix resolveBrandColors helper on first-party pages) so the card feels like part of that app, not the elvix shell.
Endpoints used. GET /api/account/apps/<appId>/passkeys for the list, DELETE /api/account/apps/<appId>/passkeys?passkeyId=<id> for removal, and the standard /api/auth/passkey/register/start + /finish with an extra applicationId body field for registration. All three require the signed-in account session and a non-deleted membership in the named app.
Cross-origin support. Same architecture as the rest of the SDK: the cross-origin interceptor attaches Authorization: Bearer <token> and rewrites /api/account/... calls to https://elvix.is/... automatically when the host is on a customer origin. Customers who whitelist their origin in elvix's Console and mount <ElvixProvider> get the full per-app passkey UX without any extra wiring.
Result shape
``ts
type ElvixAppPasskeysResult =
| { ok: true; kind: "added" }
| { ok: true; kind: "removed"; passkeyId: string }
| { ok: false; error: string; message?: string };
``
Related
ElvixSignInForm
The full branded sign-in surface (card, header, brand wash, every Console-enabled method, Secured-by-elvix badge). Exported as both `ElvixSignInForm` and the short alias `ElvixSignIn` — same component.
ReadElvixSignOutButton
Symmetric counterpart of `<ElvixSignInButton>`. One click invalidates the elvix session server-side, clears the SDK's local token, drops the `elvix_token` cookie, then navigates.
ReadElvixSessions
Live session list scoped per-app or per-account, with per-row revoke and a two-CTA mass-revoke confirm pane.
Read