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

Passwd Laravel Package

graham-campbell/passwd

A Laravel password validator and generator that checks strength, requires letters, numbers, and symbols, rejects common or weak passwords, and generates secure random passwords via a simple, configurable service provider integration.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. graham-campbell/passwd is a deliberately thin manager over PHP's native password_hash/password_verify, split into hashers (produce a hash) and checkers (verify one, potentially in multiple legacy formats). It binds into Laravel's container via a service provider and exposes a Passwd facade, registered the 4.1 way in app/config/app.php. Architecturally it is sound and small — a few classes, one config file, one extension seam. The fit problem is not design, it is era: the package targets Laravel 4.1, depends on illuminate/* from that generation, and its last tag is v0.4.0-alpha. It fits an existing 4.1 application and essentially nothing else. The "framework-agnostic" claim in the description is aspirational — the shipped integration is Laravel-specific.

Integration feasibility. Technically feasible: PSR-4 autoloading, added unit tests, and a source surface you can read end-to-end in an afternoon make it auditable. The gate is a composer require "graham-campbell/passwd:0.4.0-alpha" --dry-run against a throwaway branch. If it conflicts with your illuminate/* constraint, the evaluation ends there — Laravel's own Hash facade already wraps the same primitives and you have lost nothing. Pin the exact tag; never a caret range on a pre-1.0 security-adjacent package.

Technical risk. High, and concentrated in provenance rather than code. The upstream lives under a GrahamDeprecated namespace with zero dependents and an alpha tag — meaning no CVE patches, no PHP-version compatibility fixes, no issue-tracker answers, and no external validation that anyone has run this in production. The API is not a contract; config keys and checker registration can move between tags. Build-time and platform hazards compound it: Argon2 availability depends on how PHP was compiled (defined('PASSWORD_ARGON2I') must be checked before it is set as default), and bcrypt silently truncates at 72 bytes.

Key questions for the decision owner.

  1. What capability gap does this close that Hash / password_* does not? If the answer is "none," stop.
  2. Is the requirement a persistent runtime dependency or a one-time legacy backfill script? The latter is the only genuinely differentiated use case and it can be deleted after the migration window.
  3. Who owns the fork, and what is the budget for patching it ourselves?
  4. What is the platform-retirement date for the 4.1 stack? This is the real roadmap item; the package is a distraction from it.
  5. Has security review signed off on default algorithm, cost parameters, and legacy fallback behavior?

Integration Approach

Stack fit. Assume Laravel 4.1 only. On any modern Laravel, use the Hash facade and close the ticket. The package's value is bounded to two scenarios: (a) an existing 4.1 app with a specific legacy hash format to verify, and (b) a migration script that must accept hashes from a legacy CMS or forum. Everything else is a worse-maintained substitute for a vendor primitive.

Migration path. Wrap it before you wire it. Define a single PasswordHasher interface with hash() and check(), bind one implementation in the container, and let the application depend on the interface, not the Passwd facade. This costs roughly twenty minutes and reduces the blast radius of abandonment to one class and one binding. Enforce the policy in one place — a CredentialService or model mutator — so cost factors and rehash rules live in a single file.

For the legacy case specifically, use verify-any, rehash-on-success: try the legacy checker, and on success rehash with the current hasher and persist, with the plaintext in memory only for that instant. Gate the legacy path behind a legacy_hash = 1 flag set at import time, so you are not running three checkers on every login for the whole user base. When the flag is cleared, delete the dead checker.

Where possible, convert this into a one-time backfill or account-claim-time script rather than a login-path dependency. That reframing removes the package from your production auth path entirely and is the strongest recommendation in this assessment.

Compatibility. Pin 0.4.0-alpha, commit composer.lock, and verify defined('PASSWORD_ARGON2I') before setting Argon2 as default — otherwise you discover the failure on the signup path. Watch the bcrypt 72-byte ceiling: either accept it explicitly, pre-hash (SHA-256 then bcrypt), or move to Argon2, and record the choice. Copy configuration idioms from the package README, not modern Laravel blog posts; 4.1 syntax differs in service-provider registration and container sugar.

Sequencing.

  1. Dry-run install in a throwaway branch; abort on conflict.
  2. Read src/ in full — manager, Hashers/, Checkers/, config, service provider — and confirm singleton bindings.
  3. Build the adapter, bind it, write one real round-trip integration test plus a deterministic stub for controller tests.
  4. Dual-run against a small cohort, or run as an import job, never both.
  5. Roll out behind the legacy flag; rehash on successful login.
  6. Retire the flag, delete the legacy checker, and — if the adapter holds — remove the dependency.
  7. Write the exit plan down now: swapping the adapter body to password_hash($plain, PASSWORD_BCRYPT, ['cost' => N]) and password_verify($plain, $hash). If you cannot articulate that in a paragraph, you are coupled harder than the package deserves.

Operational Impact

Maintenance. You own this, whether or not it is stated in a ticket. Archived upstream plus alpha tag plus security-adjacent scope means the maintenance plan is a fork plan: named owner, review cadence, and a documented patch process. Budget for it explicitly in the risk register rather than absorbing it silently into "engineering overhead."

Support. Zero. No maintainer answers, no community to consult, no upgrade guide. All operational knowledge is tribal and lives with whoever ran the spike. Mitigate with a short written runbook: what the config controls, how to change cost, how to add a checker, and how to leave.

Scaling. Hashing is CPU-bound. Under login bursts the failure mode is a saturated worker pool and a slow login queue — degradation, not a crash, which makes it easy to miss until it is a customer-visible incident. Benchmark Passwd::hash() against production-class hardware and target roughly 100–250 ms; resist the temptation to lower cost in response, which is a straight security downgrade. Capacity-plan the auth surface separately from general request throughput.

Failure modes to enumerate up front.

  • Argon2 constant undefined → runtime failure on signup, the worst possible place to discover it.
  • Hash-of-a-hash via a setPasswordAttribute mutator re-firing on an already-hashed value → the user who logged in today is locked out tomorrow. Verify before hash, and confirm the save path does not re-hash.
  • Hash comparison with == or hashes leaking into logs, exception traces, or toArray() API responses. Use check() (timing-safe), add password to $hidden on every model that carries one.
  • Alpha tag drift or a PHP upgrade breaking Composer resolution months later with no upstream fix.
  • Format-detection bugs from trying multiple checkers on the whole user base — mitigated by the per-user flag.

Ramp-up. The code surface is small enough for one engineer to review in an afternoon; the cost is not learning the package but learning the 4.1 idioms it lives in, which most current developers will not have touched. Onboarding overhead is therefore mostly the "why do we have this, and when do we remove it?" conversation — which is precisely why the adapter boundary and the written exit plan matter more than the library's feature list.

TPM bottom line. Treat this as a risk-register entry with a named decision owner, not a feature ticket. Approve it only for a bounded legacy verification or migration use case, pinned, wrapped, flagged, and scheduled for deletion. Decline it as the primary hasher on any revenue- or compliance-critical path; the vendor-maintained Hash facade covers that with no new risk.

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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core