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:

javascript
const sdk = await HyphenSDK.init({
  publishableKey: 'pk_live_...'
});

sdk.isAuthenticated(); // false
sdk.getUser();         // null

Anonymous sessions can use SDK routes that both the publishable key scope and the route policy allow. Many teams use them for read-only dashboards and lightweight operational views. Actions that require a registered person still ask the user to sign in, even when the key includes the relevant scope.

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

javascript
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:

javascript
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:

bash
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": "[email protected]",
    "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.

Without writing a call. The gateway hosts a people page at https://<gateway>/people. The account holder opens it with the management token, picks the organization and the publishable key, and registers, edits, suspends, or removes people with their roles. The token is sent once and exchanged for a people session: fifteen minutes, accepted only on the people routes above, revoked when the page's session ends. The management token itself is never stored in the browser. Process Studio links to the page from its header.


Authorization Layers

Hyphen SDK authorization has two layers:

  1. Publishable key scope: enforced by the gateway
  2. SDK user permissions: arbitrary metadata for your host app

Publishable key scope

The gateway enforces the publishable key's allowed scope, including:

  • allowed_workflows
  • allowed_tables
  • allowed_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 JSON you set when you register the user. Hyphen returns it after one-time-code sign-in so your host app can make UI decisions, and the gateway reads one key from it for authorization:

  • approver_roles (an array of strings; roles is accepted as an alias). A signed-in user may decide an approval or an agent review only if this array contains the role the step names in its approver_role. Otherwise the gateway answers 403 approver_role_required.

Everything else in the object is yours.

json
{
  "approver_roles": ["fraud_l1_reviewer", "payment_release_approver"],
  "team": "operations"
}

Roles are plain strings matched by name. A Process Studio case names its role through its People setting; a workflow you author names it in the approval step. Register each reviewer with the roles they hold, and keep the role names identical on both sides.

Hyphen stores and returns the whole object, but only approver_roles is enforced, and it is separate from 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:

javascript
const sdk = await HyphenSDK.init({
  publishableKey: 'pk_live_...',
  onSessionExpired: () => {
    console.log('Session expired');
  }
});

You can also subscribe to the SDK event bus:

javascript
sdk.on('session:expired', () => {
  console.log('Session expired');
});

Checking Session State

javascript
sdk.isAuthenticated();

sdk.getSession();
// {
//   token: 'skt_...',
//   expires_at: '2026-06-03T19:00:00.000Z',
//   session_id: 'sess_...',
//   type: 'authenticated'
// }

sdk.getUser();
// {
//   id: '...',
//   email: '[email protected]',
//   display_name: 'Operations Analyst',
//   permissions: { team: 'operations' }
// }

Logout

javascript
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.