Build a consumer application
Availability: this walkthrough describes a service template currently available through beta repository access. It is not a public standalone starter. You can follow the same design in your own application using the first-login guide. For runnable public package examples, use starter projects.
Before you start
You need an accessible Udibo tenant, a development application configured as a confidential authorization-code client with refresh tokens, and a client secret. Choose opaque access tokens for these walkthroughs; they validate through introspection. See application registration for the exact settings.
The app requests openid profile email. Define application permissions in your
tenant's permission catalog and assign roles separately; permission names are
not additional OAuth scopes.
Set up the example
Register http://localhost:8008/auth/callback and configure these local runtime
values:
| Variable | Value |
|---|---|
UDIBO_ISSUER | Your tenant's issuer origin |
APP_ORIGIN | http://localhost:8008 |
UDIBO_CLIENT_ID | The registered application's client ID |
UDIBO_CLIENT_SECRET | A secret created for that application |
If you have the template checkout, run deno task dev from templates/b2c-app.
Keep the client secret and tokens on the server.
The example models a personal notes application. Define notes:publish as an
application permission and grant it through a role to one test user.
1. Establish who is making the request
Hosted login completes through a backend-for-frontend. The server validates access tokens through introspection and reads profile and email fields from UserInfo. The browser receives a session cookie.
Use the validated subject to identify the user. Email and display name are profile fields; they can change and are not database ownership keys.
Checkpoint: sign in as two people and confirm each request resolves to the correct user.
2. Protect each person's data
The notes list filters by the signed-in subject. Reading a note checks its owner before returning it. Keep both checks when replacing the example's in-memory store with your database: a filtered list does not protect a direct request for somebody else's note ID.
Creating a note also requires a verified email address. This is an account requirement separate from being authenticated. Use the validated profile's verification state and provide a clear path to verification.
Checkpoint: one person's note never appears in another person's list or direct lookup. An unverified user cannot create a note.
3. Add a paid or privileged capability
Publishing requires both ownership of the note and the notes:publish
permission from the token's current introspection response. A role can grant
that permission without changing application code.
The browser's cached session data can help render a button. It is not the authority for the server action. Removing the role should deny the next protected request even if the browser still shows the old button.
Checkpoint: test an owner with the permission, an owner without it, and a different user who does have the permission.
Make it your product
Choose your signup fields, passwordless options, and MFA policy. Walk through recovery and logout as well as the happy-path login.
The template demonstrates profile reads and application-owned notes. It does not implement every account-management or sensitive-action reauthentication screen. Identify those requirements before treating the example as a complete account area.
Replace in-memory data, use production session storage, and finish the production checklist. For existing users, begin with migration planning.
Last verified 2026-09-06.

