Your app, your rules

Most applications need some form of access control, and implementing it well is deceptively complex. Who can see what? Who can edit? What about public visitors? Graymatter ships with a complete role-based permission system and a visual navigation manager that puts you in control of every layer of access, without touching code after initial setup.
The permission model is straightforward. Every content type in your application automatically generates four permissions: view, create, edit, and delete. These permissions are grouped into roles, and roles are assigned to users. The default installation seeds an admin role with full access and a basic user role, but you can create as many roles as you need. A content moderator who can edit but not delete. A contributor who can create but not manage users. A department head who can do everything within their section. Define the role, check the boxes, and the system enforces it everywhere.
Roles can also control who assigns them. This creates an assignment hierarchy that prevents privilege escalation. An admin can assign any role, but a team lead might only be able to assign the basic user role. This is particularly useful in organizations where account management is distributed across multiple people with different levels of trust.
The navigation manager is where access control becomes visual. Admins can configure the application's navigation at /settings/nav, adding, removing, and reordering menu items through a simple interface. Each item can be set as visible to specific roles, so users only see the parts of the application that are relevant to them.
One of the more powerful features is the built-in guest role. Checking "guest" on a navigation item makes its corresponding route and content accessible to unauthenticated visitors. This means you can selectively open parts of your application to the public - a portfolio, a knowledge base, a product catalog - without any code changes. Toggle it on from the nav manager, and the system handles route access and visibility automatically. Toggle it off, and that section is private again.
The whole system is trait-based, so extending it to your own models takes minimal effort. Add the Manageable trait to a new model, run a single artisan command, and its permissions are generated and available in the role editor. Built-in authorization helpers (canView() and canManage()) work immediately. No middleware to write, no policy classes to create, no gate definitions to register. The pattern is consistent across every model in the application, which means the access control for your custom content types works exactly the same way.