Skip to content

Connect flow

View as Markdown

This page covers the Connect protocol: the browser-mediated Sudomimus flow used when your application wants direct control over the login round-trip. Connect speaks JSON over HTTPS, so any backend language with an HTTP client works; examples below are in curl, Node.js, Python, and Go.

For production code, prefer an official SDK where one exists. Start with the SDK overview or jump to the TypeScript SDK for @sudomimus/connect.

If you’re building a native client (desktop, game, CLI), see Native clients. For OIDC, see OIDC relying parties.

Tabs are synchronised across the page: pick your language once and every block below switches with it.

PhaseInitiatorEndpointResult
1. EstablishApplication backendconnect-api POST /establish{ exposureKey, hiddenKey }
2. AuthenticateBrowservia.sudomimus.comThe user completes an allowed challenge
3. RedeemApplication backendconnect-api POST /redeem{ accessToken, refreshToken }
4. RefreshApplication backendsession-api POST /refreshA new access token and rotated refresh token

Three parties split responsibility:

  • Your backend signs /establish, stores hiddenKey, redeems the completed inquiry, and verifies the resulting tokens.
  • The browser carries exposureKey to the hosted authentication UI but never sees hiddenKey.
  • via.sudomimus.com runs the passkey, email OTP, OAuth, or federation challenge and creates confirmationKey only after authentication succeeds.

The first three phases are specific to Connect. OIDC uses authorization code + PKCE, while native direct-issue exchanges a Steam ticket or AccessKey in one request. After any ordinary application flow has a refresh token, the shared Session API owns refresh, introspection, logout, and revocation.

Your backend asks Connect to open an authentication session. The response gives you an exposure key (passed to the browser) and a hidden key (kept on the server).

Terminal window
curl -X POST https://connect-api.sudomimus.com/establish \
-H "Content-Type: application/json" \
-H "Authorization: SudomimusClientJWT $SUDOMIMUS_CLIENT_AUTH_JWT" \
-d '{
"applicationAnchor": "your-application",
"returnMethods": [
{
"type": "CALLBACK",
"payload": { "callbackUrl": "https://your-app.com/auth/callback" }
}
]
}'

Store hiddenKey against the user’s pending session (e.g. in a server-side store). Send the user to via.sudomimus.com with the exposureKey in the URL.

2. Authenticate — hand off to via.sudomimus.com

Section titled “2. Authenticate — hand off to via.sudomimus.com”

Redirect the user’s browser to via.sudomimus.com with the exposure key. The user completes the passkey or email-OTP challenge there.

# No HTTP call — this is a 302 redirect from your application:
Location: https://via.sudomimus.com/?exposure-key=<exposureKey>

When the user finishes, via.sudomimus.com redirects the browser to your concrete callbackUrl with exposure-key and confirmation-key appended as query parameters. Existing query parameters and fragments are preserved. If the URL already contains either reserved parameter, Connect overwrites it with the current Inquiry value; do not put key templates in the callback URL.

In your callback handler, combine the three keys and exchange them at Connect for an access token plus a refresh token.

Terminal window
curl -X POST https://connect-api.sudomimus.com/redeem \
-H "Content-Type: application/json" \
-d '{
"exposureKey": "...",
"hiddenKey": "...",
"confirmationKey": "..."
}'

The access token is a signed JWT. Read its kid, select that key from the application’s Session JWKS at GET /applications/{applicationAnchor}/jwks.json, verify the signature, and only then trust its claims. See Tokens and verification for the full recipe, including cache refresh and the kty: "Access" header check.

Before the access token expires, exchange the refresh token at Session API for a fresh access token and a new refresh token. /refresh does not require a client-auth JWT. Refresh tokens are rotated — the token you present is consumed, and the response returns its replacement. Persist the new refreshToken and use it for the next refresh; re-using a spent one revokes the whole session. Near-simultaneous concurrent refreshes of the same token (e.g. multiple tabs) are tolerated and converge on one session; only reuse after the replacement has been issued revokes it.

Terminal window
curl -X POST https://session-api.sudomimus.com/refresh \
-H "Content-Type: application/json" \
-d '{ "refreshToken": "..." }'

For introspection, logout, and account-wide revocation, see Managing sessions.

POST /info returns the localized public profile of an application given its anchor. It does not require a client-auth JWT, so it is safe to call from browsers and untrusted contexts. Signing keys deliberately live on the Session JWKS endpoint, not this metadata route.

Terminal window
curl -X POST https://connect-api.sudomimus.com/info \
-H "Content-Type: application/json" \
-d '{ "applicationAnchor": "your-application", "locale": "en-US" }'

Use GET https://session-api.sudomimus.com/applications/{applicationAnchor}/jwks.json for token verification keys. Cache that response according to Cache-Control, select the JWT’s exact kid, and refresh once when an unknown kid appears.