tapp/filament-authentication-log
A Filament plugin for Laravel Authentication Log that adds a resource and relation manager for browsing user authentication logs. Requires rappasoft/laravel-authentication-log with the AuthenticationLoggable and Notifiable traits on your User model. Supports Filament 4.x/5.x.
This plugin is a thin Filament UI layer over rappasoft/laravel-authentication-log. It ships no models and no migrations — it only gives you a Resource (global log list) and a Relation Manager (per-user log tab). So the install is really "install the dependency, then the UI".
authentication_logs table), then add both traits to the model(s) you want tracked:use Rappasoft\LaravelAuthenticationLog\Traits\AuthenticationLoggable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use AuthenticationLoggable, Notifiable; // Notifiable is required for new-device notifications
}
composer require defaults. Filament 4.x/5.x on Laravel 12 with auth-log 5.x/6.x → plugin ^5.0. Filament 3 → plugin 3.x or 4.x depending on auth-log version. Getting this wrong is the single most common install failure.composer require tapp/filament-authentication-log:"^5.0"
app/Providers/Filament/AdminPanelProvider.php):->plugins([
FilamentAuthenticationLogPlugin::make(),
])
UserResource so support staff can answer "was that login you?" without leaving the user record.use Tapp\FilamentAuthenticationLog\RelationManagers\AuthenticationLogsRelationManager;
public static function getRelations(): array
{
return [
AuthenticationLogsRelationManager::class,
];
}
That tab shows login/logout timestamps, IP, user agent, and device, newest first. If you want a cross-user security dashboard instead (e.g. spotting brute-force attempts), the sidebar Resource added by the plugin covers that for free.
Where to look first when something is off: the published config (config/filament-authentication-log.php), then the underlying authentication_logs table. Nine times out of ten the UI is fine and the row data (morph type, guard, login_successful) is what's wrong.
Resource-only vs. relation-manager-only vs. both. These are independent; use them deliberately.
Multi-panel setups. The plugin's auto-detection of "which panel's UserResource do I link to?" gets confused when you have Admin and Developer panels. Two knobs:
FilamentAuthenticationLogPlugin::make()
->panelName('admin'), // scope the resource to a specific panel
and, for link generation, explicitly pin the resource:
// config/filament-authentication-log.php
'user-resource' => \App\Filament\Resources\YourCustomUserResource::class,
Use panelName() when the resource should only appear in one panel; use user-resource when the links point at the wrong place. They solve different problems and you may need both.
Make the authenticatable column human-readable. By default the table shows the model class name. Point it at a real column:
'authenticatable' => [
'field-to-display' => 'name',
],
If the column doesn't exist (common with first_name/last_name splits), add an accessor rather than a DB migration:
public function getNameAttribute(): string
{
return trim("{$this->first_name} {$this->last_name}");
}
Deep-link to the right page. Default target is the edit page. If your user resource is read-only, switch to view (requires that page to actually be registered on the resource):
'authenticatable' => [
'resource-page' => 'view',
],
Customize the Resource without forking. The plugin's resource is intentionally minimal; if you need extra columns or actions, don't copy it — register a Filament policy against the underlying model to control who sees what, and lean on the config for the parts it exposes. Fork only if you need to change the query itself.
Operational pattern for the Resource. Use it as a triage board: filter by login_successful = false + a date range to catch credential-stuffing, filter by guard when you have separate web/admin guards, and sort descending on login time. This is far cheaper than building your own audit table.
Translations. The package ships it, de, pt_BR, ar, zh and more. Publish only if you need to override strings:
php artisan vendor:publish --tag="filament-authentication-log-translations"
php artisan vendor:publish --tag="filament-authentication-log-config"
No migrations ship with this package. If you see an empty table or a Base table or view not found error, you skipped the dependency's publish step. Don't go hunting in this repo's database/ folder — there isn't one.
Notifiable is not optional. Without it, the new-device login notification path throws. The README lists both traits; developers routinely add only AuthenticationLoggable and then wonder why logins silently fail to notify.
Morph maps break the user column and links. If you call Relation::enforceMorphMap(), authenticatable_type stores your alias (e.g. user) rather than the FQCN. The plugin's class-name-to-resource resolution and user-resource fallback can then misbehave. Test one login with the morph map enabled before trusting the UI.
Relation manager tab is empty but the Resource has rows. Almost always one of: the trait is missing on that model, the rows belong to a different morph type, or you're looking at a user whose logs are under a different guard. Check the raw table before touching config.
resource-page => 'view' on a resource without a ViewUser page produces a broken link (or a 404 in a new tab). Filament won't validate this for you.
Version pinning matters more than usual here. Three packages must align (Filament, Laravel, laravel-authentication-log). Also note that 5.0.6 dropped PHP 8.2 support — if your CI still runs 8.2 you'll get a resolution failure that looks unrelated to this package.
Fix-floor for older branches. If you're stuck on the 3.x line, pin at >=3.1.3: earlier patches had broken lazy loading and default sort order in the relation manager. Same for default table sorting (fixed in 3.1.2).
Logs grow forever. The plugin exposes no delete/prune UI by design (audit tables shouldn't be mutable in the panel). Schedule your own retention job against authentication_logs — e.g. prune rows older than 90 days — or the table becomes your largest one within a year.
Restricting access. The Resource is registered globally; use a policy on the auth-log model to gate it, and prefer the relation manager for roles that should only see logs for users they can already edit. Don't rely on hiding the nav item as your access control.
Debugging checklist when the sidebar entry is missing: plugin not in plugins(); panelName() doesn't match the panel's actual ID string; navigation disabled via config; or the current user fails the resource's authorization. In that order.
Extension points worth knowing: panelName(), authenticatable.field-to-display, authenticatable.resource-page, user-resource, plus the published translations and config. That's the supported surface — anything beyond it means subclassing the resource or relation manager, and you'll own that diff on every major bump.
How can I help you explore Laravel packages today?