Weave Code
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

Paseto Laravel Package

paragonie/paseto

Reference PHP implementation of PASETO security tokens (v3/v4): safer alternative to JWT/JWE/JWS with modern crypto. Supports local and public tokens, includes PASERK integration for key serialization/wrapping, and works with Sodium (or sodium_compat).

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Strong Fit for Authentication/Authorization: PASETO excels as a replacement for JWT/JWE in Laravel, addressing cryptographic flaws (e.g., lack of integrity protection in JWT) while maintaining compatibility with existing token-based workflows (e.g., Laravel Sanctum, Passport).
  • Protocol Versioning: Supports seamless migrations via versioned tokens (v3/v4), reducing risk during upgrades. Aligns with Laravel’s modular architecture (e.g., swapping out JWT mid-project).
  • Purpose Separation: local (encrypted) and public (unencrypted) tokens enable granular use cases (e.g., local for internal APIs, public for stateless auth).
  • Key Management: Integrates with Laravel’s encryption (e.g., config/encryption.php) via symmetric/asymmetric keys, with optional PEM/Sodium support.

Integration Feasibility

  • Laravel Ecosystem Synergy:
    • Replaces firebase/jwt or lcobucci/jwt in auth packages (e.g., Sanctum, Passport).
    • Compatible with Laravel’s caching (e.g., Redis) for token storage/validation.
    • Works with middleware (e.g., auth:api) via custom guards or token parsers.
  • Database Schema: Minimal changes required (e.g., storing paseto tokens instead of JWTs in sessions or oauth_access_tokens tables).
  • Caching: Tokens can be cached as strings (e.g., cache()->put('paseto:user123', $token)), with validation on access.

Technical Risk

  • Key Rotation: Requires careful planning for KeyRing support (e.g., overlapping keys during transitions). Laravel’s config/keys.php can store multiple keys.
  • Sodium Dependency: v4 tokens prefer Sodium; fallback to sodium_compat adds ~100KB but may impact performance. Test in staging first.
  • Migration Complexity: Replacing JWTs requires updating all token issuance/validation points (e.g., API routes, CLI commands). Use feature flags to isolate changes.
  • Footer/Implicit Assertions: Novel features may require Laravel-specific validation logic (e.g., custom Validator rules for footers).

Key Questions

  1. Token Storage: Will tokens be stored in DB, cache, or cookies? PASETO’s size (~1KB for v4.local) may impact cookie storage limits.
  2. Key Management: How will keys be rotated? Will KeyRing be used, or manual key updates in config/encryption.php?
  3. Performance: Benchmark v4 tokens against current JWT/JWE for latency (especially with Sodium).
  4. Audit Trail: How will token validation failures (e.g., expired, invalid key) be logged? Extend Laravel’s auth logging.
  5. Third-Party Integrations: Are any packages (e.g., Stripe, AWS) expecting JWTs? If so, dual-write during migration.
  6. Compliance: Does PASETO meet regulatory requirements (e.g., HIPAA, GDPR)? Review specification for compliance notes.

Integration Approach

Stack Fit

  • Laravel Core: Replace Illuminate\Contracts\Auth\AccessToken or Illuminate\Auth\Guard implementations to use PASETO.
  • Auth Packages:
    • Sanctum: Extend Sanctum\PersonalAccessToken to use PASETO builders/parsers.
    • Passport: Override OAuth2\AccessToken to issue PASETO tokens via custom TokenRepository.
  • Caching: Use Laravel’s cache drivers (Redis, Memcached) to store parsed tokens for performance.
  • Queue Jobs: Offload token validation to queues (e.g., ValidatePasetoToken::dispatch($token)) for high-traffic APIs.

Migration Path

  1. Phase 1: Pilot
    • Replace a single auth endpoint (e.g., /api/login) with PASETO.
    • Use feature flags (config('auth.use_paseto', false)) to toggle between JWT/PASETO.
  2. Phase 2: Core Integration
    • Update Sanctum/Passport to support PASETO via config:
      'auth' => [
          'default' => 'paseto',
          'guards' => [
              'api' => [
                  'driver' => 'token',
                  'provider' => 'users',
                  'use_paseto' => true,
              ],
          ],
      ],
      
    • Migrate token storage tables (add paseto_token column alongside token).
  3. Phase 3: Full Cutover
    • Deprecate JWT issuance in favor of PASETO.
    • Update third-party integrations (e.g., webhooks) to accept PASETO.

