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

Email Guard Core Laravel Package

emailsherlock/email-guard-core

PHP guard for signup and checkout email fields: offline checks catch bad syntax, reserved TLDs, and 73k+ disposable domains with no network calls. Add an EmailSherlock API key for live MX, SMTP, role and catch-all detection. PHP 8.1+.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

emailsherlock/email-guard-core is a deliberately thin, framework-agnostic library: a single EmailGuard entry point returning a Result object with an action enum (Allow / Deny / Review) plus a reasons collection. That shape is the right one for a Laravel codebase — it is pure PHP with no HTTP kernel coupling, no global state, and no framework dependency, so it can be bound as a container singleton and invoked from a FormRequest, a custom validation rule, a controller, or a queued job without architectural compromise.

The local-first / API-escalation split is the strongest architectural property. Default behavior is deterministic, offline, and zero-latency (syntax, reserved TLDs, 73k+ bundled disposable domains). Escalation to the Verify API is opt-in via api_key and is policy-driven (block_on, review_on). That means the package can be adopted without a vendor contract, without a network dependency on the hot path of signup, and without a data-processing agreement in place on day one — which materially lowers the approval cost of a trial.

The Allow / Deny / Review triad is also a better fit for real product surfaces than a boolean. Review maps cleanly to a hold-for-confirmation state (catch-all domains, role accounts) rather than forcing a binary reject decision into the validation layer.

Integration feasibility

Composer-installable, MIT licensed, PHP 8.1+. No Laravel service provider or facade is published, so integration means writing a small first-party wrapper: a config/email-guard.php, a provider that binds EmailGuard with config-derived options, and a Rule object that maps Deny to a validation failure and Review to a flagged attribute. That is roughly half a day of work for a mid-level engineer and is genuinely low-risk because the surface area is one method.

The real feasibility question is not "can we wire it up" but "do we want to own the wiring." The README states the Symfony bundle and WordPress plugin build on this library, which means the maintainer intends the core to be the stable substrate and framework adapters to be separate artifacts. A Laravel adapter may therefore appear upstream later — worth asking, because writing our own now creates a small migration liability if an official adapter lands with a different config schema.

Technical risk

Risk Severity Notes
Maturity signals High 0 stars, 0 dependents, single maintainer. No community validation of the code or the API contract.
Release provenance High Last release dated 2026-06-19 — a future date. Either a clock/metadata error or a pre-dated tag. Treat as unverified until the tag, commit SHA, and Packagist entry are reconciled.
Bus factor High Single-vendor, effectively single-person. No evidence of a contributing cohort.
Bundled snapshot staleness Medium The 73k disposable-domain list is only as good as its refresh cadence. Disposable domains rotate fast; a stale snapshot silently degrades to allow.
Policy misconfiguration Medium Aggressive block_on (catch-all, role) will reject legitimate corporate and shared-inbox signups. This is a product-conversion risk, not just a technical one.
PII egress Medium Escalation sends the email address to a third party. Requires DPA/privacy review and a documented lawful basis before enabling in EU-facing flows.
Supply chain Medium Unknown transitive dependency tree. A zero-star package with a small maintainer base is a plausible typosquat/compromise target — pin by SHA and review the dependency graph.
Test coverage Unknown No CI or coverage badge in the excerpt. Assume unverified until inspected.

Maturity caveats worth stating plainly to stakeholders: the package advertises readme, changelog, releases as its maturity level, which is the floor of credible packaging, not evidence of production hardening. Score of ~13.9 with opportunity at ~56 suggests a package with a real problem thesis but no adoption. Recommend it be evaluated as a candidate, not a commitment.

