Skip to content

Roles & permissions

A permission catalog, two seeded roles, tenant-authored roles and permissions, and the difference between a Team and an IdP Group.

Industric's first identity model had two roles printed into the schema: admin and member. Fine for early tenants, useless for anyone with an audit obligation. The current model swaps the enum for a permission catalog, tenant-scoped roles that bundle permissions, and a split between IdP-sourced groups and tenant-authored teams.

The permission catalog

Every authorising decision in Industric is keyed by a string permission. The shipped catalog covers everything the built-in handlers gate. Most permissions follow a resource:verb shape; a few are namespace-wide read flags.

system catalog (excerpt)· text
1agents:read | invoke | write | admin See, attach to, edit, and ACL-manage agents
2deployments:read | write | delete Manage Industric Operator deployments + tokens
3audit:read | export Read and export the audit streams
4tools:read | write Cluster Tools catalogue
5policies:read | write Resource policies and bundles
6providers:read | write LLM provider gateways + credentials
7integrations:read | write Slack / Jira / Adaptive integrations
8oauth_apps:read | write OAuth Apps
9skills:read | write Skills catalogue
10users:read | invite | write Team members + invitations
11roles:read | write Roles + permission assignment
12idp:read | write Identity providers (SSO / SCIM)
13tenant:read | write Tenant settings

Permission keys are flat resource:verb strings. The full system list lives in the backend as model.SystemPermissions; every key the built-in handlers gate is in it, and adding a key is a code change, so the catalog can't drift from what's enforced.

The two seeded roles

The Roles page listing the built-in Admin and Member roles above three custom roles, each with its permission count
Identity → Roles. The two built-in roles plus tenant-authored ones, with their permission counts.

Admin and Member are protected system roles: they cannot be edited or deleted. Create and assign a custom role when you need different permissions.

  • Admin. Every permission in the system catalog. The migration rebuilds this role from SystemPermissions on each release, so it always covers new keys. Bound to the first signup on a tenant.
  • Member. Read and invoke agents and apps; read, write, and invoke workflows. Access to individual resources still requires ownership or a matching grant.

Authoring a role

Roles are tenant-scoped records: a name, a description, and a set of permissions. Author them in Identity → Roles. Two patterns we see a lot:

The New role dialog with a name, a description and a filterable permission list grouped by resource, with four permissions selected
New role. Name and describe the role, then tick permissions; the Form and YAML tabs edit the same record.
  • AuditReader. audit:read, agents:read, deployments:read. For SOC2 reviewers who need to inspect history without touching configuration.
  • OnCallEngineer. agents:read, agents:invoke, tools:read. Enough to attach to an agent and re-run things, with no write access.
One role per user
A user holds exactly one role, and that role is their entire permission set. Assigning a new role replaces the old one. Authority is resolved fresh from RBAC on every request, so a role change takes effect immediately, not at token expiry.

Custom permissions

Tenants can author permissions that aren't in our catalog: acme:invoice:approve, pii:read, treasury:wire-out. These don't gate Industric's built-in handlers (those check the fixed system catalog); your own code consumes them:

  • Inside an agent's runtime, gate a tool or action on a custom permission string.
  • In your own integration, check a custom permission before submitting an action to a resource policy evaluation hook.

The role-attach surface is identical: your role gets a checkbox next to treasury:wire-out the same way it does next to agents:invoke.

Teams and groups

The Teams page listing five custom teams with All, Custom and Directory filter tabs
Identity → Teams. Tenant-authored teams carry a Custom badge; directory-synced groups are counted under the Directory tab.

Teams and groups organise people, not permissions. They never grant roles: a user's role is assigned directly, one per user, from the Members page. What teams and groups do is scope access: they appear as principals on per-agent access lists and per-skill grants, so "everyone on platform-eng can see this agent" is one entry instead of ten.

  • Teams are tenant-authored. The dashboard is the source of truth for membership. Good for ad-hoc projects, on-call rotations, and tenants with no IdP at all.
  • Groups are IdP-sourced. SCIM pushes or a periodic LDAP/AD pull populate them. The dashboard treats them as read-only: only the IdP can mutate membership.
One side of the wire owns membership
For IdP-sourced Groups, don't edit membership in the Industric dashboard; there's no edit affordance for a reason. Membership lives in your IdP. For tenant-side overrides, model them as Teams.