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

Laravel Keycloak Guard Laravel Package

robsontenorio/laravel-keycloak-guard

Laravel Keycloak Guard provides a Keycloak authentication guard for Laravel, validating JWT access tokens and exposing roles and permissions. It integrates with Laravel's native auth system, making it easy to protect routes and APIs with Keycloak-issued tokens.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Package: robsontenorio/laravel-keycloak-guard — a Laravel auth guard that validates Keycloak-issued JWTs and resolves the corresponding local user.

Architecture fit: The package integrates at the framework's native extension point (Auth::extend / guard contract), so it sits alongside Eloquent and session guards rather than replacing them. It is most viable for applications already treating Keycloak as the system of record for identity, where Laravel owns authorization and domain data. For stateless APIs it operates as a bearer-token guard; for session-based apps it typically pairs with a web guard plus token refresh. This is a reasonable fit for a Laravel monolith or a small service fleet sharing one realm, and a weaker fit where per-tenant realms or non-Keycloak IdPs are expected.

Integration feasibility: Low-to-moderate effort. Composer install, publish config, register the guard and user provider, set realm/base URL/client credentials via env, and confirm claim-to-attribute mapping. The real work is not installation but agreeing the identity contract: which claim becomes the local user key, how first-login provisioning behaves, and how roles from the token map to Laravel gates/policies.

Technical risk: The dominant risks are identity-key correctness, token validation strictness, and signing-key lifecycle. Release 2.0.1 addresses the first directly: the guard's id() now supports string identifiers, which is the correct behavior for UUID subjects — Keycloak's sub claim is a UUID string, and Laravel has defaulted to UUID/ULID keys in recent versions. Prior to this patch, teams using UUID primary keys or relying on the token subject as the identifier faced a type-mismatch class of defect that typically manifests as failed user resolution or silent mis-association rather than a clean error, making it easy to miss in test suites that use integer fixtures. Residual risks remain around JWKS retrieval and caching under key rotation, clock skew and leeway on expiry, audience/issuer validation, and role-claim shape (realm vs. client roles, nested vs. flat). None of these are introduced or worsened by 2.0.1.

Key questions:

  • Does the guard validate iss, aud, and exp strictly, and is there configurable leeway for clock skew?
  • How are JWKS cached, and what is the refresh behavior on an unknown kid after a Keycloak key rotation?
  • Does the 2.0.1 change alter the return type or contract of id() in a way that affects code casting or comparing identifiers?
  • What is the expected behavior when a valid token has no corresponding local user — provision, reject, or defer to a registration flow?
  • Is there a supported path for multiple realms/tenants, or is one guard instance bound to one realm?
  • What is the maintainer bandwidth and release cadence, and is the package covered by any advisory process?

Integration Approach

Stack fit: Targets modern Laravel (PHP 8.x, Laravel 9+) and any reasonably current Keycloak. It composes cleanly with Laravel's middleware, policies, and gates, and does not require forking the auth stack. Teams already using Socialite-based Keycloak login should note this guard is a complementary, token-validation path rather than a replacement for the OAuth redirect flow.

Migration path: Treat 2.0.1 as a drop-in patch from 2.0.0 — the changelog indicates a single fix with no deprecations or configuration surface changes. The one group that must actively migrate is anyone who worked around the UUID limitation (for example, by casting the subject to an integer, storing the subject in a side column, or overriding id() locally). Those workarounds should be retired in favor of the native string identifier to avoid divergent identity resolution.

Compatibility: Verify three things in the target codebase: (1) the local user model's primary key type matches the claim used as the identifier, (2) any code assuming an integer Auth::id() — logging, route binding, cache keys, foreign keys — tolerates a string, and (3) test fixtures use UUID-shaped subjects rather than integer ones, since integer fixtures are precisely what masked this defect.

Sequencing:

  1. Pin 2.0.1 in composer.json and run the existing auth test suite.
  2. Replace integer-subject fixtures with realistic Keycloak tokens (UUID sub, real realm/client role claims) in an integration test.
  3. Exercise the full login path against a staging realm: token issue → guard validation → user resolution/provisioning → role-to-policy mapping.
  4. Audit downstream consumers of the authenticated identifier for integer assumptions.
  5. Remove any local overrides or casts that existed to compensate for the pre-2.0.1 behavior.
  6. Promote to production behind normal release controls; no coordinated Keycloak change is required.

Operational Impact

Maintenance: The package is community-maintained with a small contributor base; 2.0.1 includes a first-time contributor. Patch releases appear to be narrow and targeted, which is healthy, but the maintenance risk profile is that of a single-maintainer dependency. Budget for the possibility of upstream drift and keep the guard behind a thin internal adapter so it can be swapped or pinned without touching application code.

Support: Support comes from GitHub issues rather than a commercial channel. For teams with strict incident SLAs, identify an internal owner for the auth integration and consider maintaining a small fork policy. Security advisories for the package and for the underlying JWT library should be watched as part of routine dependency review.

Scaling: The guard is stateless per request — validation is CPU-bound signature verification plus the JWKS lookup, which should be cached. Horizontal scaling is straightforward provided the JWKS cache is shared or cheaply rebuildable per instance; without caching, each request risks a network hop to Keycloak, which becomes the bottleneck under load. User resolution hits the database on the hot path, so ensure the identifier column is indexed.

Failure modes: (1) Keycloak unavailability — new logins fail; existing sessions/tokens may still validate until expiry, depending on cache state. (2) Signing-key rotation with a stale JWKS cache — valid tokens rejected until refresh. (3) Clock skew between app hosts and IdP — spurious expiry rejections. (4) Identifier type mismatch — the pre-2.0.1 failure mode, now addressed, but still latent wherever local casts or workarounds persist. (5) Role-claim shape changes in Keycloak (realm vs. client roles) — silent authorization failures where a user authenticates but loses permissions. (6) Misconfigured realm or audience — the guard rejects all tokens, which is a safe failure but a total outage for the auth path.

Ramp-up: Low for any developer comfortable with Laravel auth internals; the conceptual load is mostly Keycloak-side (realms, clients, claim shapes) rather than PHP-side. Allocate roughly a day for a developer new to the integration to reach productive debugging, and ensure onboarding documentation captures the identifier contract, the JWKS caching behavior, and the claim-to-role mapping, since these are the areas where tribal knowledge tends to accumulate.

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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums