Post-Login Landing
After sign-in, different users should land on different pages — an admin on the admin home, a customer on their own record. Sovrium expresses this as auth configuration, not as redirect logic scattered across pages: each role declares a defaultLanding, the auth block declares a landingPath mount point, and noAccessPath catches whoever matches nothing.
auth:
strategies:
- type: emailAndPassword
scopeTables: [clients]
defaultRole: customer-admin
landingPath: /portal
noAccessPath: /403
roles:
- name: engineer
defaultLanding: /admin
- name: customer-admin
defaultLanding: /portal/clients/$currentUser.assignments.clients[0]
pickerLanding: /portal/select/clientsConfiguration Fields
Two fields on auth, two on each role:
| Field | Level | Description |
|---|---|---|
landingPath |
auth |
Engine-resolver mount path. Sessions navigating here are redirected to the matching role's defaultLanding. Must start with /. Required whenever any role sets defaultLanding or pickerLanding. |
noAccessPath |
auth |
Fallback path when no role's defaultLanding matches the session. Must start with /. Defaults to /403. |
defaultLanding |
roles[] |
Per-role landing URL. Must start with /. May contain at most one $currentUser.assignments.<table>[0] token. |
pickerLanding |
roles[] |
Multi-record fallback for a templated defaultLanding. Must start with /. Must not contain any assignment token. |
landingPath is user-controlled — pick /portal, /dashboard, /home, or anything else. There is no engine convention. The same goes for pickerLanding: /portal/select/clients, /companies-picker, whatever you like.
Three cross-field rules are checked when the config is decoded, so a half-wired landing setup fails sovrium validate rather than misrouting at runtime:
auth.landingPathmust be set once any role declaresdefaultLandingorpickerLanding.- A role with
pickerLandingmust also declaredefaultLanding— the picker is a fallback, not a landing in its own right. - That
defaultLandingmust be templated. ApickerLandingbeside a bare URL can never fire, so it is rejected rather than left as dead config.
Resolution Logic
When an authenticated session navigates to auth.landingPath, the engine walks auth.roles[] in declaration order and applies the first role the user holds. Order is therefore meaningful: declare the most specific role first.
defaultLanding shape |
Assignment count for the templated <table> |
Engine action |
|---|---|---|
| Bare URL (no token) | n/a | Redirect to defaultLanding unconditionally. |
| Templated (one token) | Exactly one assignment | Substitute the assignment ID, redirect there. |
| Templated (one token) | More than one assignment | Redirect to the role's pickerLanding. |
| No role matched / no assignments | n/a | Redirect to noAccessPath (defaults to /403). |
$currentUser.assignments Interpolation
Moved to Assignments & Landing Guards.
The landingPath Page Is the Access Guard
Moved to Assignments & Landing Guards.
Full Example
auth:
strategies:
- type: emailAndPassword
scopeTables: [clients]
defaultRole: customer-admin
landingPath: /portal
noAccessPath: /403
roles:
- name: engineer
defaultLanding: /admin
- name: customer-admin
defaultLanding: /portal/clients/$currentUser.assignments.clients[0]
pickerLanding: /portal/select/clients
pages:
- name: portal-landing
path: /portal
access: { require: authenticated, redirectTo: /login }
components: []
- name: client-detail
path: /portal/clients/:id
access: authenticated
components: []
- name: client-picker
path: /portal/select/clients
access: authenticated
components: []
- name: admin-home
path: /admin
access: [engineer]
components: []
- name: forbidden
path: /403
access: authenticated
components: []In this app an engineer lands on /admin; a customer-admin with one client lands on that client's detail page; with several, on the picker; and anyone the resolver cannot place hits /403.
Related Pages
- Assignments & Landing Guards — the interpolation token and the guard page.
- Roles & RBAC — where
defaultLanding/pickerLandingare declared. - Sessions —
scopeTables,user_access, and$currentUser.activeAssignment. - Pages — page
path,access, anddataSource.filter.
Last updated August 11, 2026
This documentation was written with AI, so errors or outdated content are possible. Sovrium is in beta. Contributions and corrections are welcome.