genealabs/laravel-sign-in-with-apple
Add Sign In With Apple to your Laravel app. This package integrates Apple's OAuth flow with Laravel Socialite, handles the Apple developer configuration, and provides a ready-made button and controller. Requires PHP 8.2+, Laravel 10+, and an Apple Developer subscription.
Architecture fit. The package is an additive authentication provider layered on Laravel Socialite, not a framework-level change. It registers a sign-in-with-apple Socialite driver, ships a small controller pair (login callback, notification webhook), an event class, and a Blade directive. That is a narrow surface area — roughly one provider, two routes, one event, one support helper — which is exactly what you want in an auth dependency. It composes cleanly with an app that already uses Socialite for Google/Facebook, and it does not require you to adopt the optional geneaLabs/laravel-socialiter companion; that package is a convenience for user resolution/persistence, and you can substitute your own.
The most architecturally significant feature is ClientSecretGenerator: client-secret JWT generation moved from an external Ruby + jwt gem toolchain into PHP. For a TPM this is a genuine operational simplification — it removes a non-PHP runtime from your build/rotation pipeline and lets secret rotation live in a scheduled Artisan command alongside the rest of your Laravel ops. Treat it as the reason to prefer this package over hand-rolling the driver.
Integration feasibility. Code integration is a composer require, config publish, and three environment variables. The real cost is outside the codebase: Apple Developer portal work (App ID, Service ID, Return URL registration, private key generation, .well-known/apple-developer-domain-association.txt domain verification). That work is calendar-bound and access-controlled — it depends on who holds Account Holder/Admin roles in your Apple Developer org, and that is frequently the actual schedule risk.
Two feasibility details deserve attention. First, Apple posts the authorization response as form_post, so the callback must be a POST route with CSRF exemption; the package auto-excludes the configured callback, which removes a very common 419 failure but also creates an implicit coupling between package config and route naming that you should verify explicitly. Second, redirect URL requirements are strict (HTTPS, exact match, no query string, no fragment); the package validates and throws InvalidRedirectUrlException, which is good developer ergonomics but means any CDN, proxy, or trailing-slash discrepancy becomes a hard 100% login failure.
Technical risk.
sub may change. The package exposes is_returning_user to help, but the reconciliation logic (match by email on re-auth, link apple_id alongside email/password and other providers) is your design problem, not the package's.@privaterelay.appleid.com addresses break naive email dedup, verification-mail flows, and marketing sync.AppleAccessRevoked (consent-revoked, account-delete) is delivered, but deactivation/anonymization/deletion logic is yours — and App Store rules plus privacy regulation make that non-optional. The notification endpoint JWT verification (Apple's public keys, 1h cache) is implemented; the business response is not.Key questions.
users table?sub as a first-class identity attribute separate from email?Stack fit. Laravel 10–13, PHP 8.2+, Socialite 5+. Composer-only; no Node or Ruby runtime. A single package major (5.x) covers four Laravel majors, which eliminates the usual per-Laravel-version matrix juggling. Fits any app with a Blade view layer and a Socialite provider registry.
Migration path.
config/services.php; no changes to other providers.APPLE_LOGIN env var is removed and login routes must be declared in your route files; CSRF exclusion is now automatic. Audit VerifyCsrfToken::$except and any withoutMiddleware calls for stale or duplicated entries after upgrading.ClientSecretGenerator plus scheduled rotation, and validate a generated secret against Apple in staging before decommissioning the Ruby path.Compatibility. Watch Socialite 5 as the floor if you pin older. The package's own Dusk browser tests need Chrome, but that is only relevant if you run its suite locally — not a consumer dependency. Notification endpoint adds a new public unauthenticated POST surface; treat it as part of your WAF/rate-limit posture.
Sequencing.
.p8 private key; store in a secret manager, never in the repo.POST callback route and the notification route; verify CSRF behavior empirically, not by assumption.apple_id/sub, optional provider-identity table); define linking rules for pre-existing email accounts.AppleAccessRevoked listener (deactivate/anonymize/delete).is_returning_user), expired secret, wrong redirect URL, GET vs POST callback.Maintenance. Two clocks to manage: the package's own release cadence (releases through 2026 and support for Laravel 13 suggests active maintenance) and Apple's 180-day secret expiry, which is non-negotiable recurring work. Schedule rotation around day 150 with alerting on failure. Add private-key rotation policy and monitor Apple's key endpoint (cached 1h) as an external dependency. With 0 dependents and one maintainer, assume some self-patching.
Support. Most failures surface as recognizable signatures: 419 from CSRF/route mismatch, "missing authorization code" from a GET route, invalid client from an expired or malformed secret, invalid redirect from URL drift. The package's specific exceptions make triage tractable. Invest in structured logging around the callback — Apple's error responses are terse. Expect the bulk of support volume to come from identity edge cases (returning users without a name, relay emails, duplicate accounts), not from the package.
Scaling. SIWA volume is a small fraction of auth traffic; there is no meaningful scaling concern. The only new scaling surface is the notification endpoint, which must stay fast (JWT verify + cached keys) to avoid Apple retry behavior, and should be rate-limited at the edge.
Failure modes.
sub after revocation creates orphaned or duplicate accounts.Ramp-up. Developer ramp is low — one controller example, clear README, roughly 1–2 engineering days for the code. Calendar time for Apple portal setup and domain verification is typically longer than the code, and can be dominated by org-access friction. The higher-effort work is identity modeling and revocation business logic; that is backend/product effort, not package effort. Recommend a written runbook covering key custody, rotation schedule, portal ownership, and the QA checklist above before launch.
How can I help you explore Laravel packages today?