Authentication
Gao uses Passkey (WebAuthn) as the primary authentication method. No passwords. No email codes. Credentials are device-bound and phishing-proof — the private key never leaves the user’s device.
GaoAuth
import { GaoAuth } from '@gao/system-sdk'
const auth = new GaoAuth()
Register (New User)
// Step 1: Start registration
const credential = await auth.register({
displayName: 'Alice', // shown to user during Passkey prompt
})
// Step 2: Complete — stores credential, issues domain + token
const { domain, token, refreshToken } = await auth.completeRegistration(credential)
// domain = auto-assigned e.g. "alice.gao"
// token = JWT access token (1 hour TTL)
// refreshToken = JWT refresh token (7 days TTL)
---
### Login (Returning User)
// Step 1: Initiate — triggers device Passkey prompt
const assertion = await auth.login()
// Step 2: Complete — verifies signature, issues token
const { domain, token, refreshToken } = await auth.completeLogin(assertion)
Use with SDK
const sdk = new GaoSDK({
domain,
token,
environment: 'production',
})
---
### Token Lifecycle
Token
TTL
Purpose
Access token
1 hour
Attach to all API requests
Refresh token
7 days
Obtain new access token
// Refresh when access token expires (GAO-4001)
const { token: newToken } = await auth.refresh(refreshToken)
Auto-refresh is built into the SDK — if you initialize with both token and refreshToken, the SDK refreshes automatically before expiry.
React Hook#
import { useGaoAuth } from '@gao/system-sdk/react'
function LoginPage() {
const { login, register, isAuthenticated, domain, loading, error } = useGaoAuth()
if (isAuthenticated) return ``<Dashboard />``
return (
<div>
<button onClick={login}>Sign in with Passkey</button>
<button onClick={() => register({ displayName: 'Alice' })}>
Create account
</button>
{error && <p>{error.message}</p>}
</div>
)
}
---
Passkey Compatibility
Platform
Support
iOS Safari 16+
✅ Full support
Android Chrome 108+
✅ Full support
macOS Safari / Chrome
✅ Full support
Windows Hello
✅ Full support
Older browsers
❌ Not supported
For unsupported browsers, show a clear upgrade message. Do not fall back to passwords.
---
Multi-Device
Each device registers its own Passkey. All devices are linked to the same `.gao` domain via the identity layer.
// Add new device (user must be logged in on existing device)
const credential = await auth.addDevice({ displayName: 'My iPad' })
await auth.completeAddDevice(credential)
// List registered devices const devices = await auth.listDevices()
// Remove a device await auth.removeDevice(deviceId)
Security Notes#
-
Private key never transmitted to any server — stays on device
-
Passkey is bound to the domain (
studio.gaoor your app domain) -
Phishing-proof: Passkey only works on the exact domain it was registered for
-
Biometric confirmation (Face ID / Touch ID / Windows Hello) required on every login