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

Iam Bundle Laravel Package

gdbots/iam-bundle

Identity and access management bundle for Laravel/PHP apps, integrating the Gdbots IAM service for authentication, user accounts, roles, and permissions. Provides configurable guards, middleware, and service bindings to wire IAM into your application quickly.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check first: this is a Symfony bundle. There is no IamServiceProvider, no facade, no config/iam.php, and no config/bundles.php auto-discovery that Laravel will honor. Installing it in a Laravel app gives you the underlying IAM library plus Symfony DI/security contracts — the bundle wrapper itself is largely inert unless a Symfony kernel boots it. Plan your integration around the library, not the bundle.

v5.1.0 note before you install: the release is flagged __POSSIBLE BREAKING CHANGES__. It moves the bundle onto auth0/auth0-php 9.x and now hard-codes a Guzzle client because PSR-17/PSR-18 auto-discovery is disabled for security reasons. If you are already on 5.0.x, treat this as a dependency upgrade, not a patch — read the SDK's 8→9 upgrade notes alongside it.

Minimal steps:

composer require gdbots/iam-bundle:^5.1
composer why-not gdbots/iam-bundle   # check symfony/* AND auth0/auth0-php AND guzzle conflicts
composer show auth0/auth0-php guzzlehttp/guzzle guzzlehttp/psr7  # confirm resolved versions

