presseportale/config/fortify.php
Kevin Adametz bae8347f6c security: Sicherheitsaudit 07.10.2026 (S-01–S-06) behoben, Passkeys und Zweitfaktor-Pflicht für Admins
Audit: dev/sicherheit/SICHERHEITSAUDIT-2026-10-07.md, Plan und Entscheidungen:
dev/sicherheit/ENTWICKLUNGSPLAN-SICHERHEIT-2026-10-07.md.

- S-01 Legacy-Rechnungen fremder Kunden nur mit billing:manage (auch Kundenroute).
- S-02 Kontaktzuordnung auf der Firmenanzeige verlangt companies:write, $id gesperrt.
- S-03 CompanyMembershipObserver: automatische Firmenrechte werden bei jeder
  Adress-/Zuordnungsänderung sofort neu bewertet; memberships:resync-auto.
- S-04 Passwortwechsel beendet alle anderen Sessions (PasswordChanger), Reset
  alle Sessions und offene Login-Links; Fortify PUT /user/password abgeschaltet.
  API-Tokens bleiben bestehen.
- S-05 Google: email_verified Pflicht, feste Bindung über die Provider-ID;
  Erstverknüpfung bestehender Konten außerhalb gmail/hd nur per Bestätigungslink
  in derselben Browser-Session.
- S-06 Frischer Identitätsnachweis (Passwort, App-Code, E-Mail-Code oder
  Passkey) vor E-Mail-Wechsel, erster 2FA-Einrichtung und Token-Erzeugung;
  Hinweis-Mails an die (bisherige) Kontoadresse.
- Entscheidung 5: Passkeys (Fortify, @laravel/passkeys) für alle; Super-Admins
  und Admins bestätigen die Session für den Admin-Bereich per Passkey oder
  App-Code (EnsureStrongAdminAuthentication, Notfallschalter
  AUTH_REQUIRE_STRONG_ADMIN); Reset des zweiten Faktors durch Super-Admins.

Neue Migration: create_passkeys_table. Suite 2.403 grün (1 übersprungen),
Larastan ohne Meldung.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 16:09:35 +00:00

195 lines
7.3 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
use App\Http\Middleware\BlockUnusedFortifyRoutes;
use App\Http\Middleware\EnsurePasskeyManagementIsConfirmed;
use Laravel\Fortify\Features;
return [
/*
|--------------------------------------------------------------------------
| Fortify Guard
|--------------------------------------------------------------------------
|
| Here you may specify which authentication guard Fortify will use while
| authenticating users. This value should correspond with one of your
| guards that is already present in your "auth" configuration file.
|
*/
'guard' => 'web',
/*
|--------------------------------------------------------------------------
| Fortify Password Broker
|--------------------------------------------------------------------------
|
| Here you may specify which password broker Fortify can use when a user
| is resetting their password. This configured value should match one
| of your password brokers setup in your "auth" configuration file.
|
*/
'passwords' => 'users',
/*
|--------------------------------------------------------------------------
| Username / Email
|--------------------------------------------------------------------------
|
| This value defines which model attribute should be considered as your
| application's "username" field. Typically, this might be the email
| address of the users but you are free to change this value here.
|
| Out of the box, Fortify expects forgot password and reset password
| requests to have a field named 'email'. If the application uses
| another name for the field you may define it below as needed.
|
*/
'username' => 'email',
'email' => 'email',
/*
|--------------------------------------------------------------------------
| Lowercase Usernames
|--------------------------------------------------------------------------
|
| This value defines whether usernames should be lowercased before saving
| them in the database, as some database system string fields are case
| sensitive. You may disable this for your application if necessary.
|
*/
'lowercase_usernames' => true,
/*
|--------------------------------------------------------------------------
| Home Path
|--------------------------------------------------------------------------
|
| Here you may configure the path where users will get redirected during
| authentication or password reset when the operations are successful
| and the user is authenticated. You are free to change this value.
|
*/
'home' => '/dashboard',
/*
|--------------------------------------------------------------------------
| Fortify Routes Prefix / Subdomain
|--------------------------------------------------------------------------
|
| Here you may specify which prefix Fortify will assign to all the routes
| that it registers with the application. If necessary, you may change
| subdomain under which all of the Fortify routes will be available.
|
*/
'prefix' => '',
'domain' => null,
/*
|--------------------------------------------------------------------------
| Fortify Routes Middleware
|--------------------------------------------------------------------------
|
| Here you may specify which middleware Fortify will assign to the routes
| that it registers with the application. If necessary, you may change
| these middleware but typically this provided default is preferred.
|
| BlockUnusedFortifyRoutes (Audit U09): die 2FA-Verwaltungsrouten von
| Fortify laufen nur mit Passwortbestätigung; das Projekt nutzt sie nicht
| und antwortet mit 404 – die Sicherheitsseite verlangt den zweiten Faktor.
|
*/
'middleware' => ['web', BlockUnusedFortifyRoutes::class, EnsurePasskeyManagementIsConfirmed::class],
/*
|--------------------------------------------------------------------------
| Rate Limiting
|--------------------------------------------------------------------------
|
| By default, Fortify will throttle logins to five requests per minute for
| every email and IP address combination. However, if you would like to
| specify a custom rate limiter to call then you may specify it here.
|
*/
'limiters' => [
'login' => 'login',
'two-factor' => 'two-factor',
'passkeys' => 'passkeys',
],
/*
|--------------------------------------------------------------------------
| Register View Routes
|--------------------------------------------------------------------------
|
| Here you may specify if the routes returning views should be disabled as
| you may not need them when building your own application. This may be
| especially true if you're writing a custom single-page application.
|
*/
'views' => false,
/*
|--------------------------------------------------------------------------
| Features
|--------------------------------------------------------------------------
|
| Some of the Fortify features are optional. You may disable the features
| by removing them from this array. You're free to only remove some of
| these features or you can even remove all of these if you need to.
|
*/
'features' => [
// Features::registration(), // Deaktiviert, da wir Volt verwenden
// Features::resetPasswords(), // Deaktiviert, da wir Volt verwenden
// Features::emailVerification(),
// updateProfileInformation() bewusst AUS (Audit F01): der Endpunkt
// tauschte die E-Mail sofort und ohne Verifizierung – Firmenrechte
// hängen an der Adresse. Die Kunden-UI nutzt den pending_email-Prozess.
// Features::updatePasswords(), // Abgeschaltet (Sicherheitsaudit 07.10.2026): Passwortwechsel nur über Livewire + PasswordChanger
Features::twoFactorAuthentication([
'confirm' => true,
'confirmPassword' => true,
// 'window' => 0,
]),
// Passkeys (Entscheidung 5, 07.10.2026). Den frischen Nachweis vor dem
// Hinzufügen verlangt EnsurePasskeyManagementIsConfirmed statt
// `password.confirm` — Letzteres setzt ein Passwort voraus, das
// Magic-Link- und Google-Konten nicht haben.
Features::passkeys([
'confirmPassword' => false,
]),
],
/*
|--------------------------------------------------------------------------
| Passkeys
|--------------------------------------------------------------------------
|
| Login und Sicherheitsseite laufen ausschließlich auf der Portal-Domain
| (routes/domains.php) — daran sind die Passkeys gebunden. Bewusst nicht
| APP_URL: die zeigt je nach Umgebung auf ein Web-Portal.
|
*/
'passkeys' => [
'relying_party_id' => env('PASSKEYS_RP_ID', env('APP_PORTAL_NAME', 'pressekonto.test')),
'allowed_origins' => [env('APP_PORTAL_URL', 'https://pressekonto.test')],
// Eigener Wert empfohlen: ein APP_KEY-Wechsel würde sonst die Kennungen
// ändern, unter denen die Geräte die Passkeys gespeichert haben.
'user_handle_secret' => env('PASSKEYS_USER_HANDLE_SECRET', env('APP_KEY')),
'timeout' => 60000,
],
];