Console
The web console is the operator surface for everything below the data plane: connectors, identity sources, tenants, regions, licensing, audit. It's a single Nuxt application served alongside the webserver, gated by console RBAC.
This page is the tour — what each section does and how operators move through it. For the underlying permission model (roles, scope, decision matrix), see the console-RBAC concept page.
Layout
The left navigation groups every page into five operational areas:
| Group | Pages | Purpose |
|---|---|---|
| Query | Search, Documents | Interactive search preview against the live corpus. Gated by search:query + documents:read and still filtered by OpenFGA, so what an operator sees in the preview matches what end-users would see. |
| Ingest | Sources, Identity, Identity sources, Pipeline, Supersession | Connector + identity-source administration. The Pipeline page renders the live data flow; Supersession exposes the deduplication policy + recent decisions. |
| Platform | Tenants, Regions, Secret providers, License | Cluster-wide configuration: per-tenant provisioning, residency regions, the secret-provider registry, license status + seat usage. |
| Access | Users, Roles | Console-side identity + RBAC. Distinct from the Identity page under Ingest — see below. |
| Audit | Audit log | Searchable audit trail. Every privileged action lands here, including bootstrap-admin break-glass operations. |
The nav adapts to the caller's role: pages the caller has no permission for are hidden rather than 403'd, so a viewer sees only Query + Audit, a connector_admin sees Query + Ingest + Audit, and so on.
People vs Users — two distinct populations
The console has two identity surfaces that operators routinely confuse:
| Page | Population | Authoritative store | Role |
|---|---|---|---|
| Ingest → Identity | The corpus's subject set — every person who appears as a principal on an ACL tuple in the corpus | OpenFGA tuples (projected from connector ACL events) | This is what the source-data ACL evaluator answers against. |
| Access → Users | Console administrators — the humans who can sign into the console at all | Postgres admin_users + their console_role_bindings rows | This is what console RBAC gates on. |
A person can appear in one, both, or neither:
- A Confluence reader who's never signed into the console: appears in Identity, never in Users.
- A platform operator with no source-system access: appears in Users (with some role), never in Identity.
- A platform operator who also has Confluence access: appears in both, mapped via canonical email.
The two never share rows. Conflating them is the most common operator mistake when interpreting "this user can't see anything" reports — the right question is "which surface is the user actually on?".
First sign-in: bootstrap break-glass
Every fresh cluster ships with a bootstrap-admin account with global-admin capability. It exists so the first operator can sign in before any OIDC identities are configured. To use it:
- Set
MOOLELO_ADMIN_BOOTSTRAP_TOKEN=<random-32-bytes>on the webserver deployment. - Browse to the console — you'll land on the sign-in screen.
- Click Use bootstrap token and paste the token.
- The console drops you into the dashboard with a persistent yellow banner: "Break-glass admin — every action is recorded as a privileged operation."
While bootstrap is in use, every API call is audited as a break-glass event and the console UI surfaces the banner on every page. Treat it like sudo: short-lived, witnessed.
Provisioning the first real admin
The bootstrap token isn't a long-term identity — it's the path to one. Once your OIDC provider is wired:
- Have the human admin sign in once via OIDC. The first-login behavior is per-tenant; the default (
reject) means they'll land on a "no access yet" screen but a row appears inadmin_userswith their OIDC subject. - As the bootstrap admin, open Access → Users, find the newly-created row, and click Assign role → pick
global_admin→ scope*. - The admin signs out and back in. They now have full console access via their own identity.
- Once at least one human OIDC
global_adminexists, rotate the bootstrap token out of the deployment (or setMOOLELO_BOOTSTRAP_DISABLED=true). The persistent banner disappears and break-glass is no longer reachable without a config change.
The bootstrap account never auto-disables; removing your last escape hatch is a deliberate operator action.
Per-tenant operators
For deployments with more than one tenant, the typical pattern is:
- One or two
global_adminoperators (platform team). - One
tenant_adminper tenant, scoped to that tenant only. - Per-functional-role admins (
connector_admin,user_admin,billing_admin) layered on as the team grows.
A tenant_admin can do everything inside their tenant — wire connectors, manage identity sources, see audit rows, run the search preview — but the platform pages (Tenants, Regions, License) stay hidden. They can also delegate further by binding other admins as tenant_admin or any per-tenant role within the same tenant; they cannot grant a binding outside their tenant.
API surface
Everything the console UI does goes through /api/console/*. The endpoints are documented inline in the binary and gated by the same RBAC middleware the UI consumes. Highlights:
| Endpoint | Permission required | Notes |
|---|---|---|
GET /api/console/me | (none — bootstrap allowed) | Returns the caller's capability set. The UI reads this on every page load to drive nav visibility. |
GET /api/console/roles | (none) | The 7-role catalog. |
GET /api/console/role-bindings | roles:read | Every binding visible to the caller. |
POST /api/console/role-bindings | roles:assign | Bind { admin_id, role, scope }. |
DELETE /api/console/role-bindings/{id} | roles:manage | Revoke. |
GET /api/console/identity/people | identity:read | Paginate the ingested-person population (OpenFGA-sourced). |
GET /api/console/identity/people/{canonical} | identity:read | Per-person attributes + alias rows. |
Direct API use is supported but not the recommended operator path — the console UI exists so that operators don't need to remember endpoint shapes.
Where to go next
- Console RBAC for the role + permission catalog.
- Identity catalog for how the Ingest → Identity page is populated.
- Access control for how OpenFGA filters search results.
- Subject erasure for the GDPR Article 17 workflow exposed under Identity → Subject erasure.

