Skip to content
Gravity Tables
permissions

How to set up role-based permissions for Gravity Tables

Restrict who can view, edit, and export a Gravity Tables view based on WordPress roles and capabilities. Server-side enforced, with edge-case handling and recipes.

· 5 min read · By Fahd Murtaza

If your table touches production data, customer orders, employee profiles, patient intake, financial records, role-based permissions aren’t a nice-to-have. They’re the gate that decides what each user can do. This guide covers the full permission surface in Gravity Tables.

The three permission layers#

Every Gravity Tables view enforces three layers, in order:

  1. View access, can this user see the table at all?
  2. Edit access, for users who can view, which columns can they edit?
  3. Action access, can they bulk-edit, export, or add entries?

Each is independently configurable. Each is enforced server-side. Each falls back to “deny” if not explicitly granted.

Layer 1: View access via allowed_roles#

[gravity_table id="42" allowed_roles="customer,subscriber"]

A logged-in user with the customer or subscriber role can view the table. Anyone else gets a polite access-denied message.

Tokens:

  • A role slug: customer, subscriber, editor, administrator
  • Multiple roles, comma-separated: customer,subscriber,editor
  • The wildcard *: any logged-in user
  • Empty string "": anyone, including guests (default if allowed_roles is omitted)

Note on admins: the administrator role is not auto-included unless explicitly listed. This is deliberate, sometimes you want a customer-facing dashboard that admins shouldn’t see by default. If you want admins to always see it:

[gravity_table id="42" allowed_roles="customer,administrator"]

Layer 2: Edit access via allow_edit + edit_permissions#

[gravity_table id="42" allow_edit="phone,email"]

Allows any user who can view the table to edit those two columns. Often too broad for production.

For finer control, pair with edit_permissions:

[gravity_table id="42"
  allow_edit="phone,email,status,notes"
  edit_permissions="status:order-manager,notes:order-manager"]

Now:

  • phone and email, editable by any viewer
  • status and notes, editable only by users with the order-manager capability

The edit_permissions value is a comma-separated list of column:capability pairs. Capabilities, not roles. This is intentional, capabilities are the right primitive for “can do X” gates. Use built-in capabilities (manage_options, edit_others_posts) or custom ones from your role-management plugin.

Layer 3: Action access for exports and bulk operations#

Export permissions#

[gravity_table id="42"
  export="csv,pdf"
  export_permissions="excel:manager"]

CSV and PDF download buttons appear for everyone who can view. Excel button appears only for users with the manager capability.

To gate the entire export toolbar:

[gravity_table id="42"
  export="csv,excel,pdf"
  export_global_permission="manage_options"]

Now the export toolbar is invisible (and AJAX-blocked) for anyone without manage_options.

Bulk operation permissions#

[gravity_table id="42"
  bulk="approve,delete,export"
  bulk_permissions="delete:manage_options"]

Approve and Export bulk actions are available to all viewers. Delete is gated to admins.

Add Entry permissions#

The “Add New Entry” button respects two permissions independently:

  1. The plugin’s gravityforms_create_entries capability (controls whether the user can create GF entries at all)
  2. The table’s add_permissions shortcode parameter (gates this specific table’s button)
[gravity_table id="42" allow_add="true" add_permissions="customer,manager"]

Only users with one of those capabilities see the button.

The full layered example#

[gravity_table id="customer-orders"
  allowed_roles="customer,manager,administrator"
  filter_by_user="true"
  allow_edit="shipping_address,phone,delivery_notes"
  edit_permissions="status:manager,priority:manager"
  bulk="export"
  bulk_permissions="export:any"
  export="csv,pdf"
  export_permissions="csv:any,pdf:manager"
  audit_log="true"]

What this does, viewer by viewer:

  • Guest, sees access-denied (not in allowed_roles)
  • Customer, sees only their own orders (per-user filter). Can edit shipping address, phone, delivery notes. Cannot edit status or priority. Can export their own data as CSV. No PDF export. No bulk delete.
  • Manager, sees all orders. Can edit everything customers can, plus status and priority. Can export CSV or PDF. Can bulk-export.
  • Administrator, same as Manager (admins get whatever roles they’re listed in the config, they don’t auto-elevate).

Every action is logged to the audit table. Edits show who, when, what changed.

That’s a customer portal that handles real production load. One shortcode.

Permission inheritance and overrides#

Permissions are checked in this order:

  1. Is allowed_roles configured? → Check role membership. Deny if not.
  2. Is filter_by_user="true"? → Filter rows to those owned by current user.
  3. For each cell render: does this user have edit access to this column? → Mark editable or read-only.
  4. For each action (export, bulk, add): does this user have action access? → Show or hide button.

Steps 1 and 2 happen at the database query layer, unauthorized users never receive the data. Steps 3 and 4 are UI-level (button rendering) AND AJAX-handler-level (server enforcement). The AJAX side is the actual gate; the UI side is just for clean UX.

Common patterns#

Public read-only with admin edit#

[gravity_table id="..." allowed_roles="*" allow_edit="" edit_permissions="..." admin_can_edit_all="true"]

Anyone logged in can view. Nobody can edit by default. Admins (capability: manage_options) can edit any column.

Internal-only with team-specific edits#

[gravity_table id="..." allowed_roles="staff" allow_edit="status,priority" edit_permissions="priority:senior-staff"]

Only staff role sees the table. All staff can edit status. Only senior-staff capability can edit priority.

Customer support agent dashboard#

[gravity_table id="..." allowed_roles="support,manager" allow_user_switch="manage_options" allow_edit="status,internal_notes" audit_log="true"]

Support sees all customer entries. Admins can switch context (allow_user_switch lets them filter as if they were a specific customer). Edits are audited.

Edge cases#

When allowed_roles excludes the table’s creator#

If you build a table while logged in as editor and configure allowed_roles="customer", then visit the page as editor, you’ll be denied. This catches admins off guard.

Fix: include administrator (or your editing role) in allowed_roles during development. Remove before production launch.

Capability check vs role membership#

current_user_can('manage_options') returns true for anyone with that capability, not just admins. If you’ve installed a role plugin that grants manage_options to the editor role, those users will now have edit access. Audit your roles before relying on capability gates.

Multisite#

On a multisite WordPress install, capability checks default to the current blog’s capabilities. A user who’s administrator on Blog A but subscriber on Blog B will hit the subscriber rules on Blog B’s tables. This is correct behaviour, flag it during multisite setup.