Skip to content

Connect your first application

By the end of this guide, a user will sign in on your Udibo tenant, return to your application, and call an API protected by their application session. Start with one development application and one test account.

Before you start

You need private-beta access, a tenant you can manage, and a web application with a backend. Start at Udibo for access. If you are waiting, run the local package quickstart to explore the flow.

In the dashboard, Identity lists the tenants you can manage. Create or select a development tenant, then keep its dashboard open while connecting your app. If you cannot access a required setting, ask your tenant administrator to grant the corresponding access; an application user's role does not grant dashboard administration.

For a new project, choose a starter. For an existing app, add this integration alongside your current login and switch it on for test accounts first. Follow the migration plan before moving users.

1. Register the application

Open your tenant's Applications page and choose Create application. For a web app whose backend handles the callback:

SettingDevelopment starting pointWhy
NameA name you recognize, such as “My app development”Distinguishes this registration from production
EnvironmentDevelopmentPermits a local HTTP callback
Confidential clientEnabledYour backend can protect the client secret
GrantsAuthorization Code and Refresh TokenSigns users in and renews their access
Redirect URIsYour app's complete callback URLThe service returns the browser here after sign-in
Access token formatOpaqueYour API validates tokens by introspection

For example, an app running at http://localhost:8000 with its BFF mounted at /auth uses http://localhost:8000/auth/callback. Match the actual port and path. Use that same URL in your application's configuration.

Save the application. Saving creates the client ID; it does not create a secret. On the application's detail page, use Create new secret and store the one-time value in your backend's secret configuration. Secret management requires separate administrator permission.

The application configuration guide explains token formats, scopes, production callbacks, and public clients.

2. Gather the configuration

Keep these values together for this environment:

  • The tenant's trusted issuer URL, supplied through your beta setup

  • This application's client ID and client secret

  • The exact callback URL you just registered

  • The scopes your integration needs; request openid, and add profile and email when you need those identity claims

  • A separate, high-entropy application secret to protect pending login state

The issuer is the identity host, not your application's host and not the dashboard URL. Read its discovery document at {issuer}/.well-known/oauth-authorization-server; the client can discover the protocol endpoints instead of copying them into every route.

Use environment variables or your deployment's secret manager for credentials. Do not put the client secret in browser configuration, a public repository, or an agent prompt.

3. Connect the backend and browser

Follow Use Udibo's identity service. It contains the checked Hono BFF wiring and the browser client in one place.

The integration has three pieces:

  1. Your backend mounts HonoBff at /auth, exchanges the authorization code, and stores the application's session.

  2. Your API validates the access token. With opaque tokens, use introspection against the issuer, as shown in Protect an API.

  3. Your browser uses BffClient to start login and make authenticated requests to the same application origin. React applications can use the package's provider and hooks for session presentation.

The guide explicitly marks the session store and resource server as dependencies you supply. A declared variable in a snippet is not a working database adapter. Use a runnable example if you want to inspect all the pieces together before adapting an existing application.

4. Complete a sign-in

Use a test user in the tenant. For self-registration, configure the tenant's sign-up mode to allow it and enable the intended sign-in method. A closed sign-up mode does not prevent an existing eligible user from signing in.

Open your application in a browser and start login from the application. The browser should visit the tenant's hosted sign-in page, complete authentication, and return to your registered callback. Your app then reports an authenticated session.

Checkpoint: a protected request succeeds while signed in. In a separate signed-out browser context, the same protected request is refused. Signing out ends the application's session; the tenant's SSO session is a separate session, so test the logout behavior you intend to offer.

Account sessions in your application

Use the person's access token on your tenant's host to build device controls:

RequestResult
GET /api/account/sessions{sessions: [...]} with opaque IDs, creation and activity times, address, user agent and a current marker
DELETE /api/account/sessions/{sessionId}204 after revoking one other login session
POST /api/account/sessions/revoke-others{revoked: number} after revoking the person's other login sessions

These operations require no additional scope or dashboard seat. The credential selects the person and tenant; request parameters cannot select another account. Machine credentials are refused. Session lists exclude revoked, expired and idle sessions and never include secrets or tokens.

current identifies the login that issued the credential. A credential can outlive that login: then no row is current, and revoke-others returns 409 with reason: "current_session_required". Deleting the current login returns 409 with reason: "current_session"; use the tenant's end-session endpoint to sign out. An unknown session ID and another person's ID both return the same 404.

Revocation stops session-owned tokens on the next request. A third-party grant that originated from the login retains its existing lifetime. Revoke-others also revokes idle sessions, even though the list omits them. Mutations accept no body or an empty object and share a budget of 30 attempts per minute per person with the hosted security page. A 429 includes Retry-After in seconds.

5. Make the first success repeatable

  • Repeat the flow after reloading the page and after restarting the backend

  • Confirm expired or revoked sessions cannot be restored by a refresh race

  • Confirm the browser has no access or refresh tokens in local storage

  • Test one operation without its required permission; it must be refused

Use troubleshooting if a checkpoint fails. Once it passes, choose sign-in methods, add organizations and permissions where needed, and work through the production checklist.

Last verified 2026-09-09.