v0.0.54 — Role rename + Authorization Matrix
Released: 2026-05-06. Twelve commits; the headline is the RBAC vocabulary cleanup plus the new Authorization Matrix page.
Role rename — generic Dataiku vocabulary
User-level roles get neutral, vertical-agnostic names:
| Before | After |
|---|---|
management | designer |
cs_staff | analyst |
admin, viewer | unchanged |
The schema column is unchanged — only the string values are rewritten. Backward-compat aliases stay in seat_types.LEGACY_ROLE_TO_SEAT, project_access, email service labels, and the new roleLabels.ts helper so in-flight upgrade sessions don't flicker.
Two idempotent migrations land:
rename_roles_to_generic.sql—UPDATE … WHERE role IN (...)with anIF EXISTSshort-circuit so reruns are a single probe.seed_role_aligned_groups.sql— seeds four role-aligned system groups (Org Admins,Designers,Analysts,Viewers) per org with their default permissions, on top of the pre-existingAll Members/Org Adminspair.
Authorization Matrix UI
New page at /authorization-matrix (admin-only). Sticky-header pivot table of groups × permission strings; columns are color-coded by resource family (org / project / dashboard / dataset / feature). Org-wide grants show as a filled dot; target-scoped grants show a count badge.
Org admins can click a cell to grant or revoke the org-wide permission inline (optimistic update for revoke, refetch-after-write for grant). System admin groups + the org.admin column refuse revoke — every org always has at least one group holding org.admin as a recovery escape hatch.
A new + Add permission panel above the table accepts a free-text <resource>.<action> string (validated lowercase + underscores) plus a target group, so introducing a brand-new permission no longer requires a roundtrip through Groups Management.
Backed by:
GET /api/groups/matrix— returns groups + permissions in one payload. Open to any authenticated org member.POST/DELETE /api/groups/{id}/permissions— existing mutation endpoints, still gated onorg.admin.
Stage 3 router migration
All 557 router callsites that gated on require_role(*roles) now go through services.permissions.require_permission() instead. require_role is retired in PaaS; only the SaaS vertical routers keep the legacy gate during their own migration.
Mapping rules used in the migration:
- Bare admin gates (
require_role("admin")) →require_permission("org.admin"). - Designer-or-admin tuples →
require_permission("project.edit"). - Broad-read tuples (
OVERVIEW_ROLES) →require_permission("project.view"). - All-authenticated reads →
Depends(get_current_user)(the explicit gate was effectively a no-op).
The legacy role == 'admin' shim in the resolver stays as a permanent per-request optimization — Administrators groups hold org.admin via the v0.0.54 seed; the shortcut just saves a DB roundtrip. Implicit-grant shims also map designer/analyst/viewer onto their seeded permissions so tenants where user_groups hasn't been backfilled yet still resolve correctly.
Nav fixes
Apps menu (top-right 9-dots) was routing org-level destinations like /webhooks, /backups, /oidc-providers, /saml-providers, /smtp through useProjectUrl() and 404ing inside a project. The renderItem helper now skips the project-prefix when the path matches ORG_PATHS; the v0.0.49+ org-only pages are now in that list. Five regression-test surfaces (WaffleMenu, IconTabs, MoreItems, OrgItems, CommandPalette) lock the paths against a real route.
See also
- Permissions reference — full permission-string catalog.
- Users & Groups — group + seat-type model.