Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Security Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • Framework mismatch is the headline. nette/security is a Nette Framework component: its wiring lives in SecurityExtension (a Nette DI compiler extension), its session persistence depends on nette/http (SessionStorage, CookieStorage), and its UI helper (UserPanel) targets the Tracy debug bar. None of that maps onto Laravel's container, middleware pipeline, or session guards.
  • Laravel already owns this problem space. Auth (Illuminate\Auth), gates/policies, Role-style ACL packages (Spatie Permission), and session drivers cover the same ground with first-class framework contracts. Adopting nette/security means maintaining a translation layer between two security models — high surface area for low marginal value.
  • What is genuinely reusable: the Authenticator/IdentityHandler/SimpleIdentity contracts, the Authorizator (ACL roles/resources/permissions) core, and the Passwords object. These are small, mostly framework-agnostic interfaces that could be wrapped as Laravel services, but doing so discards the package's DI conveniences — i.e., you pay the integration cost without the ergonomic payoff.
  • Net assessment: viable as a component, poor as a platform. If the goal is Laravel auth, this is the wrong tool. If the goal is a shared security ACL layer across a polyglot PHP estate (Nette + Laravel), a thin vendor-neutral ACL contract is defensible — but that is an architecture bet, not a package adoption.

Integration feasibility

  • No native adapter exists. Zero Laravel dependents on record means no community bridge, no Stack Overflow corpus, no reference implementations. Every integration decision is bespoke and owned by us.
  • Three concrete bridge points required:
    1. Session storage — implement Nette\Security\UserStorage backed by Laravel's Session/Auth session, and reconcile sliding-expiration semantics with Laravel's SESSION_LIFETIME / expire_on_close.
    2. Identity resolution — map IIdentity to/from Illuminate\Contracts\Auth\Authenticatable so Blade @auth, Gate::allows, and policy discovery don't fork into two truths.
    3. ACL evaluation — decide whether Authorizator becomes the system of record for permissions, or a secondary check beneath Laravel gates. Two permission engines is a compliance and debugging hazard.
  • Effort shape: the bridges are individually small (days each) but the reconciliation work — which layer wins on logout, expiry, guest roles, and cache invalidation — is where sprint estimates blow up. Budget 3–5 engineer-weeks for a production-grade spike, not a 3-day PoC.
  • Sequencing constraint: the package cannot be evaluated without first proving session-expiry semantics against Laravel's session middleware, because that's the package's main differentiated behaviour (v3.2.3/v3.2.4 fixes).

Technical risk

  • Two-sources-of-truth risk (high). Dual auth stacks produce divergent Auth::user(), stale identity caches (User::refreshStorage() exists precisely because caching bites), and permission checks that disagree. This is a security-review blocker, not a code-hygiene nit.
  • Licensing (medium). NOASSERTION on a security-critical dependency means legal has to hand-verify the Nette license (BSD-3-Clause in practice) before adoption. Non-trivial for enterprise procurement; trivially resolvable, but it blocks the critical path.
  • Bus factor / ecosystem depth (medium). 376 stars and a Nette-centric maintainer base means Laravel-specific breakage is ours to fix. Upstream will accept "compatibility with nette/http" fixes, not "compatibility with Laravel sessions."
  • Version velocity is a positive. Releases are current (2026-07-24), PHP 8.5 support, PHPStan enforced in CI, and v3.1.0 already paid down the I*-prefix debt. This is a maintained library, not abandoned — which makes the risk integration, not longevity.
  • BC-break history (low–medium). v3.0.1/v3.1.0/v3.2.0 each carried BC breaks (removed IUserStorage, Passwords static→object). Semver discipline is fine but majors move; our bridge layer must be pinned and regression-tested.
  • Guest identity semantics (low). v3.2.4's getGuestIdentity() is genuinely useful for anonymous-with-roles modelling, but must be explicitly reconciled with Laravel's guest handling or you get phantom roles on unauthenticated requests.

