App-origin passkeys
1auth creates and uses passkeys in your application's top-level page. By default, each hostname has a separate passkey and smart account. Configure one RP ID plus exact server-authorized rpOrigins to share a passkey/account namespace across same-site deployment origins.
clientIdidentifies your registered application, but it is not itself the WebAuthn RP ID or browser origin.
RP ID and RP origin, in plain language
WebAuthn binds every passkey to two related values:
- RP ID: the passkey's website namespace. It is a hostname with no
https://and no port, for exampleexample.com. A passkey created for one RP ID cannot silently be used for another. - RP origin: the exact page that runs the ceremony, including the scheme and any non-default port, for example
https://checkout.example.com. The browser writes this value into the signed WebAuthn response; the SDK cannot forge or replace it.
For a page at https://checkout.example.com, the default is:
RP ID: checkout.example.com
RP origin: https://checkout.example.com
Account key: https://checkout.example.comWith a configured shared RP ID of example.com, the same page uses:
RP ID: example.com
RP origin: https://checkout.example.com
Account key: https://example.comThe RP ID selects the passkey, signer, and smart-account namespace. The RP origin proves which exact webpage performed the ceremony.
The SDK sends only the configured RP ID. The browser supplies the exact request origin and signs the ceremony origin. The server selects the registered app by clientId, requires the RP ID to match its saved configuration, and requires exact membership in the server-owned rpOrigins allowlist.
Configure the registered application in the developer dashboard before deploying the client:
{
"rpId": "example.com",
"rpOrigins": ["https://test1.example.com", "https://test2.example.com"]
}Every hostname must be an exact verified non-wildcard application domain. Origins are exact: scheme and non-default port are significant. Each origin hostname must equal the RP ID or be its subdomain.
:::warning Explicit RP sharing requires both configurations
Saving rpId and rpOrigins in the developer dashboard only authorizes the namespace; it does not activate it for a client. The client must also send the same value as webauthn.rpId. If the client omits webauthn.rpId, 1auth intentionally uses the page's exact hostname and does not consult the registered shared-RP configuration.
On a canonical page whose hostname equals the saved RP ID, both configurations may produce the same visible hostname. That does not prove the explicit path is active. Verify that the client sends webauthn.rpId, especially before expecting another authorized subdomain to reuse the same passkey and smart account.
:::
Configure the client
import { OneAuthClient } from "@rhinestone/1auth";
export const oneAuth = new OneAuthClient({
providerUrl: "https://passkey.1auth.app",
clientId: "my-app",
webauthn: {
rpId: "example.com",
},
experimental_clear_signing: true,
sponsorship: {
accessTokenUrl: "/api/sponsorship/access-token",
extensionTokenUrl: "/api/sponsorship/extension-token",
},
});Providing webauthn.rpId automatically selects app-origin mode. The RP ID must be the page hostname or one of its parent domains:
Page: checkout.example.com
Allowed: checkout.example.com or example.com
Denied: accounts.other-company.comYour clientId must belong to the registered application serving the current page. Omit rpId to preserve the default exact-host behavior.
In the developer dashboard, choose the verified RP ID and add every exact page origin that may run WebAuthn. rpOrigins is server-owned configuration and is not an SDK option.
authenticate(), authenticate({ flow: "create-account" }), and authenticate({ flow: "login" }) first open the identity-only 1auth dialog. After identity verification, registration or authentication continues in your top-level page using the configured RP ID or, by default, that page's hostname.
const auth = await oneAuth.authenticate();
if (!auth.success) {
throw new Error(auth.error?.message ?? "Authentication failed");
}
const result = await oneAuth.sendIntent({
accountAddress: auth.session.accountAddress,
targetChain: 84532,
calls,
sponsorshipMode: "required",
experimental_clear_signing: true,
});Security boundary
With experimental_clear_signing: true, the passkey-origin iframe displays the authoritative server-prepared transaction review. Approval returns to the SDK, then navigator.credentials.get() runs in the application's top-level page. The server binds and verifies the exact prepared intent, challenge, browser origin, RP ID, registered app, account, and credential before submitting anything on-chain.
Supported surface
- Fresh email or OAuth account creation
- Login with an app-origin credential
getSession(),disconnect(), and the interactive authenticatedsetupRecovery()backup flow; onlyUSER_CANCELLEDis a dismissal, while other false results are setup errorssignMessage(),signTypedData(), andsignWithModal()- One
sendIntent()call with visible review or app-owned blind review, directly, throughPayButton, through EIP-1193eth_sendTransaction/wallet_sendCalls, or through wallet-clientsendTransaction()/sendCalls() - Multiple calls submitted atomically as one intent
- Origin/RP-bound passkey listing, addition, removal, recovery, and matching-intent finalization
- SmartSession permission grants and bearer-bound headless execution through
OneAuthHeadlessClient
Deployment requirements
- Serve every calling hostname over HTTPS.
http://localhostis accepted only for development and is not provider evidence. - The exact browser origin is always verified. Ports stay in the RP origin but never appear in the RP ID or account namespace.
- Without
webauthn.rpId, every distinct hostname creates distinct passkeys and smart accounts. - With
webauthn.rpId, the value must be the exact caller hostname or one of its parent domains. - Adding or changing
webauthn.rpIdchanges the SDK bearer storage key, so existing browser sessions must authenticate again. - The registered application's RP ID and every
rpOriginshostname must be exact verified, non-wildcard application domains. - Wildcard origins and unrelated-site Related Origin Requests are unsupported. 1auth does not fetch
/.well-known/webauthnfor this configuration. - Configure sponsorship endpoints before sending an intent.
clientIdidentifies application metadata and authorization; it does not override browser-origin verification. - Changing an RP ID or WebAuthn mode selects a different passkey keypair, on-chain signer, and smart account. 1auth does not migrate accounts between namespaces, so treat the change as a user-facing account switch, not a configuration-only rollout.
- Validate the deployed flow on a real domain with the password managers and browsers you support.