Laravel has four first-party authentication packages. The documentation covers what each one does. What it doesn’t tell you clearly, at least is when to use each one and why the others would be wrong for that situation.
If you’ve spent time flipping between the Sanctum docs and the Passport docs trying to figure out which one your app actually needs, this is the post that should have existed from the beginning.
Short Answer
| What you’re building | Use this |
|---|---|
| SPA (React, Vue, Next.js) talking to a Laravel API | Sanctum (cookie auth) |
| Mobile app consuming a Laravel API | Sanctum (API tokens) |
| Internal tool, admin panel, simple web app | Breeze or Fortify + session auth |
| Public API for third-party developers | Passport (full OAuth 2.0) |
| Your app needs to act as an OAuth provider (Login with YourApp) | Passport |
| B2B SaaS where other companies need to connect programmatically | Passport |
Most apps: Sanctum. Apps that need OAuth: Passport. UI-only apps: Breeze. That’s 80% of the decision. The rest of this post is for the 20% where it’s less obvious.
Full Picture: Four Packages, Four Purposes
The confusion happens because the names don’t explain the purpose clearly. Here’s the one-line version of each:
- Sanctum — Lightweight token and cookie auth for your own front-end clients
- Passport — Full OAuth 2.0 server for third-party API consumers
- Fortify — Headless auth backend (login, register, 2FA, email verify) — no UI
- Breeze — Scaffolded auth UI (Blade, Vue, React starter kit) built on Fortify
Fortify and Breeze handle traditional session-based authentication for web apps. Sanctum and Passport handle API authentication. That’s the first split.
Within API auth, the choice between Sanctum and Passport comes down to one question: are you building auth for your own front-end, or for third-party developers?
Laravel Sanctum: What It Actually Does
Sanctum is the right default for most Laravel APIs in 2026. Here’s why.
It handles two distinct authentication scenarios and it’s worth understanding both because they use different mechanisms.
Sanctum: SPA Authentication (Cookie-based)
When your SPA (React, Vue, Nuxt, Next.js) is served from the same top-level domain as your Laravel API, Sanctum uses standard session cookies. Your SPA calls /sanctum/csrf-cookie to initialize the CSRF token, then authenticates with /login. From that point on, the session cookie handles all subsequent requests, the same way a traditional web app works.
This is significant because cookie-based auth with CSRF protection is more secure than storing a token in localStorage. There’s no bearer token to steal via XSS. The session lives in an HttpOnly cookie that JavaScript can’t touch.
The practical requirement: your SPA and your API need to share a top-level domain. app.yoursite.com + api.yoursite.com works. yoursite.com + different-backend.com doesn’t.
Sanctum: API Token Authentication
For mobile apps, CLI tools, or any client that can’t use cookies, Sanctum provides API tokens. A user authenticates once and receives a token. That token is stored on the client and sent as a bearer token on every subsequent request.
Sanctum tokens are intentionally simple compared to OAuth. There are no refresh tokens, no token expiry by default (though you can configure it), no authorization scopes per-client. A token either works or it doesn’t.
This simplicity is the point. If you’re building a mobile app that authenticates as a specific user and needs to call your API, Sanctum handles this with almost no overhead.
What Sanctum doesn’t do
Sanctum has no concept of OAuth clients, authorization flows, or delegated access. It can’t generate “login with YourApp” flows. It can’t issue scoped tokens to third-party developers who want to build on top of your platform. It doesn’t support authorization code flows, client credentials flows, or any other OAuth grant type.
For all of that, you need Passport.
Laravel Passport: What It Actually Does
Passport is a full OAuth 2.0 authorization server implementation for Laravel. That sentence matters: it’s an authorization server, not just an auth library. When you install Passport, your Laravel app becomes capable of acting as an OAuth provider, the way GitHub, Google, or Stripe act as OAuth providers.
What OAuth 2.0 actually means in practice
OAuth 2.0 is a protocol for delegated authorization. It lets a user grant a third-party application limited access to your API on their behalf, without giving that application the user’s credentials.
When you build with Passport, you can:
- Issue authorization codes to third-party developers
- Manage OAuth clients (applications registered to use your API)
- Define scopes that limit what a token can access
- Support multiple grant types: authorization code, client credentials, password, implicit
- Issue refresh tokens for long-lived access
- Build a “Login with YourApp” flow that other apps can implement
This is powerful infrastructure. It’s also infrastructure most apps don’t need.
When Passport is actually the right choice
You’re building a public API platform. If developers outside your company will be building applications that connect to your API, you need OAuth. Personal access tokens from Sanctum are for your own front-ends. OAuth clients are for everyone else’s.
Your app needs to be an OAuth provider. If you want other apps to offer “Login with YourApp” or “Connect YourApp Account” like Slack’s OAuth login, Stripe Connect, or Shopify’s Partner API — that’s Passport.
B2B integrations that require scoped, auditable access. If companies will be connecting their systems to your API and you need to manage which client has which permissions, revoke access per-client, and audit API usage by OAuth client, Passport gives you that infrastructure.
Machine-to-machine auth (client credentials flow). If you have separate services that need to talk to your API without a human user in the loop, Passport’s client credentials grant handles this cleanly.
What Passport costs you
Passport is heavier than Sanctum. It requires more infrastructure (it creates several database tables for clients, tokens, and auth codes), has more configuration surface area, and takes longer to understand and set up correctly.
The bigger cost is conceptual overhead. OAuth 2.0 has real complexity — grant types, scopes, token introspection, refresh flows. If your team doesn’t need OAuth and you install Passport because it seemed more “complete,” you’re carrying that complexity with no benefit.
Fortify and Breeze: Where They Fit
Since these come up in every auth discussion, here’s where they actually live in the stack.
Fortify is a headless authentication backend. It implements login, registration, password reset, email verification, and two-factor authentication but it has no UI. It’s designed to be the auth engine that Breeze and other front-end starters are built on top of. You’d use Fortify directly if you’re building a custom UI and want the backend auth logic handled without opinions on your front-end.
Breeze is a starter kit — authentication scaffolding with a UI included. It comes in Blade, Livewire, Vue (Inertia), and React (Inertia) flavors. If you’re building a traditional web app and want a working login/register/reset flow out of the box, Breeze is the fastest starting point. It uses session-based auth, which is exactly right for browser-rendered applications.
Neither Fortify nor Breeze is an API authentication solution. They’re session-based web authentication. For API auth, you’re back to choosing between Sanctum and Passport.
Decision Tree
Work through this when you’re making the call:
Is any part of your app a traditional web app with Blade views (not an SPA)?
Yes → Use Breeze (if you want scaffolded UI) or Fortify (if you’re building your own UI). These handle session auth for you.
No, it’s all API → Continue.
Will third-party developers outside your company be consuming your API, or will your app act as an OAuth provider?
Yes → Passport
No → Sanctum
Within Sanctum, which authentication method?
Is your front-end a SPA on the same top-level domain as your API?
Yes → Use Sanctum’s cookie-based SPA auth
No (mobile app, CLI, external client) → Use Sanctum’s API tokens
If you get to the end and you’re still unsure: use Sanctum. You can always migrate to Passport later if you need OAuth. Going from Sanctum to Passport is an additive change. The reverse stripping out Passport because you realized you didn’t need it is more painful.
Common Scenarios, Definitive Answers
“I’m building a React SPA backed by a Laravel API.”
Sanctum, cookie auth. Your React app and Laravel API should share a domain (or subdomain). Run through the CSRF init flow, use /login to authenticate, and every subsequent API call uses the session cookie. No tokens on the client.
“I’m building a mobile app (iOS/Android) that needs to call a Laravel API.”
Sanctum, API tokens. Mobile apps can’t use cookie-based session auth properly. Issue a token on login, store it securely in the native keychain, send it as a bearer token on API calls.
“I’m building a SaaS and want to let customers connect our product to their other tools (Zapier, Slack, custom integrations).”
Passport. You need OAuth clients, scopes, and the authorization code flow so third-party tools can request access on behalf of your users.
“I’m building an internal tool for our company — no external API access.”
Breeze or Fortify with session auth. You don’t need API token auth at all. Sessions are simpler, more secure for web apps, and require no client-side token management.
“I’m building a B2B SaaS where enterprise customers want to integrate with us via API.”
Passport, specifically the client credentials flow for machine-to-machine, and the authorization code flow for user-delegated access. You’ll want to define scopes so customers can limit what their API keys can do.
“I just need API auth and I’m not sure what the front-end will look like yet.”
Sanctum with API tokens. It’s simple to set up, easy to test, and you can layer in cookie auth for an SPA later or switch to Passport if you end up needing OAuth. Don’t install Passport speculatively.
Note on Token Security
One thing the docs underemphasize: how you store and transmit tokens matters as much as which package you use.
Never store API tokens in localStorage. XSS vulnerabilities can steal localStorage contents. A stolen Sanctum API token is just as bad as a stolen password. If you’re building an SPA, use Sanctum’s cookie auth, the session is stored in an HttpOnly cookie that JavaScript can’t read.
For mobile apps, use the platform keychain. iOS Keychain and Android Keystore are designed for this. Don’t store tokens in shared preferences or local files.
Scope Passport tokens appropriately. If you’re using Passport, define narrow scopes and grant clients only what they need. A token that can do everything is a bigger blast radius if it’s compromised.
Set token expiration. Sanctum tokens don’t expire by default. For production APIs, add expiration via the expiration config. For Passport, set appropriate token lifetimes for your use case — short-lived access tokens with longer-lived refresh tokens is the standard pattern.
How LaraCopilot Handles Auth
One of the things developers consistently get wrong when setting up new Laravel projects is choosing and wiring auth before they’ve fully defined what they’re building. You end up installing Passport, then realizing you don’t need OAuth, then ripping it out.
LaraCopilot generates auth scaffolding based on what you’re building, not as a separate step. Describe your app, “a SaaS with a React front-end and a mobile companion app” and it wires Sanctum for both the cookie-based SPA auth and the mobile API token auth. Describe a platform API that external developers will consume and it scaffolds Passport with sensible defaults.
The generated code follows current Laravel best practices for whichever auth package is appropriate. You’re not starting from scratch or copy-pasting documentation examples, you get a working foundation you can immediately build on.
Read more about generating a full-stack Laravel app with auth already configured: Generate a Laravel Full-Stack App with AI
Ready to Code Smarter with Laravel?
Meet LaraCopilot — your AI full-stack assistant built for Laravel developers.
Skip the boilerplate, build faster, and focus on what matters: problem solving.
Bottom Line
The mental model that makes this click: Sanctum is for auth between your app and your own clients. Passport is for auth between your app and everyone else’s clients.
If you’re building a web app, SPA, or mobile app that talks to your own Laravel backend, Sanctum handles it and it handles it more simply and securely than Passport for that use case.
If you’re building infrastructure that other developers or companies will connect to, that’s an OAuth problem, and Passport is the right tool.
Don’t install Passport because it sounds more enterprise or more complete. Install it because you need an OAuth authorization server. That’s what it’s for.