Key questions

  • What problem are we actually solving? If Laravel auth suffices, the answer is "don't adopt." The package only earns its place if we need a single ACL model shared with non-Laravel PHP services. Demand that answer before any engineering time is spent.
  • Who is the system of record for permissions? nette/security ACL, or Laravel gates/policies? Pick one; the other becomes a projection.
  • Is UserPanel/Tracy in scope? If not, we're importing debug-bar code we'll never run — factor that as dead weight in the dependency review.
  • What does the security team require for a second auth stack? Expect threat-model sign-off on session expiry, guest identity, and identity caching; this is a multi-week review, not a checkbox.
  • Does procurement accept NOASSERTION? Escalate immediately if adoption is serious — legal review is the longest-lead item and gates the whole plan.

Integration Approach

Stack fit

  • Target: Laravel 10+/11+ on PHP 8.1+ (v3.2.0 requires PHP 8.1; releases track PHP 8.5). Pin nette/security with a caret constraint and treat the bridge as a first-party package under our packages/ or a private Composer repo — do not patch vendor.
  • Shape the bridge as a Laravel service provider (NetteSecurityBridgeServiceProvider) that binds Nette\Security\User, Authenticator, Authorizator, and a custom UserStorage into the container. This keeps Nette's DI extension entirely out of the app — we never load SecurityExtension.
  • Reuse Laravel's session and hashing. UserStorage delegates to Illuminate\Session\Store; Passwords is replaced by Hash::make/Hash::check unless we need Argon2id parameter control the framework doesn't expose. Prefer framework primitives wherever the package is merely adequate.
  • Middleware, not Nette presenters. Wrap ACL checks in Gate definitions (Gate::define driven by Authorizator::isAllowed) so existing can: middleware, Blade directives, and policy discovery keep working unchanged.

Migration path

  • Do not migrate in place. Run the bridge behind a feature flag against a single low-risk surface (e.g., internal admin RBAC) with the existing Laravel auth flow untouched.
  • Strangler pattern: introduce Authorizator as a shadow evaluator — compute both Laravel gate and Nette ACL decisions, log disagreements, enforce nothing. This is the cheapest way to discover semantic gaps before they become incidents.
  • Identity cutover last. Keep Auth::user() as the source for identity; map into SimpleIdentity on read. Reverse the direction only if the estate-wide ACL requirement is confirmed.
  • Rollback is trivial only if we never dual-write sessions. Design the storage adapter so the flag flips both ways without invalidating live sessions — this is the one non-negotiable migration constraint.

Compatibility

  • Session-expiry semantics must be explicitly mapped. The package's strongest behaviour (v3.2.3/v3.2.4: expired identity stays expired, no silent sliding refresh) overlaps imperfectly with Laravel's SESSION_LIFETIME. Document the chosen behaviour in code and in the ops runbook; ambiguous expiry rules are an audit finding.
  • Guest identity: decide whether getGuestIdentity() or Laravel's guest middleware owns anonymous roles. Two answers = phantom permissions.
  • $persistIdentity: new in v3.2.4 and genuinely useful for personalisation-after-logout; align it deliberately with our data-retention and GDPR posture rather than accepting the default.
  • Test matrix: PHP 8.1–8.5 × Laravel 10/11/12 × session driver (file, Redis, database). Database-backed sessions are the package's weakest assumption and the most likely place procurement's "custom session storage" concern becomes real.

Sequencing

  1. Week 0 — Decision gate. Confirm the cross-framework ACL requirement with architecture; open the licence review in parallel. Kill criterion: if architecture says "Laravel-only," stop.
  2. Week 1–2 — Session adapter spike. Custom UserStorage, expiry-semantics test suite, no ACL work. This de-risks the dominant unknown.
  3. Week 3–4 — Shadow ACL. Authorizator alongside Gate, disagreement logging, one internal surface only.
  4. Week 5 — Identity mapping. IIdentity ↔ Authenticatable, guest identity decision, cache-invalidation tests.
  5. Week 6 — Hardening. Security review sign-off, PHPStan/Pint in CI for the bridge package, runbook.
  6. Post-GA — Evaluate re-evaluation point. Reassess at each Nette major; the bridge is a maintained asset with an owner, not a one-time task.

Operational Impact

