Security
Most wallet and authentication products ask you to trust them: trust their servers, trust their key management, trust that a breach won't expose your users. 1auth takes a different approach — the architecture is designed so that trust isn't required. Private keys live in your users' devices, signing happens under their biometrics, and the rules that protect their accounts are enforced on-chain, not by anyone's servers.
This chapter explains what makes 1auth secure, in the terms you'd use when comparing authentication providers.
The short version
Five guarantees define 1auth's security model:
- 1auth cannot move your users' funds. Private keys are generated and stored in the secure hardware of the user's own device. Our servers only ever see public keys — there is nothing to steal that could sign a transaction.
- Passkeys only work in their intended domain. App-origin passkeys are bound to the app's verified domain. Experimental cross-origin integrations use passkeys bound to 1auth. In either mode, a lookalike site on another domain cannot use the credential.
- You can bring your own recovery guardian. An app can install a guardian address it controls, so recovery follows the app's own policy and infrastructure. 1auth receives only the public address, never the guardian's private key.
- Apps are quarantined from each other. Every app gets its own isolated account. A malicious or compromised app cannot touch accounts, approvals, or session keys belonging to another app.
- No one can lock users out — including us. Accounts are smart contracts on public blockchains with on-chain recovery. If 1auth disappeared tomorrow, users could still recover and use their accounts.
How this compares to the alternatives
| Seed phrases | Browser extensions | Custodial / MPC / TEE | 1auth | |
|---|---|---|---|---|
| Key lives on user device | Yes | Yes | No | Yes |
| Protected by secure hardware | No | No | Varies | Yes |
| Provider can be breached for keys | N/A | N/A | Yes | No |
| Phishing-resistant by design | No | No | No | Yes |
| Users can recover access | No | No | Yes | Yes |
| Works without extensions or downloads | Yes | No | Yes | Yes |
The trade-offs that used to define this space — security or usability, self-custody or recovery — come from managing keys in software or on servers. Passkeys remove that trade-off: the key is hardware-protected and synced across the user's devices and recoverable, with no seed phrase to write down and no extension to install. For the full custody and regulatory analysis, see Self-Custody & Compliance.
Your users' keys never touch a server
When a user signs up, their device generates a key pair inside its secure hardware — the Secure Enclave on Apple devices, the TPM on Windows, or a password manager like 1Password or Bitwarden. The private key never leaves that hardware. What reaches 1auth is the public key, which is registered as the signer on the user's smart account and verified on-chain for every transaction.
Two consequences matter when you're evaluating providers:
- A breach of 1auth's servers yields nothing usable. An attacker would find public keys, credential IDs, and account metadata — none of which can produce a signature. Compare this to custodial, MPC, or TEE-based wallets, where key material (or key shares) lives on infrastructure an attacker can target.
- Every sensitive action requires the user's biometrics. Registration, transaction signing, message signing, and consent flows all require Face ID, Touch ID, Windows Hello, or a device PIN — verified on the device and enforced again server-side. There is no session token an attacker can steal that authorizes spending.
Apps cannot cross security boundaries
1auth supports two deliberate WebAuthn placements. App-origin is the default,
where the passkey ceremony runs on the app's verified domain. Experimental
cross-origin integrations run the ceremony inside an isolated 1auth iframe or
popup served from passkey.1auth.app.
In app-origin mode, the credential works only in the app's configured RP namespace. 1auth verifies the app origin, RP ID, credential, account, prepared intent, and challenge before submitting anything on-chain. A different domain cannot reuse that passkey, even if it serves copied app code.
In cross-origin mode, the embedding app cannot access the 1auth session or passkey because the browser's same-origin policy isolates the dialog. 1auth also derives app identity from browser-proven origin data rather than trusting what the app claims about itself.
Across both modes, accounts and permissions remain isolated per app. A compromised integration can abuse only the authority its own users granted; it cannot cross into another app's accounts, approvals, or session keys.
Clear signing is available when your app needs it
Blind signing is the SDK default. In these flows, the app is responsible for showing users complete and accurate transaction details before triggering the browser's passkey prompt.
Integrations can opt into 1auth's clear-signing review UI with
experimental_clear_signing: true. The dialog decodes the actual transaction
and computes the signature from that payload, so the app cannot swap the
transaction after review without invalidating the signature.
Clear signing is an optional defense for high-risk actions, not a guarantee that every 1auth integration displays a 1auth review screen. See Signing.
Every signature is single-use and short-lived
Replay attacks — reusing a captured signature or approval — fail by construction:
- Challenges are single-use. Each authentication or signing challenge can be consumed exactly once. Even a perfectly timed race between two copies of the same request produces exactly one success; a failed attempt still burns the challenge.
- Everything expires. Challenges live for five minutes. Prepared transactions carry the quote's expiry and are rejected after it. Sponsorship tokens live for one hour (app identity) or five minutes (individual transaction grant).
- Signatures are bound to their payload. The signature presented at execution must provably match the exact transaction being executed — identity, app, payload, expiry, and chain. A signature over transaction A cannot be attached to transaction B, even by someone who can see both.
- Batch transactions sign one commitment. When a user approves multiple transactions at once, they sign a single cryptographic commitment covering all of them — removing or reordering any item breaks the batch.
Apps are quarantined from each other
Credentials are bound to the RP namespace that created them, and every app sees a different account address for the same user. The account is derived from the app's own namespace, cryptographically and deterministically. Only cross-origin integrations share the provider's RP, so a passkey created for one app-origin app cannot be used by another.
This is a genuine differentiator, and it's worth understanding why it matters:
- Blast radius is contained per app. If a user approves something risky
on
sketchy-app.example, their funds and approvals underyour-app.exampleare untouched — they're a different account entirely. - Session keys and grants stay with the app that earned them. A permission granted to one app can only be used or revoked by that app. Learning another app's grant identifiers is useless.
- Identity remains private to the authentication flow. Apps do not receive the user's email address or cross-app activity. App-origin sessions are bound to the user, app, account, provider, and calling origin; cross-origin sessions remain isolated on 1auth's domain.
Your users' passkeys can live on your domain
Registered apps default to app-origin passkeys: credentials created for your verified domain, with the WebAuthn ceremony running in your top-level app rather than on a shared provider domain.
- Phishing resistance stays with your brand. A passkey bound to
wallet.yourapp.comonly works in that configured RP namespace. A lookalike site on another domain — even one serving copied 1auth integration code — cannot use it. - Credential trust does not depend on 1auth's domain. The passkey remains anchored to a domain you control. 1auth stays authoritative for identity, credential registration, account derivation, and intent verification, but the WebAuthn ceremony runs on your origin.
- The boundary is enforced, not taken on trust. The RP ID and every exact server-authorized
rpOriginshostname must be verified app domains, and 1auth checks the selected exact ceremony origin, RP ID, app, account, credential, prepared intent, and challenge before execution. Sessions are short-lived tokens bound to the user, app, and account — not a shared 1auth cookie.
App-origin is the SDK default for every integration. Apps can explicitly opt into experimental cross-origin mode when they need its broader signing surface. The SDK never falls back between the two credential namespaces because that would select a different passkey, signer, and smart account. Setup: App-origin Passkeys.
Session keys with hard, on-chain limits
For automation — subscriptions, agents, background jobs — apps can ask users to grant a scoped session key instead of prompting for every transaction:
- The user approves exact limits in the dialog: which contract, which function, which parameter values, how much value, how many uses, and until when.
- Those limits are enforced on-chain by the smart account's validator module — not by 1auth and not by the app. A session key that drifts outside its policy simply fails on-chain.
- 1auth never receives the session key itself — only its public address. The key lives wherever the app keeps its own signing infrastructure.
Details: Permissions and Headless Mode.
Recovery without custodians
Self-custody traditionally means "lose your key, lose everything." 1auth's recovery is designed so users get safety nets without handing anyone the power to move their funds:
-
Passkeys sync across devices via iCloud Keychain, Google Password Manager, or the user's password manager — a lost phone is usually a non-event.
-
Guardians can authorize adding a new passkey — and nothing else. A guardian (a linked Google account, or a passphrase-based backup key) can vouch for the user's identity during recovery. Guardians cannot sign transactions, cannot move funds, and cannot change spending rules.
-
Apps can bring their own guardian. A registered app can install an Ethereum guardian address it controls and provide its own recovery authorization flow. 1auth verifies the guardian against the app's registered configuration, installs only the public address, and never receives the guardian private key. This lets teams keep recovery within their own trust model instead of depending on a 1auth-operated recovery signer.
-
Backup files are two-factor by construction. The downloadable backup is encrypted with AES-256-GCM; the passphrase that unlocks it is stored separately by the user. Neither piece alone recovers anything. The recovery key itself is derived from the user's passkey on-device — it is never stored by 1auth.
-
Recovery works even if 1auth doesn't. Independent recovery signers read the account's guardian configuration directly from the blockchain and verify identity with the identity provider — no dependency on 1auth's infrastructure. See Trustless Recovery.
-
The guardian signer is engineered for a hardware enclave. The service that signs recovery authorizations is built to run inside an AWS Nitro Enclave — a hardware-isolated Trusted Execution Environment:
- The guardian key exists only inside the enclave's memory. It is encrypted at rest, and the cloud key service will only decrypt it for the exact, hardware-measured image of the recovery code. No engineer — at 1auth or at the cloud provider — can read it.
- The verification policy is welded to the key. Change a single byte of the identity-checking code and the hardware measurement changes, the key becomes undecryptable, and no signature can be produced. The policy can't be bypassed on an operator-controlled server because there is no operator-controlled server in the trust path.
- Even an attacker with full cloud console access can restart or silence the service — but cannot make it sign for the wrong identity.
The Nitro Enclave build is in final production rollout; the signing policy and its on-chain guarantees are the same in every environment.
Sponsorship is guarded like money
If your app sponsors gas fees, the endpoints that mint sponsorship tokens are spending your budget — and 1auth's model treats them that way:
- Sponsorship grants are bound to one specific transaction and expire in minutes, so a leaked token can't be reused against a different intent.
- Your server decides which transactions you'll sponsor (chains, contracts, accounts, caps) before any token is signed — this check works even against scripted attackers that ignore browsers, cookies, and CORS.
- Project-level budget caps in the Rhinestone dashboard bound the worst case if anything else goes wrong.
Full setup: Fee Sponsorship.
Questions to ask any auth provider
When comparing 1auth against alternatives, these are the questions that separate architectural security from marketing:
| Question | 1auth |
|---|---|
| Where do private keys live? | User's device hardware. Nowhere else. |
| What does a server breach expose? | Public keys and metadata — nothing that can sign. |
| Can the provider sign without the user? | No — every signature requires on-device biometrics. |
| Can a lookalike domain use the user's passkey? | No — the credential is bound to the app's verified RP namespace or, in cross-origin mode, to 1auth. |
| Can one app touch another app's accounts? | No — accounts are derived per app domain. |
| Whose domain are passkeys bound to? | App-origin uses the app's verified domain; experimental cross-origin integrations use 1auth's domain. |
| Who enforces session-key limits? | The blockchain, not the provider. |
| Can recovery guardians move funds? | No — they can only authorize adding a new passkey. |
| Can an app use its own recovery guardian? | Yes — 1auth installs the registered public address and never receives the guardian private key. |
| Who can access the recovery signing key? | No one — it exists only inside an attested hardware enclave. |
| What happens if the provider shuts down? | Users recover via independent signers reading on-chain state. |
If a competitor's answer to any of these is "trust us," that's the difference.
Your responsibilities as an integrator
1auth secures the authentication and signing layers; a few things remain yours:
- Serve your app over HTTPS — passkeys require a secure context.
- Register your domains in the developer portal so users skip the unknown-origin warning.
- Use clear signing for high-risk actions — and when you blind-sign, present the full payload in your own UI first.
- Guard sponsorship endpoints like money — authenticate callers, scope what you'll sponsor, and set a budget cap.
- Scope session keys narrowly — exact functions, tight limits, short windows, and revoke when users disconnect.
- Verify signatures on your backend for your own APIs, with a domain and timestamp in the signed message.
- Never ask users for secrets — no flow should ever need a passkey, passphrase, or session private key. If one seems to, it's a bug.
Related pages
- Why Passkeys — the technology behind the guarantees
- Self-Custody & Compliance — custody analysis and regulatory framing
- Architecture — how the components fit together
- Recovery — guardian-based and trustless recovery
- Signing — blind signing and the review UI
- Fee Sponsorship — securing token-minting endpoints
- Permissions — scoping session keys