Authentication
The SDK supports two session types:
- Anonymous sessions created automatically when you call
HyphenSDK.init() - Authenticated sessions created when a pre-registered user completes OTP verification
Both session types are still bounded by the publishable key's server-side scope.
Anonymous Sessions
When you call HyphenSDK.init(), the SDK creates an anonymous session:
const sdk = await HyphenSDK.init({
publishableKey: 'pk_live_...'
});
sdk.isAuthenticated(); // false
sdk.getUser(); // null
Anonymous sessions can use any SDK route the publishable key allows. Many teams use them for read-only dashboards and lightweight operational views, but the actual capabilities come from the key scope, not from the anonymous session type itself.
All SDK requests made through an anonymous session are still logged with the session ID.
Authenticated Sessions (OTP)
Use OTP when you want user attribution in audit trails or when your host app wants to require a known user before showing certain controls.
Login Flow
sdk.login();
The SDK renders an email + OTP modal. After a successful verification, the current session is replaced with an authenticated session.
To react to successful login, listen for the modal's authenticated event and then read the current user from the SDK instance:
document.addEventListener('authenticated', () => {
console.log('Signed in as:', sdk.getUser()?.email);
});
Pre-Registration Requirement
Users must be registered to a publishable key before they can authenticate. The gateway does not support open signup.
Add users via the gateway management API:
curl -X POST https://your-hyphen.example.com/sdk/admin/publishable-keys/:keyId/users \
-H "Authorization: Bearer YOUR_MANAGEMENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"email": "analyst@acme.com",
"display_name": "Operations Analyst",
"permissions": {
"team": "operations"
}
}'
The permissions object is returned with the authenticated user and can be used by your host app for UI decisions. The gateway's primary authorization layer is still the publishable key scope.
Authorization Layers
Hyphen SDK authorization has two layers:
- Publishable key scope — enforced by the gateway
- SDK user permissions — arbitrary metadata for your host app
Publishable key scope
The gateway enforces the publishable key's allowed scope, including:
allowed_workflowsallowed_tablesallowed_actions
This is the primary authorization boundary for SDK traffic. For example, a key can include a special action scope such as process_studio, and requests outside the configured scope are rejected by the gateway.
SDK user permissions
The permissions object on an SDK user is not a fixed Hyphen permission enum. It is arbitrary JSON metadata returned after OTP authentication so your host app can make UI or workflow decisions.
For example:
{
"team": "operations",
"can_approve": true
}
Hyphen stores and returns that metadata, but it is not the same thing as the gateway-enforced key scope.
Runtime API key permissions such as full, read_only, and execute_only apply to gateway runtime API keys, not to SDK publishable keys.
Session Lifecycle
Token Expiry
SDK sessions use a fixed TTL. In the default gateway configuration, sessions expire after 4 hours, but your deployment can change that value.
When the session expires, the SDK clears the local token and triggers your configured expiry handler:
const sdk = await HyphenSDK.init({
publishableKey: 'pk_live_...',
onSessionExpired: () => {
console.log('Session expired');
}
});
You can also subscribe to the SDK event bus:
sdk.on('session:expired', () => {
console.log('Session expired');
});
Checking Session State
sdk.isAuthenticated();
sdk.getSession();
// {
// token: 'skt_...',
// expires_at: '2026-06-03T19:00:00.000Z',
// session_id: 'sess_...',
// type: 'authenticated'
// }
sdk.getUser();
// {
// id: '...',
// email: 'analyst@acme.com',
// display_name: 'Operations Analyst',
// permissions: { team: 'operations' }
// }
Logout
sdk.logout();
logout() clears the current SDK session. It does not automatically mint a fresh anonymous session. If you want to continue in anonymous mode, reinitialize the SDK or reload the page.
Security Model
| Property | Detail |
|---|---|
| Origin binding | Publishable keys are validated against configured origins before the SDK can start a session |
| Session tokens | Fixed-TTL session tokens with server-side validation; no silent refresh |
| OTP codes | 8-digit codes; by default they expire after 10 minutes and lock after 5 failed attempts |
| Org resolution | Server-side from the publishable key — the SDK never sends X-Org-Id |
| Audit logging | SDK actions are logged with the session identity (anonymous session ID or authenticated user email) |
| Shadow DOM usage | Components render in Shadow DOM to reduce host-page style collisions; this is not a security boundary |
Publishable keys are not secret. They are designed for client-side use. Security is enforced server-side through origin restrictions, scoped access, session validation, and rate limiting.
A publishable key cannot access admin endpoints or act outside its configured scope. It can read or mutate the SDK routes that its scope allows — including Process Studio beta if the key includes the process_studio action scope.