Maintenance

  • The bridge is ours forever. Zero Laravel dependents means no upstream fixes, no CVE triage help, and no community answers. Assign a named owner and put the bridge in the same on-call rotation as core auth.
  • Dependency surface is modest but real: nette/security pulls nette/utils and nette/http (session/request abstractions we partly bypass anyway). Budget quarterly upgrades and track Nette majors for BC breaks (v3.x has already broken twice).
  • Static analysis is a gift. Upstream runs nette/phpstan-rules as a mandatory build step and ships improved phpDoc types; our bridge can inherit level 8+ cleanly. This is a genuine quality argument in favour of the package and worth citing in the ADR.

Support

  • No vendor support; no SLA. Escalation path is "read the Nette source" (which is small and readable — mitigate by having one engineer do a thorough read-through early).
  • Two security models means two knowledge domains. Any engineer debugging auth must understand Laravel's guard/AuthManager resolution and Nette's User/UserStorage/Authenticator triad. That's a real onboarding tax on a team otherwise fluent in Laravel.
  • Security-team review cost is recurring, not one-off: every bridge change touching expiry, guest identity, or persistence needs re-review against GDPR/SOC 2 expectations.

Scaling

  • Compute impact is negligible. ACL evaluation is in-process array/callback checks; no external calls, no network hop, no database read if identities are cached. User caches identity and auth state (v3.0.3) to avoid repeated storage calls — good for latency.
  • Horizontal scaling depends entirely on the adapter. Redis or database-backed UserStorage scales fine; the package's cookie storage is not a fit for multi-instance deployments. Enforce the session-driver matrix in CI.
  • Cache invalidation is the scaling failure point. User::refreshStorage() must be wired into role/permission mutations, or users retain stale privileges until session expiry — which, post-v3.2.3, may be longer than expected because expired sessions no longer slide.

Failure modes

  • Silent authorisation divergence — gate allows, ACL denies (or vice versa). Highest-severity mode; mitigate with the shadow-mode disagreement log and alerting on delta.
  • Stale privilege retention — role revoked in the ACL but cached in User identity. Mitigate with mandatory refreshStorage() on mutation plus an admin "force re-auth" control.
  • Session expiry regression — bridge mis-maps expiry and quietly reproduces the exact bug v3.2.3 fixed (expired sessions kept alive). Mitigate with an explicit expiry test suite running against every session driver.
  • Guest-identity leakage — anonymous request resolves to a role-carrying identity that outlives the request. Mitigate by asserting guest identity is read-only and never persisted (upstream guarantees read-only; our adapter must not write it).
  • Upstream major lands mid-quarter — pin, and gate upgrades behind the bridge regression suite rather than composer update in CI.
  • Licence/attribution drift — NOASSERTION means we must assert the licence text in our SBOM rather than trust the badge.

Ramp-up

  • 1–2 days for a Laravel-fluent engineer to grasp the Nette triad (User → UserStorage → Authenticator, plus Authorizator); the API surface is small and the docs are decent.
  • 1 week to be productive in the bridge, including the session-expiry semantics.
  • Ramp-up is not the risk — the two-model mental overhead is. Assume every future auth engineer pays this tax; factor it into team topology, not just the initial estimate.
  • Recommended ramp asset: a one-page internal ADR plus a decision table ("which layer owns identity / sessions / permissions") so the answer isn't rediscovered per engineer. That document is the highest-leverage deliverable of the integration, and the thing that makes this adoption defensible — or, if architecture says "Laravel-only," the artefact that justifies saying no.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
mydnic/volet-feature-board
wmde/fundraising-phpcs
friendlylabs/surveyr
mg-techlegend/laravel-notify-africa
islamabdurahman/laravel-sms-service
dmhendricks/b2-sdk-php
aplicativa/laravel-admin
ezavalishin/vkma
jackardios/laravel-json-api-paginate
viral/laravel-adminpanel
dieppk/log-viewer
daimakuai-ext/helpers
codexshaper/php-blade-view
abraxas81/charts
adamlien/laravel-cas
quimgc/tasks
sistem-atc/bank-sdk
core45/laravel-cookieconsent
projectsend/community-modules
ovac/laravel-hubtel-payment