Auth::identity() and Auth::principal() both resolve to the same object. This is the right starting point for most apps: you can grow into 3D later without re-platforming your guard configuration.
Add the Identity and Principal contracts to your user model
Your user model must implement both Point
Identity and Principal. The Authenticatable trait is a stateless drop-in for Laravel’s own Illuminate\Auth\Authenticatable — it suppresses the remember-token accessors that have no meaning in a sessionless package. The ActsAsPrincipal trait provides default implementations of the Principal contract methods (getPrincipalIdentifier(), getIdentity(), getTenant(), isActive()).auth.providers.users.model at AppUser::class and the guard will use it for every bearer-token lookup.Register the guard in config/auth.php
Register a guard with Protect routes with the standard Laravel middleware:
driver: jwt and wire it to your user provider. No extra service provider registration is needed — the package auto-registers its guard drivers.auth:api.Optionally add HasDevices for refresh-token rotation
Device tracking and refresh-token rotation are opt-in. If you need them, publish and run the devices migration, then implement Without
HasDevices on your model with a morphMany relation:HasDevices, the guard operates in access-only mode: Auth::device() returns null and $guard->refresh() is unavailable. You can add device tracking later — it is purely additive.Issue an access token at login
After validating credentials, call For access-only mode without device tracking, pass
issueAccessToken() on the guard-scoped JWT service. Pass the identity, the principal, and — if you are using device tracking — the device record. Pass null for the device in access-only mode.null as the third argument and skip issueRefreshToken:Verify the contextual accessors
Once a request arrives with a valid bearer token, the guard rehydrates both identity and principal from the database and binds them. In 2D mode both accessors return the same model instance.If you call
Auth::identity() === Auth::principal() in 2D mode, the result is true — they are the same object.