Purpose
This page documents the frontend session and auth routes implemented infrontend-api.
These routes are session-scoped. They are not backend API key routes.
They are the routes used by frontend SDKs and session-based embedded product flows.
Terms
Deployment host
The deployment host is the host used to resolve the current deployment. Examples:frontend.gokboru.in6tumlz9k81r7vzob.fapi.trywacht.xyz
Frontend session
The frontend session is the browser session managed byfrontend-api.
In production, it is transported by the __session cookie.
In non-production deployments, session transport can use a development-session value.
Active sign-in
A frontend session can contain one or more sign-ins. The active sign-in is the sign-in currently used to derive:- current user
- current organization context
- current workspace context
- JWT tokens returned by
GET /session/token
Middleware prerequisites
These routes sit behind the request prelude infrontend-api.
The request prelude is responsible for:
- resolving the deployment from the request host
- reading
__sessionor__dev_session__ - creating a new session when no session exists
- refreshing expired session tokens
- attaching deployment and session data to request locals
Session transport
Production
Production uses the__session cookie.
Current behavior in prelude.go:
- if
deployment.BackendHoststarts withfrontend., that prefix is stripped before setting the cookie domain - example:
frontend.gokboru.insets cookieDomain=gokboru.in - example:
frontend.x.example.comsets cookieDomain=x.example.com
Non-production
Non-production uses development-session transport. Current behavior:- incoming development session can be provided through
__dev_session__ - refreshed development session is returned through
X-Development-Session
Route inventory
| Method | Path | Purpose |
|---|---|---|
GET | /session | Return the current frontend session object. |
GET | /session/token | Exchange the current frontend session for a signed JWT. |
POST | /session/switch-sign-in | Switch the active sign-in inside the current browser session. |
POST | /session/sign-out | Sign out the current active sign-in or a specific sign-in. |
POST | /session/switch-organization | Switch or clear the active organization context. |
POST | /session/switch-workspace | Switch or clear the active workspace context. |
GET | /session/ticket/exchange | Exchange a single-use session ticket. |
GET /session
Returns the current session object.
Auth requirements:
- no backend bearer token is required
- the request must resolve to a valid deployment and session transport
200with the current session indata
- if there is no valid existing session, the request prelude creates one before the handler runs
- this endpoint therefore always reflects the current browser session, not a backend principal
GET /session/token
Returns a signed JWT for the current session.
This is the route consumed by server SDKs when they exchange frontend session state for a verifiable JWT.
Query params
template: optional JWT template name. Defaults todefault
Success requirements
- current session exists
- current session has an active sign-in
Default token contents
The default implementation builds a JWT with:iss:https://<deployment.BackendHost>sub: active user IDsid: current session IDorganization: active organization ID when presentworkspace: active workspace ID when presentpermissions: grouped organization and workspace permissionsmetadata: rendered JWT template metadata when configured
Success response
Failure cases
404template not found404session not found400no active sign in500token rendering or signing failure
Important distinction
__sessionis the browser session token/session/tokenreturns the signed auth JWT used by server-side verification
POST /session/switch-sign-in
Changes active_signin_id inside the current browser session.
Query params
sign_in_idrequired
Success behavior
- the sign-in must already belong to the current session
- on success, the session cache is invalidated and the updated session is returned
Failure cases
400invalid sign in ID400sign in ID not found in the current session
POST /session/sign-out
Signs out the current browser session.
Query params
sign_in_idoptional
Behavior
- if
sign_in_idis provided, only that sign-in is deleted - otherwise all sign-ins for the session are deleted and
active_signin_idis cleared
Side effects
- session cache is invalidated
- session deletion webhooks are published when applicable
Failure cases
400invalid sign in ID400sign in not found for the current session500transaction failure
POST /session/switch-organization
Changes the active organization membership for the active sign-in.
Query params
organization_idoptional
Behavior
- if
organization_idis omitted or empty, organization and workspace active memberships are cleared - otherwise the handler validates membership and organization eligibility rules
Eligibility checks
The current implementation checks:- organization membership exists
- per-organization IP allowlist rules when enabled
- per-organization MFA enforcement when enabled
- organization admins bypass those restrictions
Failure cases
400no active sign in400invalid organization ID400user is not a member of this organization403IP and/or MFA eligibility failure500update failure when clearing active organization context
POST /session/switch-workspace
Changes the active workspace membership for the active sign-in.
Query params
workspace_idoptional
Behavior
- if
workspace_idis omitted or empty, workspace and organization active memberships are cleared - otherwise the handler validates membership and workspace eligibility rules
Eligibility checks
The current implementation checks:- workspace membership exists
- per-workspace IP allowlist rules when enabled
- per-workspace MFA enforcement when enabled
- workspace admins and organization admins bypass those restrictions
Failure cases
400no active sign in400invalid workspace ID400user is not a member of this workspace403IP and/or MFA eligibility failure500update failure when clearing active workspace context
GET /session/ticket/exchange
Exchanges a single-use ticket stored in Redis.
Query params
ticketrequired
Ticket types currently supported
impersonationagent_accesswebhook_app_accessapi_auth_access
Shared validation before type-specific handling
The handler first validates:- ticket is present
- ticket exists in Redis
- payload is valid JSON
deployment_idin the ticket matches the current deployment
Shared failure cases
400missingticket401invalid or expired ticket400invalid deployment ID in ticket401ticket not valid for this deployment400invalid ticket type
Impersonation ticket behavior
Forticket_type = impersonation:
- an existing frontend session is required
user_idis required- the target user must exist on the deployment and not be disabled
- the target user cannot already be signed in on the current session
- a new sign-in is created and made active
- the ticket is deleted after successful exchange
success: truemessage: "Impersonation successful"- updated
session
Related SDK consumers
These routes are consumed by:- Next.js Server Auth
- frontend hook packages for React Router and TanStack Router
- app-specific ticket exchange flows for webhook apps, API auth apps, and AI runtime access
