FabrikFabrik
FabrikAdministration

Groups and quotas

Groups, Django permissions, role templates, and GroupQuota numeric limits and feature toggles — how Fabrik decides what a user is allowed to do and how much of it.

Groups do two jobs in Fabrik: they bundle Django permissions for easy assignment, and they carry a GroupQuota that caps resource usage and toggles feature access. Most deployments configure three or four groups and never touch user-level permissions.

The group list

Settings → Administration → Groups shows every group with member count, permission count, and whether a quota is configured. Search filters by name.

Clicking a group opens three tabs:

  • Members — users currently in the group, with add/remove controls.
  • Permissions — Django permissions granted, grouped by app.
  • Quota — numeric limits and feature toggles.

Role templates

Creating a group from scratch means picking permissions out of a list of hundreds. Templates skip that — each template is a pre-curated permission set plus a sensible quota preset.

Four templates ship built-in:

TemplateIntentHighlights
AdministratorFull accessAll permissions, all features on, concurrent AWX jobs capped at 10
OperatorRun queries and automationsCreate/edit queries and scheduled tasks, use AWX, 100 saved queries, 50 AWX requests/day
EditorBuild and share queriesQueries and categories only — no AWX, 50 saved queries, 10 scheduled tasks
ViewerRead-onlyview_* on everything, execute queries but not create, 10 saved queries, no AWX

Templates are a starting point, not a constraint. After creating a group from a template, edit the permissions and quota freely. The template just saves you the up-front work of picking defaults.

Templates also preset the quota, not just the permissions. A Viewer group gets max_export_rows=5000 out of the box; an Operator gets 50000. Check the quota tab after creating from a template to see what was applied.

The Admin group

The Admin group is special:

  • Bootstrapped on first migration — can't be deleted, can't be renamed.
  • Members bypass every per-model permission check (same as a superuser).
  • Members pass IsAdminOrSuperuser, which gates all admin endpoints.

Members of Admin still need to exist as active users and still get audited like everyone else. The bypass is for permissions, not identity or accountability.

Admin membership is the closest thing Fabrik has to "root." Grant it sparingly — two or three people in a small team, a handful in a large one. Everyone else should be in Operator, Editor, or Viewer with their capabilities tuned by group quota.

Cloning a group

Clone copies all permissions from an existing group under a new name. Useful when you want a variation — "Operator-APAC" with the same permissions as Operator but a different quota, or a "Editor-External" with reduced connection limits.

The clone copies permissions only. The quota does not copy — the new group starts with no quota, which means users in it fall back to global defaults. If you want the quota copied too, set it manually after cloning.

Django permissions

Under the hood, permissions are the usual Django add_/change_/delete_/view_ tuples per model. Fabrik uses FabrikModelPermissions instead of the stock DjangoModelPermissions, with two differences:

  1. GET requires view_ permission (stock DRF skips permission checks for safe methods). This is the right default for a product handling sensitive infrastructure data.
  2. Superusers and Admin group members bypass all checks, so the permission system doesn't get in the way of admin work.

When a regular user is denied, the response includes a descriptive message: "You do not have permission to edit APIC connections. Contact your administrator to request access." — useful context so the user knows what to ask for.

Certain Django apps are excluded from the permission picker entirely (admin, contenttypes, sessions, authtoken, token_blacklist) — they're framework machinery, not user-facing features.

Group quotas

A GroupQuota row attaches to a group and controls numeric limits and feature toggles.

Numeric limits

The rule: 0 means unlimited. Any positive integer is the hard cap.

FieldWhat it capsDefault in DB
max_saved_queriesSaved queries this user owns0 (unlimited)
max_scheduled_tasksScheduled tasks this user owns0
max_apic_connectionsAPIC connections this user owns0
max_awx_requests_dailyAutomation requests per day0
max_awx_concurrentAutomation jobs running at once5
max_query_resultsRows returned from a single query execution0
max_export_rowsRows in a CSV/JSON export50,000
query_execution_dailyBackground query executions per day0
ai_analysis_dailyAI builder calls per day0

