Users and Groups (RBAC Model)
Honeyframe uses a two-axis Role-Based Access Control (RBAC) model that decouples licensing from security permissions.
The Two-Axis Model
Security in Honeyframe is structured around two independent axes:
- Seat Types (Licensing Axis): Defines the user's licensing tier and default capabilities.
- Group Permissions (Security Axis): Defines specific access to resources (projects, datasets, dashboards) via group membership.
Seat Types
Seat types are assigned at the user level and represent their primary role within the platform. They drive implicit organization-wide permissions.
- Admin: Platform administrators with full access to organization settings, users, and all resources.
- Builder: Users who can create and manage project assets, flows, and metadata.
- Analyst: Users focused on data exploration and dashboarding. Can view projects and interact with data.
- Viewer: Read-only users who consume dashboards and project overviews.
The seat type is stored on the user record. Each seat type carries a fixed set of implicit grants, described in the Permissions Reference.
Groups and Permissions
Permissions are never granted directly to users; instead, they are granted to groups. Users inherit permissions by being members of one or more groups.
Groups
Groups belong to an organization. A group can be:
- Local: Managed entirely within the Honeyframe platform.
- LDAP-Mapped: Carries an LDAP DN, so its membership is synchronized from a directory server — see LDAP Configuration.
Permissions
A permission grant gives a group a specific capability. It consists of:
- Permission Type: A dot-separated string defining the resource and action (e.g.,
project.edit,dashboard.view). - Target ID: (Optional) Scopes the permission to a specific object (e.g., a specific
dashboard_id). Without a Target ID, the permission is granted organization-wide.
Resolution Logic
Every permission check — in the API and in the UI — goes through one resolver, with this precedence:
- Superadmin: Bypasses all checks.
- Admin Seat: Bypasses all checks for the organization.
- Implicit Grants: Grants based on the user's seat type (e.g., Builders implicitly get
project.edit). - Group Grants: Explicit permission grants on the groups the user belongs to.
Superadmin (global privilege)
is_superadmin is a global flag — it bypasses every org-scoped check, across all organizations — and is distinct from the org-scoped admin role/seat. Because granting it is a full privilege escalation, it is governed by stricter rules than ordinary role changes (v0.0.89):
- SSO sign-up never grants it. All four SSO auto-create paths (Google, Microsoft, generic OIDC, SAML) insert new users with
is_superadmin = FALSE; the seededrole(defaultviewer) is the only privilege a first-time SSO sign-in receives. (A prior defect auto-granted superadmin on first SSO sign-in; this was fixed and is now guarded by a static test that assertsis_superadmin = FALSEacross every SSO insert path.) - Only a superadmin can grant it.
PATCH /api/users/{id}accepts anis_superadminfield, but writes to it are gated behindcaller.is_superadmin— holdingorg.adminis not sufficient. In the UI the Make SA / Revoke SA action is visible only to superadmins and hidden on the caller's own row. - Self-revoke is blocked. A superadmin cannot remove their own
is_superadmin, mirroring the self-deactivate guard so the last superadmin can't lock the platform out.
Sign-in aliases
A user can hold multiple login emails. Each alias is a row in honeyframe.user_email_aliases (unique on LOWER(email), FK → users ON DELETE CASCADE), and every auth path — password, Google, Microsoft, generic OIDC, and SAML — resolves the login against the alias table as well as the primary email. This lets someone who changed employers, or who signs in with both a work and an SSO identity, land on the same user record instead of a duplicate.
Aliases are managed by an admin:
| Endpoint | Purpose |
|---|---|
GET /api/users/{id}/emails | List a user's login emails. |
POST /api/users/{id}/emails | Add an alias. |
DELETE /api/users/{id}/emails/{alias_id} | Remove an alias. |
Permissions and group memberships are unaffected — an alias only widens how a user signs in, never what they can do. For unattended access, see Personal Access Tokens, which are governable per-token by an org admin.
Permissions in the UI
The UI hides or disables actions the signed-in user can't perform and blocks whole pages they can't open. It reads the user's flat permission list from GET /api/groups/me/permissions; custom integrations can call the same endpoint. The server re-checks every request, so the UI gates are a convenience, not the enforcement point.