PHPackages                             authn-sh/sdk-php-laravel - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. authn-sh/sdk-php-laravel

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

authn-sh/sdk-php-laravel
========================

Laravel package for authn.sh — service provider, middleware, Blade directives, facade. Wraps authn-sh/sdk-php for Laravel 11+.

v0.7.1(3w ago)07AGPL-3.0-onlyPHPPHP ^8.2CI passing

Since May 3Pushed 3w agoCompare

[ Source](https://github.com/authn-sh/sdk-php-laravel)[ Packagist](https://packagist.org/packages/authn-sh/sdk-php-laravel)[ Docs](https://authn.sh)[ RSS](/packages/authn-sh-sdk-php-laravel/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (11)Versions (11)Used By (0)

authn-sh/sdk-php-laravel
========================

[](#authn-shsdk-php-laravel)

Laravel package for [authn.sh](https://authn.sh) — auto-discovered service provider, container bindings, middleware, Blade directives, and an `Authn` facade. Wraps [`authn-sh/sdk-php`](https://github.com/authn-sh/sdk-php) for Laravel 11+.

Requirements
------------

[](#requirements)

- PHP **8.2+**
- Laravel **11+** (`^11.0 || ^12.0`)
- A PSR-18 HTTP client (Guzzle, Symfony HttpClient, etc.) — required by the underlying `authn-sh/sdk-php` SDK and auto-discovered via [`php-http/discovery`](https://docs.php-http.org/en/latest/discovery.html).

Install
-------

[](#install)

```
composer require authn-sh/sdk-php-laravel
```

The service provider auto-discovers. Publish the config:

```
php artisan vendor:publish --tag=authn-config
```

Middleware
----------

[](#middleware)

Register `authn` on routes that require a valid session JWT:

```
Route::middleware('authn')->group(function () {
    Route::get('/dashboard', DashboardController::class);
});
```

Blade directives
----------------

[](#blade-directives)

### `@authnSignedIn` / `@authnSignedOut`

[](#authnsignedin--authnsignedout)

```
@authnSignedIn
    Welcome back, {{ Authn::auth()->sub }}
@endauthnSignedIn

@authnSignedOut
    Sign in
@endauthnSignedOut
```

### `@authnHas`

[](#authnhas)

Evaluates organization roles and permissions from the active session JWT:

```
@authnHas('role:org:admin')
    Admin panel
@else
    You do not have admin access.
@endauthnHas

@authnHas('permission:org:billing:manage')
    Billing
@endauthnHas
```

The argument must be prefixed with `role:` or `permission:`. Any other prefix raises an `InvalidArgumentException` at render time so typos fail loudly.

### `@authnHasConnectedAccount`

[](#authnhasconnectedaccount)

Renders the inner block when the active session JWT advertises an `ExternalAccount` linked to the named OAuth provider:

```
@authnHasConnectedAccount('google')
    Connected to Google.
@else
    Connect Google
@endauthnHasConnectedAccount
```

The matching route middleware `authn.connected:` fail-closes by redirecting to `authn.connected_accounts.redirect_url` (the `{provider}` placeholder is substituted with the route argument):

```
Route::get('/integrations/google', [GoogleController::class, 'show'])
    ->middleware(['authn', 'authn.connected:google']);
```

### `@authnHasPasskey`

[](#authnhaspasskey)

Renders the inner block based on the active session's passkey signal. Two modes:

- `verified` (default) — matches when the current session was authenticated by a passkey first-factor (`VerifiedClaims::wasVerifiedByPasskey()`).
- `enrolled` — matches whenever the user has at least one verified passkey on file (`VerifiedClaims::hasPasskey()`).

```
@authnHasPasskey
    Manage API keys
@else
    This area requires a passkey sign-in.
@endauthnHasPasskey

@authnHasPasskey('enrolled')
    You already have a passkey on file.
@else
    Add your first passkey
@endauthnHasPasskey
```

The matching route middleware `authn.requires_passkey[:]` fail-closes by redirecting unauthenticated requests to `authn.url.sign_in` and signed-in-but-under-authenticated requests to `authn.passkey.enroll_url`:

```
Route::get('/account/security', [SecurityController::class, 'show'])
    ->middleware(['authn', 'authn.requires_passkey']);            // verified (default)

Route::get('/account/api-keys', [ApiKeyController::class, 'index'])
    ->middleware(['authn', 'authn.requires_passkey:verified']);

Route::get('/account/passkey-required-area', [Controller::class, 'show'])
    ->middleware(['authn', 'authn.requires_passkey:enrolled']);
```

The default mode is configurable via `authn.passkey.default_strict_mode` (env `AUTHN_PASSKEY_DEFAULT_STRICT_MODE`).

### `@authnHasEnterpriseAccount`

[](#authnhasenterpriseaccount)

Renders the inner block based on the active session's enterprise-SSO signal. Two modes for the no-argument form:

- `verified` (default) — matches when the current session was authenticated through an enterprise IdP (`VerifiedClaims->enterpriseConnectionId !== null`).
- `linked` — matches whenever the user has at least one linked `EnterpriseAccount`, whether or not the current session is enterprise-SSO.

```
@authnHasEnterpriseAccount
    You signed in via enterprise SSO.
@else
    Sign in with your organization
@endauthnHasEnterpriseAccount
```

With a connection-id argument, the directive matches when the active session's `enterpriseConnectionId` equals it OR when the user has a linked `EnterpriseAccount` for that connection:

```
@authnHasEnterpriseAccount('entcon_01HKX9SY9V7H7TF8C8K7J9X4ZA')
    Org admin
@endauthnHasEnterpriseAccount
```

The matching route middleware `authn.requires_enterprise_sso[:]` fail-closes by redirecting unauthenticated requests to `authn.url.sign_in` and signed-in-but-under-authenticated requests to `authn.enterprise_sso.redirect_url`:

```
Route::get('/workspace', [WorkspaceController::class, 'show'])
    ->middleware(['authn', 'authn.requires_enterprise_sso']);            // verified (default)

Route::get('/workspace/admin', [WorkspaceAdminController::class, 'show'])
    ->middleware(['authn', 'authn.requires_enterprise_sso:verified']);

Route::get('/workspace/profile', [ProfileController::class, 'show'])
    ->middleware(['authn', 'authn.requires_enterprise_sso:linked']);
```

The default mode is configurable via `authn.enterprise_sso.default_strict_mode` (env `AUTHN_ENTERPRISE_SSO_DEFAULT_STRICT_MODE`).

Facade methods
--------------

[](#facade-methods)

```
use Authn\Sdk\Laravel\Facades\Authn;

$claims = Authn::auth();              // ?VerifiedClaims — null outside an authn-authenticated request
Authn::hasRole('org:admin');          // bool
Authn::hasPermission('org:foo:bar');  // bool
Authn::hasPasskey();                  // bool — defaults to the configured strict mode ("verified")
Authn::hasPasskey('enrolled');        // bool — true when the user has any verified passkey
Authn::hasEnterpriseSso();            // bool — defaults to the configured strict mode ("verified")
Authn::hasEnterpriseSso('linked');    // bool — true when the user has any linked EnterpriseAccount
```

Development
-----------

[](#development)

```
composer install
composer test       # Pest + Orchestra Testbench
composer phpstan    # PHPStan + Larastan @ level 10
composer pint       # code style check
composer pint:fix   # apply fixes
```

CI runs the full suite on the **PHP 8.2 / 8.3 / 8.4 / 8.5 × Laravel 11 / 12** matrix.

License
-------

[](#license)

[AGPL-3.0-only](LICENSE).

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance94

Actively maintained with recent releases

Popularity6

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity42

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

8

Last Release

25d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/6453240?v=4)[Vagner Cavalcante](/maintainers/vagnercsouza)[@vagnercsouza](https://github.com/vagnercsouza)

---

Top Contributors

[![vagnercsouza](https://avatars.githubusercontent.com/u/6453240?v=4)](https://github.com/vagnercsouza "vagnercsouza (18 commits)")

---

Tags

laravelsdkAuthenticationidentityauthn

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/authn-sh-sdk-php-laravel/health.svg)

```
[![Health](https://phpackages.com/badges/authn-sh-sdk-php-laravel/health.svg)](https://phpackages.com/packages/authn-sh-sdk-php-laravel)
```

###  Alternatives

[propaganistas/laravel-disposable-email

Disposable email validator

6012.9M7](/packages/propaganistas-laravel-disposable-email)[psalm/plugin-laravel

Psalm plugin for Laravel

3325.1M337](/packages/psalm-plugin-laravel)[laravel/ai

The official AI SDK for Laravel.

9782.1M153](/packages/laravel-ai)[moonshine/moonshine

Laravel administration panel

1.3k239.9k72](/packages/moonshine-moonshine)[harris21/laravel-fuse

Circuit breaker for Laravel queue jobs. Protect your workers from cascading failures.

24740.3k](/packages/harris21-laravel-fuse)[auth0/login

Auth0 Laravel SDK. Straight-forward and tested methods for implementing authentication, and accessing Auth0's Management API endpoints.

2795.2M3](/packages/auth0-login)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
