For a Laravel API serving your own SPA and mobile app, when is Sanctum the right choice, and what requirement would push you to Passport?
answer
- first-party versus third-party clients
- Sanctum does not speak OAuth2
- opaque DB tokens, no refresh token
- Passport: clients, grants, scopes, keys
- docs: Passport only if you need OAuth2
basics
~20 sSanctum fits first-party clients: session cookies for your SPA and database-backed personal access tokens for your mobile app. Choose Passport only when you must be an OAuth2 authorization server, for example so third-party apps can act for your users.
solid answer
~50 sLaravel's docs put it bluntly: if the application absolutely needs OAuth2, use Passport; for an SPA, a mobile app or simple API tokens, use Sanctum. Sanctum gives your own SPA the `web` session and gives the mobile app opaque personal access tokens with abilities, stored hashed and revoked by deleting a row; it has no client registry, grants, consent screen or refresh tokens. Passport, built on `league/oauth2-server`, makes your app an OAuth2 server: registered clients, authorization-code with PKCE, client credentials and device grants, scopes, refresh tokens and signed access tokens that need `passport:keys`. So the trigger for Passport is a third party — a partner's app, a vet clinic's system — needing delegated access to your users' data, or an integration contract that mandates OAuth2. For a pet-sitting marketplace with only its own SPA and app, Sanctum is less to run and less to get wrong.
go deeper
Recall the docs' rule: Sanctum for your SPA, mobile app and simple tokens; Passport only when OAuth2 is required.
Contrast what each package stores and issues: Sanctum's hashed opaque tokens with abilities versus Passport's clients, grants, scopes and refresh tokens.
Name the concrete trigger for Passport — third-party delegated access or a mandated OAuth2 contract — and the operational cost you accept with it.
Decide whether to run an authorization server at all, or keep first-party auth simple and add OAuth only for a partner programme.
## The question behind the question "Sanctum or Passport?" is really **"who are your API's clients?"** Laravel's documentation answers in two sentences: if your application absolutely needs to support OAuth2, use Passport; if you are authenticating a single-page application, a mobile application, or issuing API tokens, use Sanctum. Sanctum does not support OAuth2 at all. ## What Sanctum gives you - **SPA session auth**: your own frontend on the same registrable domain uses the ordinary `web` session, CSRF-protected, with no token in the browser. - **Personal access tokens**: `createToken($name, $abilities, $expiresAt)` stores a SHA-256 hash in `personal_access_tokens`; the client sends `id|secret` as a Bearer token. - **Abilities**: free-form strings on a token, checked with `tokenCan()` and the `abilities` / `ability` middleware. - **Revocation by deletion**: a deleted row fails on the next request. - **Small surface**: one table, one guard driver, one prune command. What it lacks is exactly the OAuth2 machinery: no registered clients, no authorization endpoint or consent screen, no grant types, no refresh tokens. ## What Passport adds - A full **OAuth2 authorization server** on `league/oauth2-server`, installed with `php artisan install:api --passport`. - **Clients** created with `passport:client`, each with its own redirect URIs and hashed secret. - **Grants**: authorization code (with PKCE for public clients), client credentials, refresh token and device authorization; the password and implicit grants are off unless you enable them. - **Scopes** declared with `Passport::tokensCan()`. - **Signed access tokens**, which is why `passport:keys` generates an RSA key pair; lifetimes default to one year unless configured. ## A decision table | Requirement | Sanctum | Passport | |---|---|---| | Your SPA, same top-level domain | Yes — session mode | Possible, heavier | | Your own mobile app | Yes — personal access tokens | Yes, via an OAuth flow | | Users generate tokens for their own scripts | Yes | Yes, as personal access clients | | Third-party apps act for your users with consent | No | Yes — authorization code + PKCE | | Machine-to-machine client with its own credentials | Only by issuing a token to a model | Yes — client credentials grant | | Short-lived access token plus refresh token | No refresh token | Yes | ## Judgment calls a senior should voice 1. **Do not choose Passport for "future-proofing".** Its clients, keys, grant configuration and upgrade notes are real operational cost; Sanctum can later sit beside Passport for first-party traffic if a partner programme appears. 2. **Mobile does not require OAuth.** A first-party app can exchange credentials for a Sanctum token; the docs show exactly that flow. 3. **Refresh semantics differ.** With Sanctum, the policy is long-ish tokens plus explicit expiry and re-login; with Passport, short access tokens plus refresh tokens. 4. **Running your own issuer is a commitment.** If the requirement is "log in with our identity provider" rather than "let others log in with us", neither package is the answer — you are the client, not the server. 5. **The docs' own hint**: an app using Passport mainly to issue personal access tokens should consider Sanctum instead. For a pet-sitting marketplace with an owners' SPA and a sitters' mobile app, Sanctum covers both clients. The day a partner vet-clinic system needs to read a pet's booking history on the owner's behalf, you are in OAuth territory and Passport earns its keep. ## How Sanctum validates a token, in contrast Every Sanctum Bearer request costs a database lookup by id, a SHA-256 comparison and, by default, a `last_used_at` write. That is the price of instant revocation: delete the row and the next request fails. It is rarely a bottleneck for first-party traffic, and it is one more reason Sanctum stays simple — there are no keys to rotate and no token format to parse.
- How does a Sanctum mobile client recover when its token expires?It signs in again through your credentials endpoint and receives a new token from `createToken()`. Sanctum has no refresh-token grant, so the lifetime you choose is a trade-off between user friction and how long a stolen token stays useful.
- Can Sanctum and Passport run in the same application?Both register their own guard driver, so an app can use `auth:sanctum` for its SPA routes and a Passport guard for partner routes. The cost is two token models and two sets of configuration, so do it only when a real third-party requirement exists.
saying these in an interview costs you the question
- Mobile apps need Passport because they cannot use Sanctum tokens
- Sanctum is a simplified OAuth2 server with fewer grants
- Pick Passport by default so you can add partners later
- Sanctum tokens are JWTs, so they cannot be revoked
- Per-token permissions require Passport scopes