Skip to content

Roles and RBAC

Fontana uses role-based access control (RBAC) in two layers:

  1. Zitadel - who the user is, MFA, and which role name they hold (project role grant)
  2. Flow / Convex - what that role can do via a static permission catalog and dynamic role documents

You assign roles in Zitadel (or via SCIM when enabled). Admins define permission sets in Admin → Roles. There are no per-user permission overrides in the app: effective permissions always come from the user’s assigned role.

Zitadel project role (e.g. editor)
→ JWT claim on login
→ Convex storeUser → users.roleId
→ roles.permissions → effective permission list
→ Flow sidebar, pages, and mutations
Layer You configure Fontana stores
Identity Zitadel (SSO, MFA, project role grants, SCIM when enabled) User profile, enabled flag, projected roleId
Authorization Admin → Roles (permission sets), Admin → Users (enable/disable only) Convex roles table, permission checks on every mutation

Zitadel project role keys must match Convex role names exactly (for example admin, editor, viewer, member). If the token carries a role name with no matching Convex role, the user signs in but receives no permissions until an admin creates the role or fixes the Zitadel grant.

Four roles are upserted on every workspace seed. Custom roles you create in Admin are never modified by seed.

Role Typical use Permission summary
admin Platform and security administrators Wildcard * (all permissions)
editor Builders and analysts who create workflows, agents, and knowledge Full read/write on workflows, agents, skills, Knowledge Graph, files, and evals; AI model selection; no user admin or platform deploy
viewer Read-only operators and reviewers Read workflows, agents, skills, Knowledge Graph, files, evals, and explore; edit own profile
member Minimal access Explore, read workflows, edit own profile

Grant these roles in Zitadel as project roles on the Flow application. Provisioning seeds a break-glass admin@fontana.local account with the admin project role on fresh installs.

Permissions use resource:action ids (OAuth2-compatible), defined in the static catalog shipped with Fontana:

Resource Example actions What it gates
workflows read, write, delete Canvas, workflow lists, run and edit
agents read, write, delete AI agent definitions and Admin agent surfaces
skills read, write, delete Skill packages
knowledge-graph read, write, delete Knowledge Graph documents and namespaces
evals read, write, run, delete Evaluation tests
files read, write, delete File browser and uploads
ai page, select_model, add_model, … Usage page, model approval, defaults
users read, write, create, delete, enable Admin → Users and user management
teams admin Admin → Teams (create, rename, membership)
platform read, write Admin → Deployment, API keys, releases
profile read, write, allow_email_change User profile and preferences
explore read Community template explore
audit_logs_own read LLM debug for the caller’s chat threads
audit_logs_team read LLM debug for any user’s threads (high trust)

Wildcards are supported when editing roles in Admin:

  • * - all permissions (used by default admin)
  • workflows.* - all actions on one resource area

Admin → Roles lets you:

  • Create custom roles with any combination of catalog permissions or wildcards
  • Edit permission sets for custom roles (default seed roles can be edited like any other Convex role document)
  • Delete custom roles that are no longer needed

After you create a custom role in Flow, grant the matching project role name in Zitadel so users receive it on login.

Teams add a second dimension for team-bound workflows:

  • teams:admin - create teams, rename teams, and manage team membership (viewer or editor on the team)
  • Team-bound workflows require both global workflows:* permissions and team membership with the right team role

Personal workflows (teamId unset) follow global RBAC only. See Admin → Teams and Team Workflows in the sidebar.

Flow hides sidebar entries and blocks routes when the signed-in user lacks the required permission. Examples:

Route Permission required
/workflows, /workflow workflows:read
/agents, /tools agents:read
/knowledge-graph knowledge-graph:read
/usage, /threads ai:page
/admin/users, /admin/roles users:read
/admin/teams teams:admin
/admin/deployment platform:read
/audit-logs/chat (own) audit_logs_own:read

Backend mutations call the same permission checks; missing permission fails closed with an error.

When an admin disables a user in Admin → Users, effective permissions become empty immediately regardless of role. Re-enable restores permissions from the assigned role.

Privileged RBAC changes (role edits, user enable/disable, team membership) should appear in admin audit logs and, when producers are enabled, the immutable security audit trail. See Immutable audit trail.