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

Authkit Laravel Laravel Package

birdcar/authkit-laravel

birdcar/authkit-laravel is a Laravel authentication toolkit designed to simplify common auth setup and user flows. It offers a lightweight starting point for adding authentication to Laravel applications, with a small footprint, straightforward integration, and a minimal approach for projects seekin...

View on GitHub
Deep Wiki
Context7

Getting Started

Start with the config and the guard, then wire a test on day one — this release makes the test loop the fastest way to learn the package.

  1. Install and publish config

    composer require birdcar/authkit-laravel
    php artisan vendor:publish --tag="authkit-config"
    

    Set the WorkOS credentials (WORKOS_CLIENT_ID, WORKOS_API_KEY, redirect URI) and point the workos guard at your User model.

  2. Look first at: config/authkit.php (guard, organization sync, FGA, Vault disk, HTTP transport), then docs/testing.md — it is the canonical map of every fake and assertion added in 2.1.0.

  3. First use case — gate checks driven by WorkOS roles/permissions:

    Route::middleware(['auth:workos'])->group(function () {
        Route::get('/dashboard', DashboardController::class)
            ->middleware('can:view-dashboard');
    });
    

    Inside the request, use Authkit::currentOrganization() and $request->organization() rather than re-reading the session.

  4. First test — no cookies, no JWKS fetch, no network:

    use Birdcar\Authkit\Facades\Authkit;
    
    it('shows the dashboard', function () {
        Authkit::actingAs(User::factory()->create(), [
            'organization' => 'org_123',
            'roles' => ['admin'],
            'permissions' => ['dashboard.view'],
        ]);
    
        $this->get('/dashboard')->assertOk();
    });
    

If you already have a test suite, add Http::preventStrayRequests() to your base TestCase before adopting the fakes — it will surface any code path still talking to WorkOS for real.

Implementation Patterns

Synthetic sessions for feature tests. Authkit::actingAs($user, [...]) builds a session that flows through the same contracts as a real login, so anything downstream of the guard behaves normally:

Authkit::actingAs($user, [
    'organization' => $organization,      // model or 'org_...' string
    'roles' => ['admin'],
    'permissions' => ['invoices.manage'],
    'features' => ['beta-reports' => true],
]);

Feature flags land in the Pennant workos store, so Feature::active('beta-reports') and Blade @feature directives work unchanged. Authkit::actingAsGuest() covers the unauthenticated branch.

Impersonation. Pass the impersonator in the acting-as options; the Impersonating event fires so your listeners and audit hooks still run.

Selective faking. Fake the whole surface, or only what the test touches:

$workos = Authkit::fake();                      // everything
$workos = Authkit::fake(['fga', 'vault']);      // just these two

Unfaked managers keep real behavior on every code path — useful when a test needs the genuine Vault crypto or a live SDK call, dangerous if you forget preventStrayRequests().

Scripting and asserting per manager.

  • FGA: script allow/deny (default deny), then assertChecked(...) to prove the check happened, not just that the response was right.
  • Invitations: stateful send/revoke/accept registry — assert the invitation exists after the endpoint returns.
  • Audit Logs: AuditLog::assertLogged(...) resolves the real actor and applies the same metadata sanitization as production; export lifecycle and schema registrations are covered too.
  • Organization sync: captured at the Bus level, then completeSync() to drive the job to completion without queue workers.
  • API keys: user- and org-scoped create/list/revoke; fake keys authenticate through the real authkit-key guard, so key middleware is genuinely exercised.
  • Vault: in-memory KV with version history and ConflictException parity — the Vaulted cast and vault disk run their real code over marked fake crypto.
  • Pipes: connected-account fixtures plus scripted tokens; both business exceptions are triggerable, so failure branches are testable.
  • Groups: CRUD, membership, role assignments, with the FGA cache-bust contract preserved.

HTTP-level assertions. WorkOS traffic now rides the application's HTTP client (authkit.http.transport, default laravel), so Laravel's idioms apply:

Http::fake([
    'api.workos.com/*' => Http::response(['data' => []], 200),
]);

Authkit::actingAs($user);
$this->get('/invitations')->assertOk();

Http::assertSent(fn ($request) => str_contains($request->url(), 'invitations'));

This is the right tool for asserting wire shape (endpoints, headers, payloads); the manager fakes are the right tool for asserting application behavior.

Test-suite composition. Use actingAs for the 90% case (controllers, policies, gates), manager fakes for integration tests around a single WorkOS feature, and Http::fake() only when the request itself is the contract.

Gotchas and Tips

  • Selective fakes leak. Authkit::fake(['fga']) leaves every other manager live. If a controller touches Vault, the test hits the network. Pair partial faking with Http::preventStrayRequests() so leaks fail loudly instead of flakily.
  • Asserting without faking throws. Calling AuditLog::assertLogged(...) before Authkit::fake() raises a LogicException naming the fix. Good behavior, but it means a shared test helper that fakes one manager can't be reused to assert on another.
  • Fakes are in-memory and per-test. Nothing persists across tests or across RefreshDatabase boundaries. Re-script inside each test — don't stash state on a static or a setUp singleton.
  • actingAs is not a real login. No cookie, no JWKS fetch, no SDK call. Anything keyed off actual authentication events (beyond Impersonating) won't fire. If your test asserts a Login listener, drive the real guard instead.
  • Organization argument is polymorphic. Models and org_... strings both work, but the resolved claim differs — assert on Authkit::currentOrganization()->id rather than the raw object when you care about shape.
  • Don't assert on fake Vault ciphertext. Crypto is visibly marked fake. Assert on plaintext round-trips, version counts, and ConflictException behavior; treat the ciphertext as opaque.
  • Transport switch has a testing cost. Setting AUTHKIT_HTTP_TRANSPORT=guzzle opts out of Laravel's HTTP client, which means Http::fake() and Http::assertSent() no longer see WorkOS calls. Only do this if you need Guzzle-specific behavior; the SDK's retry, error mapping, and JWKS caching are unchanged either way.
  • Managers are no longer final. That's a designed seam for the testing subclasses and is guarded by an arch test — but don't treat it as an invitation to extend VaultManager in app code. Prefer the fakes; subclassing ties you to internals.
  • workos/workos-php 9.2.0 changed the events poller signature. The package now passes the $events filter explicitly (empty = all types, same wire request). If you wrap or override the poller yourself, mirror that call or you'll break on the version bump.
  • Debugging checklist for a failing WorkOS test: (1) did you fake the manager the code actually calls? (2) is Http::preventStrayRequests() on? (3) with Http::fake(), dump Http::recorded() to confirm the request was even attempted — a LogicException or an empty sent-list usually means the guard short-circuited before any WorkOS call.
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.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
adachsoft/php-code-style