Passwordless Authentication

Choose and implement AuthOS passkey or magic link authentication

AuthOS release 0.8.2 TypeScript SDK 0.8.0 Latest-only documentation

This guide demonstrates passwordless authentication using passkeys (WebAuthn/FIDO2) and magic links. These flows avoid password handling, but their security and usability depend on enrollment, recovery, browser or email security, and deployment configuration.

Overview

AuthOS supports two passwordless authentication methods:

  1. Passkeys (WebAuthn) - Biometric authentication using Touch ID, Face ID, Windows Hello, or hardware security keys
  2. Magic Links - One-time email links for authentication without passwords

Both methods avoid a memorized password in the described flow. Their security properties depend on implementation, browser or email-channel security, recovery design, and deployment configuration; this guide does not provide a general security guarantee.

Prerequisites

Before implementing passwordless authentication:

  • Install the SDK: npm install @drmhse/sso-sdk
  • Initialize the SSO client with your platform URL
  • Ensure your application uses HTTPS (required for WebAuthn)

Choose a passwordless mechanism

Choose the method whose trust boundary and recovery model match your application before opening implementation details.

Mechanism Choose it when Implementation
Passkeys (WebAuthn) Your users have compatible browsers or authenticators and you can provide an independently tested recovery path. Implement passkeys
Magic links Email possession is an acceptable authentication factor and your delivery, expiry, and replay controls are ready. Implement magic links

You can offer both methods, but do not silently turn a failed passkey operation into an email login. Explain the fallback and let the user choose it.

Passkeys (WebAuthn) Authentication

The passkey flow moved to Implement passkeys.

Browser Compatibility Check

See the browser compatibility check.

Registering a Passkey

See Registering a passkey.

Logging In with a Passkey

See Logging in with a passkey.

Complete React Passkey Implementation

The complete component moved to Implement passkeys.

The email-link flow moved to Implement magic links.

See Requesting a magic link.

See Verifying a magic link.

The complete components moved to Implement magic links.

Best Practices

Passkey Security

Review passkey security.

Review magic-link security.

User Experience

  1. Progressive enhancement: Detect browser capabilities and offer appropriate methods
  2. Clear instructions: Guide users through the authentication process
  3. Alternative methods: Always provide fallback authentication options
  4. Loading states: Show clear feedback during authentication
  5. Error messages: Provide actionable error messages

Implementation Checklist

  • Check browser support before showing passkey options
  • Implement proper error handling for WebAuthn exceptions
  • Configure appropriate magic link expiration times
  • Add rate limiting for magic link requests
  • Test on multiple devices and browsers
  • Provide clear user instructions
  • Implement fallback authentication methods
  • Monitor authentication success rates
  • Handle edge cases (expired links, cancelled authentication)

Combining Methods

For the best user experience, combine multiple passwordless methods:

export function UnifiedPasswordlessLogin() {
  const [email, setEmail] = useState('');
  const [method, setMethod] = useState<'passkey' | 'magic_link'>('passkey');

  const hasPasskeySupport = sso.passkeys.isSupported();

  // Auto-select magic link if passkeys not supported
  useEffect(() => {
    if (!hasPasskeySupport) {
      setMethod('magic_link');
    }
  }, [hasPasskeySupport]);

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();

    if (method === 'passkey' && hasPasskeySupport) {
      // Try passkey login
      try {
        const result = await sso.passkeys.login(email);
        // Handle success
      } catch (error) {
        // Fallback to magic link on error
        console.log('Passkey failed, sending magic link');
        await sso.magicLinks.request({ email });
      }
    } else {
      // Use magic link
      await sso.magicLinks.request({ email });
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        required
      />

      {hasPasskeySupport && (
        <div className="method-selector">
          <label>
            <input
              type="radio"
              checked={method === 'passkey'}
              onChange={() => setMethod('passkey')}
            />
            Use Passkey (Touch ID / Face ID)
          </label>
          <label>
            <input
              type="radio"
              checked={method === 'magic_link'}
              onChange={() => setMethod('magic_link')}
            />
            Email me a magic link
          </label>
        </div>
      )}

      <button type="submit">
        {method === 'passkey' ? 'Sign in with Passkey' : 'Send Magic Link'}
      </button>
    </form>
  );
}

Troubleshooting

Passkey Issues

Use Passkey issues.

Use Magic-link issues.

Pages