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 as Authorization: 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\HasApiTokens to your User model (exactly where Laravel's own scaffolding puts it), and
  • provisions the personal_access_tokens table 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/token against 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:

  • Sanctumlaravel/sanctum is already in your composer.json; the personal_access_tokens table is on your database. Nothing to do.
  • Passportlaravel/passport ships in composer.json and the oauth_* tables are on your database. On your own server, generate the signing keys once with php artisan passport:keys (or set PASSPORT_PRIVATE_KEY / PASSPORT_PUBLIC_KEY as environment variables), and the stock /oauth/token route serves your existing clients.

Next Steps