Key questions

  1. Is there an official Laravel adapter planned, and what is its config schema? If yes, defer the wrapper.
  2. What is the actual snapshot refresh process and cadence — shipped in releases, or fetched at runtime? If runtime, that reintroduces a network dependency we assumed we didn't have.
  3. What is the SemVer discipline? Is ^0.x safe, or do we need exact pins?
  4. What is the Verify API's published latency, rate limit, uptime SLA, and pricing model per call?
  5. Where is the email address transmitted and retained on escalation? Is there a DPA and a zero-retention option?
  6. What is the observable behavior on API failure — fail-open (allow) or fail-closed (deny)? Is it configurable, and what is the default?
  7. Is there a reproducible benchmark for local-only check cost at our signup volume?
  8. What is the maintainer's continuity plan — is there any indication of a second committer or a funding/sponsorship model?

Integration Approach

Stack fit

Laravel surface Fit Notes
Custom validation Rule Excellent Deny → fail with reasons; Review → pass + flash/flag.
FormRequest Excellent Drop-in via the rule.
Service provider binding Good Trivial; ~20 lines.
config/email-guard.php Good Keep api_key in env, never in config cache output.
Queued job (async escalation) Good Review decisions can be resolved post-signup without blocking the request cycle.
Event / listener Good Emit EmailDenied / EmailHeldForReview for analytics and abuse dashboards.
Laravel Nova / Filament admin Neutral Manual — render reasons on the user record.

The package does not attempt to own persistence or the user model. That is correct for a Laravel integration: store the action and reasons on the user or a side table, not inside the library.

Migration path

Adopt in three gates, each reversible:

  1. Shadow mode (1–2 weeks). Run the guard on every signup, log the decision, enforce nothing. Compare Deny decisions against actual downstream behavior (did the account verify email? did it convert? did it chargeback?). This produces the false-positive evidence needed to justify a policy, and it costs nothing because local checks are offline.
  2. Enforce local-only. Turn on syntax/reserved-TLD/disposable enforcement. This is the lowest-controversy tier — a syntactically invalid or .invalid address is not a lost customer. Measure signup completion delta.
  3. Enable API escalation with Review on catch-all. Add the API key behind a feature flag, scoped to a percentage of traffic. Review rather than Deny for catch-all preserves conversion while collecting signal.

Do not run gates 2 and 3 simultaneously. Attribution becomes impossible.

Compatibility

  • Confirm the PHP constraint against the target app's actual runtime, and against the Laravel version matrix in use. PHP 8.1 is the likely floor; verify the package does not require 8.2+ syntax despite the README.
  • Verify autoload compatibility (PSR-4) and that the bundled snapshot ships as a package asset reachable via __DIR__, not a path relative to the vendor root (a classic break under optimized autoloaders or when the package is symlinked in local development).
  • Check behaviour under config:cache and route:cache — configuration must be read at boot, not at call time.
  • Confirm the package does not register its own error/exception handlers.

Sequencing

  1. Spike: install in a scratch branch, run the full corpus of existing production emails through shadow mode, and produce a confusion-matrix report (how many real customers would have been denied).
  2. Security/privacy review: dependency tree, tag provenance, PII egress, DPA status.
  3. Write the wrapper (provider + config + rule + event) and cover it with tests that stub the guard so CI never calls the network.
  4. Ship shadow mode to production behind a flag.
  5. Promote to enforcement tier-by-tier with a kill switch (a single config boolean that forces Allow).
  6. Re-evaluate at 90 days: if the upstream project has not gained maintainers or a Laravel adapter, fork the wrapper internally and pin hard.

Operational Impact

Maintenance

The recurring cost is not the code — it is the snapshot. The disposable-domain list is the package's core value and its core liability: it decays continuously and the refresh mechanism is undocumented in the excerpt. Budget a quarterly review to confirm the pinned version has a recent snapshot, and treat "snapshot older than 90 days" as a maintenance ticket. Composer pinning should be exact or tightly bounded until SemVer discipline is confirmed; a ^0.x range on a zero-adoption package is an uncontrolled upgrade path on your signup form.

We also own the wrapper, which means we own the config schema, the validation rule, the event contract, and the tests. That is a small but permanent surface — roughly a day per quarter of upkeep, plus the migration cost if an official Laravel adapter later lands with a different shape.

