laravel-cloudflare-access maintained by jimbojsb
Description
Laravel authentication and authorization via Cloudflare Access
Author
Josh Butts
Last update
2026/05/01 20:10
(dev-master)
License
Downloads
127
Tags
Cloudflare Access for Laravel
Authentication via Cloudflare Access JWT validation for Laravel.
Requirements
- PHP 8.3+
- Laravel 11.0+ or 12.0+
Installation
composer require jimbojsb/cloudflare-access-laravel
Publish Configuration
php artisan vendor:publish --tag=cloudflare-access-config
Publish Migration (Optional)
php artisan vendor:publish --tag=cloudflare-access-migrations
php artisan migrate
The migration creates a users table with id, name, email, groups (nullable json), and timestamps.
Configuration
Add to your .env:
CLOUDFLARE_ACCESS_SUBDOMAIN=yourcompany
CLOUDFLARE_ACCESS_AUDIENCE=your-application-audience-tag
CLOUDFLARE_ACCESS_POPULATE_GROUPS=false
CLOUDFLARE_ACCESS_SUBDOMAIN: Your team domain subdomain (e.g., if your domain isyourcompany.cloudflareaccess.com, useyourcompany)CLOUDFLARE_ACCESS_AUDIENCE: The Application Audience (AUD) Tag from Cloudflare Zero Trust dashboardCLOUDFLARE_ACCESS_POPULATE_GROUPS: Set totrueto sync groups from Cloudflare Access JWT to the user model (default:false)
User Model
Your User model needs name, email, and groups columns. Update config/cloudflare-access.php if using a different model:
'user_model' => App\Models\User::class,
Ensure your model casts groups as an array:
protected $casts = [
'groups' => 'array',
];
Usage
Add Login Route
Register the login route in your routes/web.php:
use Jimbojsb\CloudflareAccess\Http\Controllers\LoginController;
Route::get('/login', [LoginController::class, 'login']);
Authentication Flow
- User visits your app behind Cloudflare Access
- Cloudflare Access sends a JWT in the
Cf-Access-Jwt-Assertionheader - The package validates the JWT against Cloudflare's public keys
- A user is created or updated with name, email, and groups from the JWT
- The user is logged into Laravel's session
Protecting Routes
Use Laravel's built-in auth middleware:
Route::middleware('auth')->group(function () {
Route::get('/dashboard', [DashboardController::class, 'index']);
});
Local Development
For local development without Cloudflare Access, create a user.json file in your project root:
{
"name": "Local Developer",
"email": "dev@example.com",
"groups": ["admin"]
}
This only works when APP_ENV is not production. Note that groups will only be populated if CLOUDFLARE_ACCESS_POPULATE_GROUPS is set to true.
For safety, you should add this file to your .gitinore.
Testing
composer test
License
MIT License. See LICENSE.