Auth facade with no new API to learn. You keep Auth::check(), Auth::user(), standard middleware, and standard events; the package adds contextual accessors and ships hardened jwt and basic guards on top.
Why contextual auth
A single-model approach works fine for simple apps, but breaks down when the same person needs to act on behalf of different tenants, memberships, or roles — or when you need to track which client device issued a request for replay protection and last-seen tracking. By separating Identity from Principal, you can model the full “logged in as X, acting as Y inside tenant Z” relationship cleanly, and the package’s JWT pipeline encodes that context directly into the token claims.Core concepts
| Concept | What it is |
|---|---|
| Identity | Who logged in. The account behind the request — a person or a service account. |
| Principal | Who the request is acting as. Often the same as the identity; can be a role or membership. |
| Device | Which client obtained the login — a browser, a mobile app, a CLI session. |
| Tenant | The isolation boundary the principal acts within. Optional, for multi-tenant apps. |
| Type | An optional categorical label on the tenant — e.g. "staff" vs "customer". |
Adoption modes
The package supports two adoption shapes with the same guards, so you can start simple and grow without re-platforming. 2D mode (identity is the principal) is the simplest shape. One model implements bothIdentity and Principal. The user who logs in is the actor on whose behalf the request runs. Auth::identity() and Auth::principal() return the same object.
3D mode (identity → principal → tenant) is for multi-tenant apps where the logged-in human operates on behalf of a tenant-scoped actor. The identity and principal are separate models. A pid claim in the JWT encodes which principal is active, and Auth::principal() returns that tenant-scoped membership or role. Auth::tenant() returns the tenant the principal belongs to.
Guards
Two sessionless guards are included, registered viaauth.guards.*.driver in config/auth.php:
jwt— Bearer token guard. Access tokens are self-verifying JWTs. The guard rehydrates identity and principal on every bearer request with no server-side access-token store. Refresh-token rotation is device-backed and stateful.basic— HTTP Basic guard. Wraps credential validation in a constant-timeTimeboxto prevent timing side-channels. Supports per-guard identifier fields (email,username,key_id, etc.).
Contextual accessors
Import the package’sAuth facade to get IDE-friendly autocompletion on the contextual methods:
auth container key. You can keep the Illuminate facade for Auth::check() and Auth::user() — the contextual accessors only become available when you swap to the package facade.
Requirements
- PHP ^8.3 (extensions:
hash,mbstring,openssl) - Laravel ^12.40 || ^13.3
Installation
Install via Composer, publish config and migrations, and set your JWT secret.
Quick start
Wire up your first JWT guard and issue your first access token.