Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Sanctum Tokens Laravel Package

mlsolutions/sanctum-tokens

View on GitHub
Deep Wiki
Context7

Getting Started

Prerequisites

  • Laravel app with laravel/sanctum installed and migrated (php artisan migrate after publishing Sanctum's migration).
  • Laravel\Sanctum\HasApiTokens trait on the model that will own tokens (usually App\Models\User).
  • Laravel Nova 4/5 installed and working.
  • Check composer.json constraints in the repo against your Laravel/Nova versions before installing — this is a single-maintainer package with one release, so version support may lag.

Install and register

composer require mlsolutions/sanctum-tokens

Then follow the README's registration step. Nova packages of this shape usually register one of three ways:

  1. A Nova Tool added in app/Providers/NovaServiceProvider.php → tools([...]).
  2. A Resource Tool added to the fields() of your User resource (so it appears on the user detail page).
  3. A custom field / action attached to the resource.

Verify which by reading src/ and the service provider — the registration snippet in the README is the single source of truth here. After registering, run php artisan nova:publish if the package ships frontend assets, and clear caches (php artisan optimize:clear) if the tool doesn't appear.

First use case

The canonical day-to-day scenario: an admin opens a User in Nova, clicks the token panel, creates a token with a name and (optionally) abilities, and copies the plaintext token once from the UI to hand to an integration owner. Everything after that is lifecycle: listing tokens with last_used_at, revoking stale ones.

Where to look first

  1. README (install + registration + screenshot).
  2. src/ service provider — tells you whether it's a tool, field, or resource, and what config it reads.
  3. config/ (if publishable) — defaults for abilities, expiration, model binding.
  4. The Sanctum migration and personal_access_tokens table, since that's the data contract underneath.

Implementation Patterns

Attach to the User resource (most common)

Add the package's field/tool to app/Nova/User.php and keep it in a ->onlyOnDetail() context so it doesn't clutter index views. A typical detail page then shows: token name, abilities, created_at, last_used_at, expires_at, and a revoke button.

Scoped abilities instead of wildcard

When creating tokens through the UI, pass explicit abilities (['orders:read', 'orders:write']) rather than ['*']. Then in your API layer check $request->user()->tokenCan('orders:read') instead of relying on role checks. This is the main reason to use tokens over session auth for integrations: the blast radius of a leaked token is bounded.

Expiration strategy

Sanctum has a global sanctum.expiration (minutes) and a per-token expires_at. Decide which you're using before rollout:

  • Global expiration: simplest, but retroactively expires every token when you change config.
  • Per-token expires_at set at creation: better for contracts and audits; store the intent in the token name ("acme-sync-2025-06").

Admin/support workflow

Treat token creation as a privileged operation. Gate it with a policy or Gate check so only specific Nova roles can mint tokens for other users. A support agent being able to mint a token as any user is effectively full account impersonation for your API.

// app/Policies/UserPolicy.php
public function createToken(User $user, User $target): bool
{
    return $user->hasRole('admin');
}

Bulk operations via Nova Actions

For day-to-day hygiene, pair the package with a Nova Action on the User resource that revokes tokens where last_used_at is older than N days or expires_at < now(). The package handles creation; revocation is just $user->tokens()->where(...)->delete().

Programmatic creation (scripts, seeders, tests)

Don't route everything through Nova. For service accounts and local dev:

$token = $user->createToken('local-dev', ['orders:read'], now()->addMonth());
// $token->plainTextToken — only available here, once

Testing token auth

Sanctum::actingAs($user, ['orders:read']);
$this->getJson('/api/orders')->assertOk();

$this->getJson('/api/orders')->assertForbidden(); // wrong ability

For Nova-side tests, actingAs($admin) plus a post to whatever endpoint the tool registers (check routes/ in the package or Nova's tool endpoint convention).

Gotchas and Tips

The plaintext token is shown once, and only once. Sanctum stores a SHA-256 hash. If your UI flow loses it (page refresh, modal closed, copy failed), the only recovery is delete-and-recreate. Make sure the Nova component surfaces the token in a copy-to-clipboard field before dismissing, and warn users in the UI copy.

Don't confuse this with user-facing API keys. This package is an admin-plane tool. If end users need self-service API keys, build that in your app's own UI — you don't want the token lifecycle coupled to Nova availability or Nova permissions.

Privilege escalation is the real risk. Nova access ≠ permission to impersonate. Default-deny: only admins mint tokens, and log who created which token (the base table doesn't record a creator — add a created_by column via your own migration if you need an audit trail, or log to your activity log at creation time).

Package maturity. Zero stars, one release, single maintainer. Practical implications:

  • Pin the version in composer.json ("mlsolutions/sanctum-tokens": "1.0.*"), don't use ^ against a 0.x-style version range.
  • Read src/ before installing — it's small enough to audit in ten minutes.
  • Expect to vendor/fork it. Keep your own Nova resource or action as a fallback so you're never blocked by an abandoned dependency.
  • Check the composer.json require block explicitly for Laravel/Nova majors; a missing constraint will silently install on an unsupported version and fail at runtime.

Sanctum config interactions. SANCTUM_STATEFUL_DOMAINS and the sanctum.guard config affect whether tokenCan() behaves as you expect. If a freshly created token returns 401, check: correct guard, Authorization: Bearer <token>, token not expired, and the personal_access_tokens row exists with the right tokenable_type.

last_used_at is lazy. Sanctum updates it on authenticated requests, but not on every request in every version — don't build "active tokens" dashboards that assume second-level accuracy. For revocation campaigns, use a window (e.g. "unused in 90 days"), not a strict threshold.

Soft deletes and morphs. If your User model is soft-deletable, tokens survive deletion and tokenable resolution will fail or return a trashed model depending on your queries. Decide whether to cascade-delete tokens in deleting/forceDeleting hooks.

Extension points to prefer over patching. Override the Nova resource/field in your app rather than editing vendor/. If the package publishes config (php artisan vendor:publish --provider="MlSolutions\\SanctumTokens\\...ServiceProvider"), change abilities defaults and expiration there. If it doesn't publish config, wrap its behavior in your own Nova Action — that's the most upgrade-safe integration.

Debugging checklist when a token "doesn't work":

  1. Row exists in personal_access_tokens? (tokenable_id, abilities JSON).
  2. expires_at null or in the future?
  3. Header formatted correctly, no trailing whitespace/newline from a copy-paste of the UI token?
  4. Route protected by auth:sanctum middleware?
  5. tokenCan() returning false because abilities were stored as a JSON string vs array (check the cast)?
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums