| name | laravel-security |
| description | Harden Laravel apps with Policies for model authorization, Gate-based RBAC, validated mass assignment, and CSRF protection. Use when creating authorization policies, securing env config access, or preventing mass assignment vulnerabilities. |
| metadata | {"triggers":{"files":["app/Policies/**/*.php","config/*.php"],"keywords":["policy","gate","authorize","env","config"]}} |
Laravel Security
Priority: P0 (CRITICAL)
Workflow: Secure Resource
- Generate policy —
php artisan make:policy PostPolicy --model=Post.
- Implement policy methods — Return
bool for view, update, delete actions.
- Authorize in controller — Call
$this->authorize('update', $post).
- Add Gate bypass — Define
Gate::before() for admin users in AuthServiceProvider.
- Validate inputs — Use Form Request with
$request->validated() for Model::create().
Policy Example
See implementation examples for Policy class with controller authorization.
Implementation Guidelines
Authorization & RBAC
- Policies: Always use
php artisan make:policy PostPolicy --model=Post for model-level authorization.
- Checkers: Implement
update(User $user, Post $post): bool and call $this->authorize('update', $post) in controllers.
- Gates: Use
Gate::define('admin', fn(User $user) => ...) for global permissions. Check with Gate::allows('admin') or Blade @can('admin'). prefer Policies for model-bound checks; use Gates for global permissions.
- Admin Bypass: Define
Gate::before(fn($u) => $u->isAdmin() ? true : null) in AuthServiceProvider.
Configuration & Environment
- Environment: Only call env() inside config/*.php files. Access via
config('app.key') in your application code. Never env() in controllers; use config() instead.
- Caching: Run
php artisan config:cache to validate that env() isn't used where it shouldn't .
Data & Input Security
- Mass Assignment: Use Form Request with rules() and call $request->validated() for Model::create(). Define $fillable on model; never pass $request->all() to create().
- CSRF: Ensure @csrf directive in all Blade
<form> tags. active on web routes by default; use ->except(['/webhook']) only for trusted third-party callbacks.
- Role-Based Access: Use Policies with role checks in policy methods; define
Gate::before for admin bypass; or use spatie/laravel-permission; never inline $user->role === 'admin'.
Anti-Patterns
- No
env() outside config files: Access via config() helper.
- No custom auth logic: Use Laravel's built-in auth system.
- No unvalidated mass assignment: Always call
validated().
- No auth logic in Blade: Pass permissions as data from controller.
References
Configuration boundary
- Read environment values only in configuration files; application code uses
config('app.key'), never env() in controllers.
Canonical response anchors
When this skill applies, preserve the following domain terminology or equivalent concrete examples in the answer when relevant:
-
configuration files,only in configuration,Do not call `env()
-
@can('admin')
-
never env() in controllers,use config() in controllers,not in controllers
-
web routes,web middleware,CSRF middleware
-
Additional task-grounded exact anchors: config('app.key')