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.
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:
- View access, can this user see the table at all?
- Edit access, for users who can view, which columns can they edit?
- 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 ifallowed_rolesis 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:
phoneandemail, editable by any viewerstatusandnotes, editable only by users with theorder-managercapability
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:
- The plugin’s
gravityforms_create_entriescapability (controls whether the user can create GF entries at all) - The table’s
add_permissionsshortcode 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:
- Is
allowed_rolesconfigured? → Check role membership. Deny if not. - Is
filter_by_user="true"? → Filter rows to those owned by current user. - For each cell render: does this user have edit access to this column? → Mark editable or read-only.
- 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.