The limits apply at call time: creating a saved query, starting an execution, requesting an export. If you're over the limit, the action is rejected with a message like "You have reached your limit of 50 saved queries."

Daily limits reset at midnight UTC and count rows created within the last 24 hours — the check is COUNT(*) WHERE created_at >= today_start, not a moving window.

Feature toggles

Booleans that turn whole product areas on or off for a group:

ToggleGates
can_create_queriesQuery Builder save button
can_execute_queriesRunning any query (including saved ones)
can_create_scheduledScheduled task creation
can_use_awxAWX Automation section entirely
can_use_time_machineTime Machine capture and compare
can_export_dataCSV/JSON export endpoints
can_share_resourcesSharing queries/tasks with other users
can_use_ai_builderAI-assisted query building

Toggles stop before the numeric check. If can_use_awx=false, the user doesn't even hit max_awx_requests_daily — the AWX section is gone for them entirely.

Multi-group quota resolution

A user can belong to multiple groups. When quotas from different groups overlap, Fabrik resolves them with a single rule: most permissive wins.

  • Numeric fields: if any group has 0 (unlimited), the effective value is 0. Otherwise, the highest value across groups wins.
  • Boolean toggles: if any group has true, the effective value is true.

Examples:

A user in Operator only:

  • max_saved_queries=100 → capped at 100.
  • can_use_awx=true → AWX allowed.
  • max_awx_concurrent=5 → 5 concurrent jobs.

A user in Operator (100 queries, AWX on) and Viewer (10 queries, AWX off):

  • max_saved_queriesmax(100, 10) = 100.
  • can_use_awxtrue OR false = true.

The Viewer membership adds nothing — Operator is strictly more permissive. This is fine; it doesn't hurt to be in both.

A user in Admin (everything unlimited) and Operator (100 queries):

  • max_saved_queries0 (unlimited) beats 100 = 0 (unlimited).

Unlimited wins over any finite number. This is why admins don't need to care about the quotas on other groups they're also in.

No group quota → global defaults

If a user is in no groups — or in groups that have no GroupQuota row — Fabrik falls back to DEFAULT_QUOTAS from Django settings. The defaults are mostly 0 (unlimited) for resources with a max_export_rows=50000 backstop, and all feature toggles true.

The practical read: groups with no quota configured are effectively unlimited. If you want limits, create the quota explicitly.

Superusers are always unlimited

Superusers bypass quota checks entirely. get_effective_quota returns all-unlimited for them regardless of group membership. This is intentional — the bootstrap admin should never lock themselves out of the system by accidentally landing in a restricted group.

Editing a quota

Groups → pick a group → Quota tab. The form has two sections:

  • Numeric limits with a 0 = unlimited hint under each field.
  • Feature toggles as a grid of switches.

Changes apply immediately to all users in the group. There is no "draft" or "preview" — if you set max_saved_queries=10 on a group whose users already have 50 queries each, they keep their existing queries but can't create new ones until they delete some.

GroupQuota is a OneToOneField to Group, so each group has at most one quota. If you see a group with no Quota tab contents, no quota is configured — click Save on the empty form to create one.

Audit trail

Group-related actions are logged under the group_permission category:

  • group_created, group_updated, group_deleted, group_cloned
  • permissions_added, permissions_removed (with the permission list in metadata)
  • quota_updated

Quota changes don't carry a before/after diff in the current audit entry — they log that a change happened and who made it. Compare against the live settings if you need to see what changed; the audit trail is the "who and when," the current state is the "what."

Common patterns

  • Three-tier setup. Admin, Operator, Viewer. Most deployments start here. Use the three built-in templates, tune the quotas, done.
  • Per-team groups. Operator-NetEng, Operator-SecOps — same permissions, different quotas. Clone the base Operator group, rename, adjust the quota.
  • Contractor group. Editor permissions + can_use_awx=false + tight daily limits. Keeps third-party access bounded.
  • Service accounts. Dedicated groups for non-human users (scheduled imports, monitoring integrations). Quotas typically high; feature toggles restricted to what the service actually uses.

That's access control. LDAP, covered next, plugs your corporate directory into the same group and permission system.