Documentation
API Authentication
Sanctum tokens and Passport OAuth2, running on your own database
Stellify runs Laravel's own authentication packages inside your project — not a hand-rolled imitation. Enable a capability and you get real Sanctum API tokens or a real Passport OAuth2 server, issuing and verifying against your project's database. On export there's nothing to rewrite: the same package, the same tables, the same code.
Overview
Two capabilities cover API authentication, and you pick by use case:
- Sanctum — simple bearer tokens ("API keys"). A user calls
createToken(), you hand the plain-text token to a client, and requests carry it asAuthorization: Bearer …. Best for first-party apps, personal access tokens, and machine-to-machine keys you issue yourself. - Passport — a full OAuth2 server. Third parties exchange credentials at a token endpoint for short-lived access tokens (with refresh tokens). Best when other applications need to authenticate against your project — client-credentials for server-to-server, password grant for trusted first-party logins.
Both store their data — tokens, clients — on your project's connected database, never Stellify's. That's what makes export a no-op: your live app already owns the rows.
Enable either from Project Settings → Capabilities (or ask an agent to enable the sanctum / passport capability).
Sanctum: API Tokens
Enabling the sanctum capability does two things automatically:
- adds
Laravel\Sanctum\HasApiTokensto yourUsermodel (exactly where Laravel's own scaffolding puts it), and - provisions the
personal_access_tokenstable on your database.
Any model can opt in by listing the trait in its uses.
Issuing a token
$token = $user->createToken('mobile-app')->plainTextToken;
return response()->json(['token' => $token]);
The plain-text token is shown once — return it to the caller and store only the hash (Sanctum handles that for you).
Verifying a request
Add auth:sanctum to a route's middleware (in the route editor's Middleware field). Requests without a valid bearer token are rejected with 401 before your controller runs — you never write the check yourself. Inside the controller, the authenticated user is available through auth():
$user = auth()->user(); // the token's owner
$token = $user->currentAccessToken();
Tokens can carry abilities (scopes) and expiry — $user->createToken('name', ['orders:read'], now()->addDays(30)) — enforced by Sanctum in the usual way.
Passport: OAuth2 Server
Enabling the passport capability provisions the OAuth tables (oauth_clients, oauth_access_tokens, oauth_refresh_tokens, and the auth-code / device-code tables) on your project's database.
Create a client
Clients are created in your project code (run it once, e.g. from a seeder or a one-off Run):
// Server-to-server (client credentials)
$client = (new \Laravel\Passport\ClientRepository())
->createClientCredentialsGrantClient('Reporting Service');
// Trusted first-party login (password grant)
$client = (new \Laravel\Passport\ClientRepository())
->createPasswordGrantClient('Mobile App', confidential: true);
The client's plain_secret is only readable at creation — capture it then.
The token endpoint
In the studio, tokens are issued at a project-scoped endpoint (because the studio is a shared test instance and your clients live on your database):
POST /oauth/{yourProjectId}/token
Client-credentials example:
curl -X POST https://stellisoft.com/oauth/{projectId}/token \
-d grant_type=client_credentials \
-d client_id={clientId} \
-d client_secret={clientSecret}
Password grant:
curl -X POST https://stellisoft.com/oauth/{projectId}/token \
-d grant_type=password \
-d client_id={clientId} \
-d client_secret={clientSecret} \
-d username=user@example.com \
-d password=secret
Supported grants: client_credentials, password, and refresh_token. The response is the standard OAuth2 payload — access_token, token_type, expires_in, and (for the password grant) refresh_token.
On export the
/{projectId}prefix drops away and stock Passport serves/oauth/tokenagainst the same tables. The authorization-code consent screen is coming; the grants above cover server-to-server and trusted first-party logins today.
Verifying a request
Add auth:api to a route's middleware. Passport validates the token's signature and confirms it exists on your database — a token minted for another project can never authenticate against yours. Inside the controller:
$user = auth()->user(); // the token's user (null for client-credentials tokens)
How auth() behaves in the studio
Inside your project code, auth() resolves the tenant principal — the user tied to the bearer token the request carried. When no token is present (for example while you preview your own app in the editor), it falls back to your studio session so previews still behave like a logged-in user. Token-authenticated API calls always see the token's user.
Export
Both capabilities export as ordinary Laravel:
- Sanctum —
laravel/sanctumis already in yourcomposer.json; thepersonal_access_tokenstable is on your database. Nothing to do. - Passport —
laravel/passportships incomposer.jsonand theoauth_*tables are on your database. On your own server, generate the signing keys once withphp artisan passport:keys(or setPASSPORT_PRIVATE_KEY/PASSPORT_PUBLIC_KEYas environment variables), and the stock/oauth/tokenroute serves your existing clients.
Next Steps
- Database Connection - Where your tokens and clients are stored
- Project Settings - Enable capabilities
- Exporting Code - Your exported app keeps the same auth
- Previous
- Database Connection
- Next
- Project Settings