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 and enabled flag as Fontana Files configuration, projected roleId
Authorization Admin → Roles (permission sets), Admin → Users (enable/disable only) Roles as Fontana Files configuration, permission checks on every mutation

Zitadel project role keys must match Fontana role names exactly (for example admin, editor, viewer, member). If the token carries a role name with no matching Fontana 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, Knowledge Graph, files, and evals; read skills; AI model selection; no user admin or platform deploy
viewer Read-only operators and reviewers Read workflows, agents, skills, Knowledge Graph, files, and evals; edit own profile
member Minimal access 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 The agent catalog; write changes MCP connections, Agent Interop, and chat channels
skills read The skill catalog and AI → Skills
knowledge-graph read, write, delete Knowledge Graph documents and namespaces
evals read, write, run, delete Evaluation tests
files read, write, delete, admin File browser and uploads; admin opens every namespace, including the costs record, and can run its workflows; it also manages every asset in the asset library
ai page, view_usage, manage_global_spending_caps, … Cost center, spending caps, 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 → Email, Admin → Lineage, API keys
profile read, write, allow_email_change User profile and preferences
audit_logs_own read Activity entries whose chain the caller started
audit_logs_team read Every Activity entry; edit shared Activity views (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 (a default seed role can be edited too, but the next workspace seed restores its default permissions)
  • Delete custom roles that are no longer needed

Roles are kept as Fontana Files configuration: Admin → Roles writes the role list, and Flow applies the change within moments. A role’s name is its key, so you change a role’s permissions, not its name.

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

teams:admin lets you create teams, rename teams, and manage team membership (viewer or editor on the team) in Admin → Teams. Teams and their members are kept as Fontana Files configuration, like roles.

Workspace workflows follow the Fontana Files grants on that workspace, plus global workflows:*. A grant names a person or a team, so team membership can give you access to a workspace. A team grant names the team itself, not its display name, so renaming a team keeps its grants. If you can read the workspace, you see its run data. If you can edit it (including files:admin), you can Run any workflow in it.

Agent and skill packages follow the same grants. An editor grant on a namespace lets you edit the packages in it, including an agent’s schedules.json, and no role permission is checked for those writes. See Agents and Skills.

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

Route Permission required
/projects, /workflow workflows:read
/agents, /tools agents:read
/usage, /threads ai:page
Cost center (/ai?view=usage) ai:page (your own spend), ai:view_usage (the whole workspace)
/admin/users, /admin/roles users:read
/admin/teams teams:admin
/admin/assets files:admin
/admin/email, /admin/openlineage platform:read
/audit-logs/activity (own) audit_logs_own:read

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

People, teams, and roles are kept as Fontana Files configuration. Every grant, personal namespace, and personal key names a person by the Fontana id kept there, and a team by the team itself. After a workspace is restored from its Fontana Files and its secrets (see Backup and restore), each person signs in to their own namespaces, grants, conversations, personal access tokens, and API keys. If the identity provider was replaced and a person’s sign-in id changed, Fontana matches them to their existing account only by a verified email address.

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. Role, user, and team membership changes also appear in the Activity log.