ptondereau / biscuit-laravel
Laravel integration for Biscuit authorization tokens
Requires
- php: >=8.2
- ext-biscuit_php: >=0.5
- illuminate/auth: ^12.0 || ^13.0
- illuminate/database: ^12.0 || ^13.0
- illuminate/filesystem: ^12.0 || ^13.0
- illuminate/http: ^12.0 || ^13.0
- illuminate/support: ^12.0 || ^13.0
- symfony/polyfill-php83: ^1.31
Requires (Dev)
- carthage-software/mago: ^1.55
- larastan/larastan: ^3.13
- orchestra/testbench: ^10.0 || ^11.0
- pestphp/pest: ^3.8 || ^4.0 || ^5.0
- ptondereau/biscuit-php-stubs: ^0.5.1
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-10 20:27:31 UTC
README
Laravel integration for Biscuit authorization tokens.
This repository is a read-only mirror. The package is maintained in the
packages/laravel/directory of ptondereau/biscuit-php and synced here automatically. Please open issues and pull requests against the main repository.
Requirements
- PHP 8.2 or later
- Laravel 12 or 13
- The
biscuit_phpextension:pie install ptondereau/biscuit-php
Installation
composer require ptondereau/biscuit-laravel php artisan vendor:publish --tag=biscuit-config
Set the root key in .env, as a hex string or a PEM file:
BISCUIT_PUBLIC_KEY=ed25519/... # BISCUIT_PUBLIC_KEY_FILE=/path/to/public.pem
The private key (BISCUIT_PRIVATE_KEY or BISCUIT_PRIVATE_KEY_FILE) is only needed to mint tokens.
Authorization
A Biscuit is not an authentication token. Keep your guards (session, Sanctum, Passport) for users. The token only carries rights.
The token comes from the Authorization: Bearer header, or from the cookie named in BISCUIT_COOKIE. Its signature is checked against the public key.
Declare Datalog policies in config/biscuit.php:
'policies' => [ 'posts.read' => 'allow if right("posts", "read")', 'posts.edit' => 'allow if right({resource}, "edit")', ],
Each policy is a Gate ability. It works with can middleware, Gate::allows(), @can and $this->authorize():
Route::middleware(['auth', 'can:posts.edit,post'])->put('/posts/{post}', UpdatePost::class);
The Gate argument fills the policy placeholders:
| Argument | Parameters |
|---|---|
| Eloquent model | {resource} = primary key |
| string or int | {resource} = the value |
| associative array | each key is a placeholder |
Placeholders the policy does not use are ignored. Values must be strings, integers or booleans. The authorizer adds the current time, so checks such as check if time($t), $t < 2030-01-01T00:00:00Z expire tokens.
An ability that starts with allow or deny is used as an inline policy: Gate::allows('allow if right("posts", "read")').
A Biscuit policy is denied when the request has no valid token, whoever the user is. Other abilities go to the app's own gates and policies.
Minting tokens
use Biscuit\Auth\BiscuitBuilder; use Biscuit\Auth\PrivateKey; $token = (new BiscuitBuilder('user({id}); right("posts", "read");', ['id' => 'alice'])) ->build(app(PrivateKey::class)) ->toBase64();
License
Apache-2.0