Compatibility

  • Backward Compatibility: Maintain JWT support during migration via polyfills (e.g., PasetoJwtAdapter).
  • Key Compatibility: Ensure existing Laravel encryption keys (APP_KEY) can be reused for symmetric PASETO (SymmetricKey).
  • Middleware: Extend Illuminate\Auth\Middleware\Authenticate to handle PASETO tokens:
    public function handle($request, Closure $next) {
        if ($request->bearerToken() && config('auth.use_paseto')) {
            $token = $this->validatePasetoToken($request->bearerToken());
            auth()->setUser($token->getUser());
        }
        return $next($request);
    }
    
  • Testing: Use Laravel’s HttpTests to verify token flows (e.g., login, refresh, revocation).

Sequencing

  1. Key Generation: Generate PASETO keys and store in config/encryption.php or a secrets manager.
  2. Builder Setup: Create a PasetoService facade to wrap token creation:
    class PasetoService {
        public function issueLocal(array $claims): string {
            $key = SymmetricKey::fromString(config('paseto.key'));
            return Builder::getLocal($key)
                ->setClaims($claims)
                ->setExpiration(now()->addHours(1))
                ->toString();
        }
    }
    
  3. Parser Setup: Build a PasetoGuard to validate tokens in middleware:
    class PasetoGuard extends Guard {
        public function validateToken($token) {
            $parser = Parser::getLocal(SymmetricKey::fromString(config('paseto.key')))
                ->addRule(new ValidAt)
                ->addRule(new IssuedBy(config('app.name')));
            return $parser->parse($token);
        }
    }
    
  4. Database Migration: Add paseto_token column to sessions/oauth_access_tokens:
    Schema::table('oauth_access_tokens', function (Blueprint $table) {
        $table->text('paseto_token')->nullable()->after('token');
    });
    

Operational Impact

Maintenance

  • Key Rotation: Automate via Laravel’s schedule or a cron job to update KeyRing entries:
    // app/Console/Commands/RotatePasetoKeys.php
    public function handle() {
        $oldKey = SymmetricKey::fromString(config('paseto.old_key'));
        $newKey = SymmetricKey::generate();
        config(['paseto.key' => $newKey->raw()]);
        $this->updateKeyRing($oldKey, $newKey);
    }
    
  • Dependency Updates: Monitor paragonie/paseto for breaking changes (e.g., PHP 8.2+ features). Use Laravel’s composer.json scripts for testing:
    "scripts": {
        "test:paseto": "php artisan paseto:test"
    }
    
  • Logging: Extend Laravel’s auth logging to include PASETO events (e.g., paseto.validated, paseto.expired).

Support

  • Troubleshooting: Common issues:
    • Token Rejection: Check key version/purpose mismatch (e.g., v3.local vs v4.public).
    • Performance: Profile Sodium vs. OpenSSL for v4 tokens.
    • Footer Errors: Validate JSON rules in Parser (e.g., FooterJSON max depth).
  • Documentation: Add PASETO-specific docs to Laravel’s auth section, including:
    • Key management best practices.
    • Example KeyRing configurations for multi-tenant apps.
    • Migration checklist.

Scaling

  • Horizontal Scaling: PASETO tokens are stateless; scale validation across workers by distributing keys via config or a shared cache (Redis).
  • Token Size: v4.local tokens are ~1KB; ensure API gateways (e.g., Nginx) handle headers up to 4KB.
  • Rate Limiting: Use Laravel’s throttle middleware to limit token validation attempts (e.g., brute-force attacks on public tokens).

Failure Modes

| **Failure

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.
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope
nawasara/auth-primitives
adhocrat-io/arkhe-main
make-dev/orca-harpoon
itsemon245/lamet
baks-dev/dashboard
amoifr/pickle-panther-bundle
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle