nette/security
Nette Security is a compact PHP library for authentication and authorization: secure password hashing (bcrypt/argon2), user identities and login, role and permission checks, and CSRF protection. It works standalone or as part of the Nette Framework.
nette/security gives you a complete, maintained implementation of three things we would otherwise hand-roll: identity lifecycle (User, SessionStorage, CookieStorage), pluggable authentication (Authenticator / IdentityHandler), and role/resource/permission authorization (Authorizator + ACL). For a greenfield PHP service without an opinionated framework, that is a genuine "buy" — it removes weeks of design and review from the critical path.nette/security is built around Nette's DI SecurityExtension and its own User/IAuthorizator contracts. Adopting it means running two identity models side by side or bypassing Gate entirely — a permanent tax on every engineer who touches authorization. Pick one; document which.Permission assertions) covers the admin-panel / multi-role / feature-gating tier well. It does not cover attribute-based or relationship-based authorization (per-record ownership, tenant hierarchies, policy-on-model) without building on top. That tells us what to put in v1 and what to defer.User::$persistIdentity (does an identity survive logout for personalization, or hard-null out?) and guest identities via getGuestIdentity() (do anonymous visitors carry their own roles and data?). Both are the kind of thing that shows up as "why does the header still show the user's name after they logged out?" in QA. Having a maintained implementation with a documented answer is worth more than it looks.SessionStorage no longer refreshes the sliding expiration once a session has already expired — is the kind of latent bug that fails an audit finding or a pen test. If we are building session handling ourselves, we now own finding and fixing that class of bug. That is a real cost to weigh against the integration cost.Consider adoption when:
SameSite handling, an explicit $persistIdentity policy, guest identities with real roles.#[\SensitiveParameter] applied to sensitive arguments, and a major-version cadence that keeps BC breaks contained and predictable (v3.2.0's removal of the deprecated IUserStorage is the shape of it — breaking changes arrive in majors, not patches).Look elsewhere when:
SecurityExtension is a Nette DI extension and does not run in Laravel's container. You would be hand-writing the entire adapter and then maintaining it across every Laravel upgrade. Stay on the native stack — Fortify/Sanctum/Breeze plus Gate and Policies — and spend the effort on policy design instead.SessionStorage and CookieStorage are the options; anything else is yours to build.Net PM recommendation for a Laravel roadmap: do not adopt as an auth layer. Optionally timebox a one-day spike on the ACL component alone (roles/resources/permissions with assertions) as a candidate permission engine behind Laravel's existing identity — and expect to conclude that Gate and Policies already cover it with less machinery.
For executives — if you are pitching adoption in a non-Laravel context: "We are choosing to buy our authentication and role-based access control rather than build it. That removes a multi-week block of security-sensitive custom code from the roadmap and replaces it with a component that is actively maintained, already supports current PHP versions, and has recently fixed a real session-expiry defect we would otherwise have shipped ourselves. The cost is adopting someone else's identity model; the benefit is that we do not own the security bugs in it. One item needs your help: the license string is unresolved and needs a legal sign-off before we commit."
For executives — if the question is Laravel: "We evaluated it and are recommending against it. It is a good component, but it is built for a different framework. Making it work in Laravel means writing and permanently maintaining an adapter, and running two identity systems where we currently run one. The security benefit over what we already have is close to zero; the ongoing engineering tax is not. We are keeping Laravel's native auth and investing the same effort in policy design, which is where our actual access-control risk sits."
For engineering: "It solves identity lifecycle and RBAC properly — pluggable authenticators, SessionStorage/CookieStorage, $persistIdentity so logout behavior is a setting rather than an accident, and guest identities that carry real roles instead of a magic string. It is PHPStan-clean with a mandatory static-analysis build, and it tracks new PHP releases fast. The catch is that it is Nette-native: the DI extension does not run in Laravel, and there is no middleware or Gate bridge, so integration is entirely ours to write and own. If we adopt it for a non-Laravel service, great. For the Laravel app, we are not doing it — and the honest reason is that the adapter, not the package, would be the liability."
For security and compliance: "Two things matter here. First, session expiry is handled correctly — an expired session stays expired instead of being silently kept alive, which is the exact behavior that makes audit trails unreliable. Second, permission checks are centralized in one authorizator rather than scattered across middleware and controllers, which makes access reviews tractable. The package also marks sensitive parameters with #[\SensitiveParameter] and enforces static analysis in its own build, which reduces the class of defect we care about. Our caveats: it is a component, not a hardened identity platform — no MFA, no federation, no session revocation across devices. And the license metadata is unresolved, so treat this as not approved for production until legal confirms it."
How can I help you explore Laravel packages today?