Role visibility
The admin bar is a frontend toolbar, not a panel page. Whether it renders is decided per request by a single role check against a stored list, not by Filament's panel-access contract.
Visibility model
AdminBar::visible() runs on every public (non-panel) request:
- Resolve
auth()->user(). Guests get nothing. - Bail if the request is inside any panel path (
onPanelRequest()). - Require
hasRole()on the user — i.e. the Spatie permission trait. - Load
enabledRoles(): therolesarray from the firstadmin_bar_settingsrow, orconfig('admin-bar.default_roles')(super_admin,editor,author) when no row exists yet. - Return
$user->hasRole($roles)— true if the user holds any enabled role.
The enabled set is edited in the panel under Settings → Admin bar (AdminBarSettings). The page itself is gated to super_admin via canAccess(). Its ManageRoles Livewire table lists every Spatie Role with a CheckboxColumn that calls AdminBar::setRoleEnabled($role, $bool), persisting straight to admin_bar_settings.roles.
Per-role items
The plugin does not filter New/Edit items by role. newItems() and editUsing() are registered once on the plugin and resolve globally. Each newItems URL may be a closure, and editUsing is a closure returning ?string; a closure that returns null drops the item from the bar. Per-role differences (e.g. only super_admin sees New, editors see Edit only) are implemented by the host app inside those closures — typically with $user->hasRole(...) — not by the admin bar itself.
Distinct from panel access
FilamentUser::canAccessPanel() gates who may enter the panel. The admin bar is a public-site concern and uses the same Spatie roles, but its on/off set is independent: a role can be allowed into the panel yet have the bar hidden, and vice versa.
Guards
visible() reads auth()->user(), so the bar follows the panel/web guard session. A panel on a separate authGuard() is a separate user pool — users from that guard won't see the bar unless that guard's user model also satisfies the role check.
flowchart TD
A["Public request"] --> B{"auth()->user()?"}
B -->|null| Z["No bar"]
B -->|user| C{"On panel path?"}
C -->|yes| Z
C -->|no| D{"hasRole()?"}
D -->|no| Z
D -->|yes| E["enabledRoles from settings or config"]
E --> F{"user.hasRole enabledRoles?"}
F -->|no| Z
F -->|yes| G["Render bar: dashboard, New items, Edit, Howdy/logout"]
G --> H["Item closures may return null -> item hidden"]
See also