Then read, in this order:

  1. vendor/gdbots/iam-bundle/src/DependencyInjection/Configuration.php — the authoritative config tree (service ids, storage backend, Auth0 domain/client credentials, role/permission sources). This is your real documentation; the README is thin.
  2. vendor/gdbots/iam-bundle/src/DependencyInjection/IamExtension.php — how services are constructed, which constructor args matter, and where the Guzzle client is instantiated (v5.1.0).
  3. The auth0/auth0-php 9.x SdkConfiguration / Auth0 factory — this is the object graph the bundle builds for you.
  4. vendor/gdbots/iam/src/ — the domain model (Iam, user/role/permission objects, the check method you'll actually call).

Bind the core service manually in app/Providers/IamServiceProvider.php:

public function register(): void
{
    $this->app->singleton(\Gdbots\Iam\Iam::class, function ($app) {
        return new \Gdbots\Iam\Iam(/* config array translated from config/iam.php */);
    });
}

First use case: read the authenticated principal's roles/permissions and gate a single route. Wrap the library check in a middleware or Gate::define, not in controllers — you want one choke point before you have ten.

Implementation Patterns

Pattern A — library-only integration (recommended). Skip the bundle entirely. Use the IAM classes (and the Auth0 SDK underneath them) directly and map them onto Laravel's auth stack. You keep Laravel's Auth, Gate, middleware, and testing idioms, and you avoid fighting two containers.

Pattern B — don't use this bundle just to reach Auth0. v5.1.0 confirms the bundle's job is wiring auth0/auth0-php. In Laravel you already have first-class options: auth0/login for the guard/flow, or the SDK standalone. Only take on this bundle if you specifically want its IAM/role abstraction layered on top.

Custom user provider + guard. Implement Illuminate\Contracts\Auth\UserProvider that resolves an IAM user id to an Authenticatable adapter. Keep the adapter thin — an id, roles(), permissions() — and let Laravel own session/remember-token concerns.

class IamUserProvider implements UserProvider {
    public function retrieveById($id) { return $this->iam->findUser($id)?->toLaravelUser(); }
    // ...
}

Gate/policy mapping. Define gates once at boot from the IAM permission namespace, or use a single wildcard gate:

Gate::before(fn ($user, $ability) => $user?->iam()->isGranted($ability) ? true : null);

Return null (not false) when IAM has no opinion so policies still get a chance to run.

Middleware for route protection. Route::middleware('iam:posts.publish') with a middleware that throws AuthorizationException. Keeps authorization declarative and greppable, and makes it trivial to audit which routes are protected.

Stateless APIs. For SPA/mobile, don't lean on Symfony's firewall/session assumptions. Resolve the principal from a bearer token in a middleware, attach it via Auth::setUser(), and keep IAM checks per-request. Console commands and queued jobs have no session — pass the acting principal explicitly as a job property, don't call Auth::user() inside the handler.

Caching. IAM decisions are usually a DB/HTTP round-trip — and in v5.1.0 they go out over Guzzle to the Auth0 Management API, so they are network round-trips, not local ones. Cache the permission set per user per request ($request->attributes) and a short-TTL cache (60–300s) across requests. Invalidate on role change via a model event or an explicit IamCache::forget($userId). Auth0 Management API rate limits are the practical ceiling here.

Testing. Bind a fake Iam in tests that returns a scripted permission set. Do not hit a real backend in feature tests. Because v5.1.0 hard-codes its Guzzle client (see Gotchas), you cannot swap the HTTP client through the container — stub at the Iam boundary you control, or push a Guzzle MockHandler onto a HandlerStack if you must exercise the SDK path.

Upgrading 5.0 → 5.1. Do it in a branch, not a patch release:

composer require auth0/auth0-php:^9.0 gdbots/iam-bundle:^5.1 -W
composer why-not auth0/auth0-php 8   # what's still pinned to the old major

Run your authorization feature tests against the new major, and diff the resolved auth0/auth0-php version before and after — the SDK's 9.x changes are where the breakage will surface, not in this package's thin wrapper.

If you must use the bundle: isolate it. Run a small Symfony service that boots the kernel and exposes an HTTP endpoint (/check, /user/{id}), and have Laravel call it. Trying to boot a Symfony bundle's DI inside a Laravel service provider works only for trivially-constructed services and breaks the moment the bundle touches security.*, parameter bags, or compiler passes.

Gotchas and Tips

  • v5.1.0 is marked as possible breaking. Do not treat it as a semver-safe patch. Pin exactly ("gdbots/iam-bundle": "5.1.0"), upgrade deliberately, and keep a lockfile you can revert. If the 8.x→9.x SDK jump is more than you want right now, staying on 5.0.x is a legitimate, defensible choice.
  • Guzzle is now a hard runtime dependency. v5.1.0 hard-codes a Guzzle client because PSR-17/PSR-18 auto-discovery is disabled. Consequences: guzzlehttp/guzzle and guzzlehttp/psr7 must be installed and resolvable; you cannot substitute Symfony HttpClient or Laravel's HTTP client; and a Guzzle major/minor conflict in your app becomes a blocker. Check with composer why-not guzzlehttp/guzzle ^7 before upgrading.
  • The HTTP client is not swappable through the container. Because the client is constructed inside the bundle rather than discovered, $this->app->bind(ClientInterface::class, ...) won't reach it. For tests, reach for Guzzle's MockHandler/HandlerStack; for production, don't plan on instrumenting the transport from Laravel. Add your own logging wrapper above the Iam service instead.
  • Don't "fix" the disabled auto-discovery. Turning PSR-17/PSR-18 discovery or http_discovery back on to get a nicer dependency graph reopens the supply-chain risk the maintainer deliberately closed off. Accept the hard-coded client.
  • Env placeholder syntax is incompatible. Symfony's %env(IAM_DSN)% and %iam.storage% are not resolved by Laravel's config(). Translate every placeholder in your own config/iam.php and pass a plain array into the library. Same applies to Auth0's env-driven SdkConfiguration — build it explicitly in a service provider.
  • Auth0 config names changed across SDK majors. The SdkConfiguration builder and its option keys are the usual casualty of an 8→9 bump. Anything you copied from an older tutorial (domain, client_id, client_secret, audience, management_token, cache/TTL options) needs verifying against 9.x, not assumed.
  • config/bundles.php is ignored. The bundle is never "registered"; anything the bundle does at boot (compiler passes, cache warmers, tagged services, event subscribers) simply won't happen. Don't assume bundle-provided services exist.
  • Symfony EventDispatcher ≠ Laravel's. If the bundle dispatches domain events, Laravel's dispatcher won't see them. Bridge by passing a PSR-14 adapter, or attach listeners at the library level.
  • Symfony version pinning. The bundle's symfony/* constraints can conflict with the versions Laravel locks. Run composer why-not before committing; a forced downgrade of symfony/http-foundation is a bad trade.
  • Chicken-and-egg on first admin. There's no Laravel seeder. You need a bootstrap path to create the initial user/role (a CLI script or an IAM_BOOTSTRAP env-gated command). Document it, or the first deploy stalls.
  • Backend provisioning is out of scope. The bundle wires the IAM service; it does not create your Auth0 tenant, APIs, roles, or permissions. Provision those declaratively (Auth0 Deploy CLI / Terraform) and run it in CI.
  • Stale permission caches across PHP-FPM workers. A role revocation that only clears one process's cache is a security bug. Prefer a shared cache store (Redis) with explicit invalidation over array/file caching.
  • No Symfony profiler. You lose the security panel that makes this bundle debuggable in Symfony. Add structured logging around the isGranted decision path (user, ability, result, auth0_request_id) early; you'll need it.
  • Extension points worth knowing: decorate the IAM service in the container (Laravel extend()), swap the user provider, and wrap isGranted in your own AuthorizationService so callers never bind to the package's types directly. That single indirection is what makes it replaceable later — and it's what will save you at the next auth0/auth0-php major.
  • Maturity risk. Zero stars, zero dependents, and a niche ecosystem, now with a hard-coded HTTP client and a major dependency bump shipped under a minor version number. Treat it as a reference implementation: pin an exact version, vendor or fork if you need a patch, and write your own integration tests around the behavior you depend on. The domain model is the valuable part; the Symfony bundle wrapper is the part you're least likely to use in Laravel.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager