mikebronner/laravel-sign-in-with-apple
A Laravel package that adds Sign in with Apple authentication to your app. It handles Apple's token verification, user lookup and creation, and integrates cleanly with Laravel's existing auth scaffolding and Socialite-style flows.
Architecture fit. mikebronner/laravel-sign-in-with-apple is a focused, single-purpose Laravel package that wraps Apple's OAuth2/OIDC flow (authorize → token exchange → ID token validation → user provisioning). It sits cleanly alongside Laravel's native auth scaffolding and Socialite-style providers, so it fits the standard "Laravel monolith with an external identity provider" architecture without introducing a new service, queue, or datastore. The 13.0.0 release deepens that fit: auto-registered routes and controller (PR #66) reduce wiring code, and the built-in client_secret JWT generator (PR #68) removes a common external dependency (a manually generated, short-lived Apple client secret). Net: lower integration surface than 12.x, not higher.
Integration feasibility. High for any Laravel 12/13 app already on PHP 8.2+. The package is Composer-installable, config-driven, and does not require infrastructure changes. The main friction points are configuration, not code: the shortened config keys under services.apple (PR #64) mean an existing config/services.php must be edited, and the "update configuration to reflect current Apple Sign In requirements" change (PR #61) implies new/renamed keys that must be reconciled against the published config stub. Auto-registered routes (PR #66) are convenient but can collide with pre-existing custom callback routes — worth verifying route names and middleware before shipping.
Technical risk. Moderate, concentrated in three areas:
services.apple) and auto-registered routes are behavior changes, not additive ones. Silent misconfiguration (e.g. old keys left in place) will surface as opaque auth failures at runtime rather than at boot.form_post, so this fix is necessary, but it changes how the callback route is exempted/validated — needs verification that the exemption is scoped narrowly and does not weaken CSRF elsewhere.client_secret generation in-process (PR #68) is a security improvement (no long-lived static secret) but shifts key-handling responsibility onto the app: the .p8 private key, Team ID, Key ID, and Services ID must be managed as secrets, and the JWT's ~6-month max lifetime must be respected. Misconfigured keys now fail as invalid_client (PR #73) rather than a generic error — better, but still an operational dependency on Apple's credential model.Lower-risk but notable: single-maintainer concentration (nearly all PRs authored by @mikebronner), and a changelog that mixes genuine 13.0.0 work with what appears to be accumulated 12.x-era fixes — worth confirming the actual diff scope before assuming the version boundary is clean.
Key questions.
services.apple config keys, and is there a published upgrade guide or automated config migration?.p8 key expected to live, and does the package integrate with Laravel's config/env conventions for secret storage?first_name/last_name (PR #71), given Apple only returns these on first authorization?Stack fit. Native fit for a Laravel app using Blade/Inertia/Livewire or a Laravel API backend with a separate SPA/mobile client. No new runtime, no sidecar, no broker. If the product already uses Socialite for Google/Facebook, this package can coexist but is not a Socialite driver — expect a parallel auth path and, ideally, a thin internal abstraction so the app's user-provisioning logic is shared across providers rather than duplicated.
Migration path. Treat 13.0.0 as a planned migration, not a patch:
12.x on the current branch; create a migration branch for 13.0.0.config/services.php stub against the app's version; apply the services.apple rename and any new keys from PR #61.client_secret generation into the package; remove any external secret-generation cron/job and rotate the Apple key if the old secret was long-lived.invalid_client, missing authorization code, Apple token errors, Apple 5xx) to user-facing messaging.Compatibility. Laravel 13 and PHP 8.5 support are explicit (PRs #58, #59, #60). Confirm the app's minimum supported Laravel/PHP matrix — if any deployed environment is still on Laravel 10 or PHP 8.1, 13.0.0 is not adoptable there and the codebase would need a split-version strategy or a platform upgrade first. Also verify transitive dependencies (JWT library for PR #68, HTTP client) resolve cleanly under the app's lockfile.
Sequencing. Recommended order: (1) platform upgrades to Laravel 13 / PHP 8.5 in a non-prod environment; (2) config migration and route reconciliation; (3) exception handling and user-facing error states; (4) revocation endpoint and account-unlinking job; (5) first_name/last_name persistence, since these arrive only on first consent and must be captured then or lost; (6) staged rollout behind a feature flag with Apple Sandbox testing. Steps 1–3 are blocking; 4–5 can follow.
Maintenance. Low ongoing code maintenance — the package is small and config-driven. The real maintenance burden is credential lifecycle: Apple .p8 keys, Key IDs, Services IDs, and redirect URL registration in the Apple Developer portal. The new client_secret JWT generator removes a recurring manual rotation task but replaces it with a "your app must hold the private key correctly" obligation. Dependency freshness is good (Laravel 13 and PHP 8.5 landed promptly), which suggests an attentive maintainer, but the single-maintainer profile is a bus-factor risk worth noting in any long-horizon dependency review.
Support. Internal support load will concentrate on a small number of recurring, well-understood tickets: "Sign in with Apple button does nothing," "redirect URL mismatch" (now explicitly validated at PR #70, which converts a silent failure into a clear error), and "account not linked after re-install" (an Apple platform behavior, not a package bug — name/email are only provided on first authorization). Document these as known behaviors in the internal runbook to keep L1 support from escalating. The descriptive exceptions added across PRs #65, #72, #73, #75 materially reduce mean time to diagnose, which is the biggest support-cost win in this release.
Scaling. Effectively free at any realistic scale. Apple sign-in is a low-QPS, latency-tolerant path relative to core traffic; the package makes outbound HTTPS calls to Apple's token endpoint on callback only. The one scaling-adjacent consideration is the revocation webhook (PR #74): if implemented synchronously it puts Apple's delivery latency inside your request cycle, so it should be handled via a queued job regardless of volume. No caching, sharding, or horizontal-scaling concerns.
Failure modes. Ranked by likelihood × impact:
invalid_client on token exchange — expired/rotated key, wrong Team ID/Key ID/Services ID, or clock skew. Now surfaces as a descriptive exception (PR #73); highest-frequency real-world failure.Ramp-up. Low for a Laravel-fluent engineer: roughly half a day to read the package, publish config, and run a Sandbox sign-in end to end. Plan for an additional day for the parts that are Apple-specific rather than Laravel-specific — Apple Developer portal setup (Services ID, key generation, return URL registration), Sandbox account testing, and understanding the first-authorization-only semantics of first_name/last_name. The client_secret JWT generator and descriptive exceptions shorten ramp-up versus 12.x by eliminating the two most common sources of "it just doesn't work" confusion.
How can I help you explore Laravel packages today?