---
title: "Installation — Auth for Laravel | Roundly"
description: "Install via Composer, generate the JWT keys, run the installer, wire the jwt guard and user provider, prepare the model and run the doctor."
url: https://roundly-consulting.com/open-source/docs/auth-for-laravel/installation
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Auth for Laravel](https://roundly-consulting.com/open-source/docs/auth-for-laravel.md)

# Installation

Require the package, generate the RSA key pair for jwt-for-laravel, run the installer and migrate. The service provider is auto-discovered:

```bash
composer require roundly-consulting/auth-for-laravel
php artisan jwt:generate-keys
php artisan authentication:install
php artisan migrate
```

authentication:install publishes the package config and migrations together with the migrations of refresh-tokens-for-laravel, two-factor-for-laravel and passkeys-for-laravel, then prints the wiring below. It never edits your config files.

## Publish tags

| Tag | Publishes |
| --- | --- |
| `authentication-config` | `config/authentication.php` |
| `authentication-migrations` | The four auth\_\* tables plus a stub that adds the account columns and passkey\_user\_handle to the default guard’s table. |
| `authentication-translations` | lang/vendor/authentication/{en,sk} — error messages, validation and notification copy, shipped in English and Slovak. |

Migrations are publish-only — the package never loads them, so publish (or run the installer) before you migrate.

## Wire the guard

Each guard needs a jwt guard with its own audience and the authentication user provider in config/auth.php:

```php
// config/auth.php
'guards' => [
    'users'   => ['driver' => 'jwt', 'provider' => 'users',   'audience' => env('JWT_USERS_AUDIENCE', 'app-users')],
    'clients' => ['driver' => 'jwt', 'provider' => 'clients', 'audience' => env('JWT_CLIENTS_AUDIENCE', 'app-clients')],
],
'providers' => [
    'users'   => ['driver' => 'authentication', 'guard' => 'users'],
    'clients' => ['driver' => 'authentication', 'guard' => 'clients'],
],
```

In config/jwt.php, make every jwt guard use the token-version resolver — without it, invalidation revokes nothing:

```php
// config/jwt.php
'guard' => [
    'token_version' => \RoundlyConsulting\Auth\Support\TokenVersionResolver::class,
    // …
],
```

## Prepare the model

The guard model implements the contracts of the features the guard uses:

```php
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use RoundlyConsulting\Auth\Concerns\HasAuthentication;
use RoundlyConsulting\Auth\Contracts\Account;
use RoundlyConsulting\Passkeys\Concerns\InteractsWithPasskeys;
use RoundlyConsulting\Passkeys\Contracts\HasPasskeys;
use RoundlyConsulting\RefreshTokens\Traits\HasRefreshTokens;
use RoundlyConsulting\TwoFactor\Concerns\HasTwoFactorAuthentication;
use RoundlyConsulting\TwoFactor\Contracts\TwoFactorAuthenticatable;

class User extends Authenticatable implements Account, HasPasskeys, TwoFactorAuthenticatable
{
    use HasAuthentication, HasRefreshTokens, HasTwoFactorAuthentication, InteractsWithPasskeys, Notifiable;

    protected function casts(): array
    {
        return [...$this->authenticationCasts(), ...$this->twoFactorCasts(), 'email_verified_at' => 'datetime'];
    }
}
```

The published stub adds the authentication columns and the passkey user handle (passkey\_user\_handle, skipped when the table already has it) to the default guard’s table; two-factor’s own stub (two-factor-migrations) adds the TOTP columns, so a fresh install passes authentication:check. Every other guard table calls $table->authenticationColumns() (plus $table->twoFactorColumns() and $table->passkeyUserHandle() when those features are on) — php artisan authentication:guard clients scaffolds the model, migration and factory for you.

## Run the doctor

```bash
php artisan authentication:check
```

The doctor checks every config rule, the provider wiring, the required columns, the JWT keys, the access-token revoker, mail and routes, and exits with code 1 on any error.

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/auth-for-laravel.md)