Support

There is no support contract for the library. Self-hosted local checks are fully within our control and diagnosable from source; the escalation path is not. The Verify API's SLA, status page, and incident communication are unknown and must be established before gate 3. Internally, define a single owner (backend platform, not the signup team) so that a policy change has one approver.

Support load will be dominated by false-positive complaints — "your site won't let me sign up with my work email" — routed through customer support with no visibility into why. Mitigation: log action and reasons to an internal-only admin field, and give support a documented override. Without this, the guard becomes a support-cost center rather than a fraud reduction.

Scaling

Local-only mode scales for free: it is an in-memory set lookup against a bundled snapshot, no I/O, no shared state, safe to invoke per-request and safe to fan out across any number of PHP-FPM workers. Memory overhead is the snapshot itself — measure it; a 73k-entry list is small but non-zero per worker under a large FPM pool, and it is loaded per process.

API escalation is the only scaling constraint. It converts a sub-millisecond validation into a network round trip on the signup critical path, subject to third-party rate limits and latency. Three mitigations, in order of preference: (a) restrict escalation to addresses that pass local checks and are not obviously free-mail, reducing call volume substantially; (b) cache decisions keyed by a hash of the normalized address, with a TTL long enough to absorb retries but short enough to catch new disposables; (c) move escalation off the request path entirely — accept, then verify asynchronously and flag the account, which is what the Review action was designed for.

Failure modes

Failure Effect if unhandled Mitigation
Verify API timeout Signup latency spike or exception on the hot path Hard timeout (~1s), fail-open to local result only, circuit breaker
API 429 / quota exhausted Silent degradation or hard failures Quota alerts at 70%, fall back to local-only, never hard-fail signup
Invalid/expired API key Same as above, but persistent and quiet Startup health check; alert on elevated escalation error rate
Snapshot file missing or unreadable Local checks silently pass everything Fail loudly at boot — this is a configuration error, not a runtime one
Stale snapshot Disposable signups leak through; no signal Track deny-rate trend; alert on a sustained drop
Over-aggressive policy Legitimate customers rejected at signup Shadow-mode calibration, Review over Deny for catch-all, support override
Malformed/oversized email input Package exception, 500 on a public form Validate length/encoding before invoking; wrap in try/catch
Vendor abandonment No snapshot updates, no security patches Fork-and-vendor contingency; the local-check logic is small enough to reimplement in ~200 lines if needed

The most important operational property: no failure mode of this package should ever prevent a legitimate customer from signing up. Everything above is expressible as a single rule — degrade to Allow when uncertain — and that rule should be written into the config defaults, not left to per-call-site discipline.

Ramp-up

Low, but not zero. A backend engineer unfamiliar with the package needs roughly half a day to read the source, wire the provider, write the rule, and cover it with tests; the API is one method and one result object. The larger ramp-up cost is organizational rather than technical:

  • Product/trust needs to agree the deny policy and own the false-positive tradeoff. This is a conversion decision, not an engineering one.
  • Legal/privacy needs to clear PII egress before escalation is enabled — allow 1–2 weeks and do not sequence it last.
  • Support needs the override runbook and admin visibility before enforcement, not after the first complaint.
  • Data/analytics needs the shadow-mode comparison to make the go/no-go call credible.

Realistic timeline from approval to full enforcement: three to five weeks, of which engineering is under one. Plan and staff accordingly — the gating work is policy and privacy, and the technical integration is the fast part.

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.
andydefer/laravel-notification
adachsoft/cli-process-tester
jhaskell13/laraflow
sebastienheyd/boilerplate-media-manager
ccast/tagixo-primix
pretendtrue/laravel-builder
sawmainek/laravel-scout-tntsearch-driver
tomshaw/laravel-calendar-table
dibakar/laravel-ownership
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo
stevenay/myanfont
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc