PHPackages                             ronu/laravel-federated-auth - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. ronu/laravel-federated-auth

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

ronu/laravel-federated-auth
===========================

Configurable Laravel federated authentication bridge for social providers, OAuth2/OIDC providers and enterprise identity systems such as Keycloak.

v1.2.0(2w ago)110↓60%MITPHPPHP ^8.2CI failing

Since Jul 8Pushed 1mo agoCompare

[ Source](https://github.com/charlietyn/laravel-federated-auth)[ Packagist](https://packagist.org/packages/ronu/laravel-federated-auth)[ RSS](/packages/ronu-laravel-federated-auth/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (22)Versions (11)Used By (0)

Laravel Federated Auth
======================

[](#laravel-federated-auth)

 **Production-ready federated authentication bridge for Laravel 11/12, OAuth2, OpenID Connect, Socialite, Apple, Keycloak and custom multi-tenant user systems.**

 [![PHP 8.2+](https://camo.githubusercontent.com/29e32808c0574370fe15f62d642be470591731e10574291cf4e18b6083fadda5/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d253545382e322d3737374242343f7374796c653d666c61742d737175617265266c6f676f3d706870)](https://camo.githubusercontent.com/29e32808c0574370fe15f62d642be470591731e10574291cf4e18b6083fadda5/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d253545382e322d3737374242343f7374796c653d666c61742d737175617265266c6f676f3d706870) [![Laravel 11 or 12](https://camo.githubusercontent.com/6178f7cc5b52af55ea6f04c613b4dfe2654fee8ca77705e6345b827dfc6eb3c8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d313125323025374325323031322d4646324432303f7374796c653d666c61742d737175617265266c6f676f3d6c61726176656c)](https://camo.githubusercontent.com/6178f7cc5b52af55ea6f04c613b4dfe2654fee8ca77705e6345b827dfc6eb3c8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d313125323025374325323031322d4646324432303f7374796c653d666c61742d737175617265266c6f676f3d6c61726176656c) [![OAuth2 state hardened](https://camo.githubusercontent.com/dd84cd9dd4014a9fc7e96fa0caf4e2ec40c9586d4c9ca6311af0ec69eb83a54e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4f41757468322d737461746525323068617264656e65642d626c75653f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/dd84cd9dd4014a9fc7e96fa0caf4e2ec40c9586d4c9ca6311af0ec69eb83a54e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4f41757468322d737461746525323068617264656e65642d626c75653f7374796c653d666c61742d737175617265) [![OIDC nonce and PKCE](https://camo.githubusercontent.com/66fc6b12890d7ee0b39f90d3eb8ab1bc8cd8bf406bbc12ff2bfc665fb2cdf2fa/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4f4944432d6e6f6e6365253230253242253230504b43452d3041374541343f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/66fc6b12890d7ee0b39f90d3eb8ab1bc8cd8bf406bbc12ff2bfc665fb2cdf2fa/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4f4944432d6e6f6e6365253230253242253230504b43452d3041374541343f7374796c653d666c61742d737175617265) [![MIT License](https://camo.githubusercontent.com/422db9fd40f5831c765cf6530b6750c081b696bd18d904cf89554df98c676277/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e3f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/422db9fd40f5831c765cf6530b6750c081b696bd18d904cf89554df98c676277/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e3f7374796c653d666c61742d737175617265)

---

Overview
--------

[](#overview)

`ronu/laravel-federated-auth` is a **contract-first Laravel package** for integrating external identity providers into real Laravel applications without forcing a specific user model, database schema, guard, token system or tenancy strategy.

It is designed for applications where social login is not enough:

- custom `users` tables;
- UUID or non-standard primary keys;
- multi-tenant identity links;
- `Client`, `Admin`, `Veterinarian`, `Technician` or other user types;
- JWT/API guards instead of session auth;
- custom role and permission systems;
- Keycloak or enterprise OIDC;
- native/mobile clients sending `id_token` directly;
- Apple private relay emails;
- secure redirect flows with package-managed `state`, plus OIDC `nonce` and PKCE where the adapter controls the code flow.

---

Supported providers
-------------------

[](#supported-providers)

ProviderFlow supportNotesGoogleRedirect + tokenSocialite adapter with package-managed one-time `state`.FacebookRedirect + tokenSocialite adapter with package-managed one-time `state`; email verification trust is opt-in.AppleRedirect + native `id_token`Dedicated OIDC-style adapter with Apple client secret JWT, nonce and PKCE for code flow.KeycloakRedirect + tokenEnterprise OIDC with roles/groups, nonce and PKCE for code flow.Generic OIDCRedirect + tokenAuth0, Azure AD, Okta or custom OIDC providers with nonce and PKCE for code flow.---

Architecture
------------

[](#architecture)

```
Provider
   ↓
Provider Adapter
   ↓
ExternalIdentity DTO
   ↓
UserResolver / UserProvisioner
   ↓
IdentityLinkRepository
   ↓
RoleMapper
   ↓
TokenIssuer
   ↓
AuthResult / AuthResponseFormatter

```

The provider proves **external identity**. Your Laravel application owns the local user, tenant scope, roles, account status, local token and response format.

---

Sequence diagrams
-----------------

[](#sequence-diagrams)

The following diagrams trace the full request pipeline end to end, from the HTTP entry point through `FederatedAuthBroker` and the extension contracts down to the JSON response.

Both use the **browser redirect flow**. The **native / mobile token flow** (`POST /{provider}/token` → `loginFromToken()`) skips the redirect and state-consumption phases (steps 1–2) and enters the broker at `authenticateIdentity()` — every step from `validateIdentity()` onwards is identical.

### Login — returning user (existing identity)

[](#login--returning-user-existing-identity)

An external identity that is already linked to a local user. The broker resolves the user, enforces account status, touches the link and issues a local token. No user is created (`was_provisioned=false`, `was_linked=false`).

[![Federated login sequence diagram: browser redirect, one-time state consumption, identity resolution and local token issuance](docs/diagrams/federated-login-sequence.svg)](docs/diagrams/federated-login-sequence.svg)

### Registration — first-time user (auto-provision)

[](#registration--first-time-user-auto-provision)

No linked identity exists. After the security validations, the broker optionally matches by verified email, then provisions a new local user (only when `auto_provision` is enabled), creates the identity link and issues a token (`was_provisioned=true`, `was_linked=true`).

[![Federated registration sequence diagram: callback, optional verified-email match, user provisioning, identity linking and token issuance](docs/diagrams/federated-register-sequence.svg)](docs/diagrams/federated-register-sequence.svg)

> Diagrams are generated as standalone SVGs under [`docs/diagrams`](docs/diagrams).

---

Installation
------------

[](#installation)

```
composer require ronu/laravel-federated-auth

php artisan vendor:publish --tag=federated-auth-config

# Run ONLY this package's migration, isolated from your app's migrations:
php artisan federated-auth:migrate
```

`federated-auth:migrate` runs the package's identity-store migration from inside the package (via `--path`) without triggering any pending host-app migrations. Supported flags: `--rollback`, `--refresh`, `--status`, `--database=`, `--force`, `--pretend`.

Prefer to manage the schema yourself? Publish the migration into your app and run the standard `migrate` instead:

```
php artisan vendor:publish --tag=federated-auth-migrations
php artisan migrate
```

Optional documentation publish:

```
php artisan vendor:publish --tag=federated-auth-docs
```

---

Requirements
------------

[](#requirements)

DependencyVersionPHP`^8.2`Laravel / Illuminate`^11.0` or `^12.0`Laravel Socialite`^5.15`Guzzle`^7.8`firebase/php-jwt`^6.10`---

Quick configuration
-------------------

[](#quick-configuration)

```
FEDERATED_AUTH_ENABLED=true
FEDERATED_AUTH_ROUTES_ENABLED=true
FEDERATED_AUTH_ROUTES_PREFIX=api/auth/federated

FEDERATED_AUTH_GOOGLE_ENABLED=true
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GOOGLE_REDIRECT_URI=https://api.example.com/api/auth/federated/google/callback

FEDERATED_AUTH_APPLE_ENABLED=true
APPLE_CLIENT_ID=com.example.web
APPLE_TEAM_ID=TEAMID1234
APPLE_KEY_ID=ABC123DEFG
APPLE_PRIVATE_KEY_PATH=/secure/path/AuthKey_ABC123DEFG.p8
APPLE_REDIRECT_URI=https://api.example.com/api/auth/federated/apple/callback

FEDERATED_AUTH_KEYCLOAK_ENABLED=true
KEYCLOAK_BASE_URL=https://auth.example.com
KEYCLOAK_REALM=my-realm
KEYCLOAK_CLIENT_ID=my-api-client
KEYCLOAK_CLIENT_SECRET=secret
KEYCLOAK_REDIRECT_URI=https://api.example.com/api/auth/federated/keycloak/callback
```

---

Routes
------

[](#routes)

MethodURIPurpose`GET``/api/auth/federated/providers`List configured providers.`GET``/api/auth/federated/{provider}/redirect`Start browser redirect login.`GET/POST``/api/auth/federated/{provider}/callback`Handle provider callback.`POST``/api/auth/federated/{provider}/token`Native/mobile token login.`POST``/api/auth/federated/{provider}/link/token`Link provider identity to authenticated user.`DELETE``/api/auth/federated/{provider}/unlink`Unlink provider identity.---

Browser redirect flow
---------------------

[](#browser-redirect-flow)

```
GET /api/auth/federated/google/redirect?tenant_id=clinic-1&user_type=Client&channel=web
        ↓
Create one-time OAuthAuthorizationState
        ↓
Redirect to provider
        ↓
Callback returns code + state
        ↓
Consume state once
        ↓
Restore tenant_id, user_type, channel, guard and redirect_uri
        ↓
Normalize ExternalIdentity
        ↓
Resolve or provision local user
        ↓
Create/touch identity link
        ↓
Issue local API token

```

Provider callbacks usually return only `code` and `state`. The package restores the original application context from the consumed state before resolving or creating a provider identity link.

**Important security scope:** Socialite-backed redirect providers such as Google and Facebook get package-managed one-time `state` validation. OIDC `nonce` validation and PKCE are applied by OIDC-style adapters that control the code flow, such as Apple, Keycloak and generic OIDC providers.

---

Native / mobile token flow
--------------------------

[](#native--mobile-token-flow)

Mobile clients can authenticate using the provider SDK and send the provider token to Laravel.

```
POST /api/auth/federated/keycloak/token
Content-Type: application/json

{
  "id_token": "provider-id-token",
  "tenant_id": "clinic-1",
  "user_type": "Client",
  "channel": "mobile"
}
```

```
POST /api/auth/federated/keycloak/token
Content-Type: application/json

{
  "access_token": "provider-access-token",
  "tenant_id": "clinic-1",
  "user_type": "Client",
  "channel": "mobile"
}
```

OIDC token handling is explicit:

Submitted fieldBehavior`id_token`Decode and validate as an OIDC ID token.`access_token`Call `userinfo_endpoint` when configured.unknownJWT-looking values are treated as ID tokens.---

Response example
----------------

[](#response-example)

```
{
  "success": true,
  "was_provisioned": false,
  "was_linked": false,
  "user": {
    "id": 25,
    "uuid": "4d78f4fb-70ef-45ef-b98a-d143d39464a3",
    "email": "client@example.com",
    "user_type": "Client",
    "auth_identifier": 25
  },
  "access_token": "local-jwt-token",
  "token_type": "bearer",
  "expires_in": 3600,
  "metadata": []
}
```

The response is configurable through `AuthResponseFormatterInterface`, so you can expose only safe user fields.

---

Security posture
----------------

[](#security-posture)

The package is secure-by-design for redirect and token flows, with provider-specific coverage:

- all package-managed redirect flows can use one-time OAuth `state`;
- all package-managed redirect flows can reject replay through state consumption;
- all package-managed redirect flows can use optional user-agent/IP fingerprint binding;
- Apple, Keycloak and generic OIDC code flows can use OIDC `nonce` validation;
- Apple, Keycloak and generic OIDC code flows can use PKCE;
- redirect host validation protects dynamic redirect URIs;
- tenant-aware callback context restoration prevents callback logins from losing tenant scope;
- native/mobile OIDC token flows preserve explicit `id_token` vs `access_token` handling;
- provider tokens are not stored by default;
- public social providers should not auto-provision privileged users.

Recommended production settings:

```
FEDERATED_AUTH_OAUTH_STATE_ENABLED=true
FEDERATED_AUTH_OAUTH_STATE_TTL_SECONDS=300
FEDERATED_AUTH_OAUTH_STATE_BIND_USER_AGENT=true
FEDERATED_AUTH_PKCE_ENABLED=true
FEDERATED_AUTH_OIDC_NONCE_ENABLED=true
FEDERATED_AUTH_ALLOWED_REDIRECT_HOSTS=api.example.com,app.example.com
FEDERATED_AUTH_ALLOW_HTTP_LOCALHOST_REDIRECTS=false
```

`FEDERATED_AUTH_PKCE_ENABLED` and `FEDERATED_AUTH_OIDC_NONCE_ENABLED` affect OIDC-style adapters that control the code flow. Socialite-backed providers such as Google and Facebook still receive package-managed `state`, but package-level nonce/PKCE is not applied there unless a dedicated adapter controls that provider flow.

---

Identity link model
-------------------

[](#identity-link-model)

The package links external identities to local users using this conceptual key:

```
tenant_id + provider + provider_user_id → local_user_id

```

Do not use email as the federated identity key. Apple can return private relay emails and some providers may return missing or unverified emails.

---

Extension contracts
-------------------

[](#extension-contracts)

ContractResponsibility`UserResolverInterface`Find local users.`UserProvisionerInterface`Create local users when allowed.`IdentityLinkRepositoryInterface`Store provider identity links.`TokenIssuerInterface`Issue local tokens.`RoleMapperInterface`Sync local roles from provider claims.`UserStatusCheckerInterface`Block disabled users.`OAuthStateStoreInterface`Store and consume OAuth state.`AuthResponseFormatterInterface`Format API responses.`PermissionPayloadResolverInterface`Append optional permission payloads.---

Optional `ronu/rest-generic-class` integration
----------------------------------------------

[](#optional-ronurest-generic-class-integration)

The package can integrate with `ronu/rest-generic-class` without depending on it directly.

```
composer require ronu/rest-generic-class
```

```
FEDERATED_AUTH_RESPONSE_INCLUDE_PERMISSIONS=true
FEDERATED_AUTH_RGC_ENABLED=true
```

This enables an `ok/data/meta` response shape and optional effective permissions in login responses.

---

Provider recommendations
------------------------

[](#provider-recommendations)

ProviderRecommended useGoogleClient login with verified email and package-managed state.FacebookPublic login with package-managed state; do not trust email verification unless explicitly configured.AppleNative/mobile or web login; use `sub` as identity key, not email.KeycloakEnterprise login, nonce/PKCE-capable code flow and controlled role/group mapping.Generic OIDCAuth0, Azure AD, Okta or custom identity servers with OIDC nonce/PKCE support.---

Documentation
-------------

[](#documentation)

Full documentation lives in [`docs`](docs).

Recommended starting points:

- [`docs/00-simple-guide.md`](docs/00-simple-guide.md)
- [`docs/03-core-architecture.md`](docs/03-core-architecture.md)
- [`docs/08-security-and-edge-cases.md`](docs/08-security-and-edge-cases.md)
- [`docs/12-oauth-hardening.md`](docs/12-oauth-hardening.md)
- [`docs/13-apple-provider.md`](docs/13-apple-provider.md)
- [`docs/14-rest-generic-class-integration.md`](docs/14-rest-generic-class-integration.md)
- [`docs/15-guide-integration.md`](docs/15-guide-integration.md)

---

Testing
-------

[](#testing)

```
composer install
vendor/bin/phpunit
vendor/bin/pint --test
```

---

Production checklist
--------------------

[](#production-checklist)

- Configure allowed redirect hosts.
- Keep OAuth state enabled.
- Keep OIDC nonce enabled for OIDC-style providers that control the code flow.
- Keep PKCE enabled for OIDC-style providers that control the code flow.
- Do not assume Socialite-backed Google/Facebook redirects have package-level nonce/PKCE unless using a dedicated adapter.
- Do not trust Facebook email verification unless intentionally configured.
- Do not auto-provision privileged users from public social providers.
- Confirm tenant scoping in `IdentityLinkRepository`.
- Confirm token issuer uses the expected guard.
- Confirm provider tokens are not stored unless needed.
- Run PHPUnit and Pint before release.

---

Philosophy
----------

[](#philosophy)

```
External providers authenticate identity.
Your Laravel application owns authorization.

```

That separation keeps the package flexible enough for startups, SaaS products, enterprise systems and modular Laravel platforms.

---

License
-------

[](#license)

The MIT License (MIT). Please see [`LICENSE.md`](LICENSE.md) for more information.

###  Health Score

43

—

FairBetter than 89% of packages

Maintenance95

Actively maintained with recent releases

Popularity9

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~5 days

Total

8

Last Release

14d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/0f59437a00cb4187df5eeb376f1c72053def2a2b16227a1e70d0c48ab2c99a4e?d=identicon)[charlietyn](/maintainers/charlietyn)

---

Top Contributors

[![charlietyn](https://avatars.githubusercontent.com/u/10063918?v=4)](https://github.com/charlietyn "charlietyn (152 commits)")

---

Tags

laravelsocialiteoauth2OpenID Connectkeycloakoidcfederated-authidentity-broker

###  Code Quality

TestsPHPUnit

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/ronu-laravel-federated-auth/health.svg)

```
[![Health](https://phpackages.com/badges/ronu-laravel-federated-auth/health.svg)](https://phpackages.com/packages/ronu-laravel-federated-auth)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.4M354](/packages/psalm-plugin-laravel)[api-platform/laravel

API Platform support for Laravel

58190.1k21](/packages/api-platform-laravel)[laravel/socialite

Laravel wrapper around OAuth 1 &amp; OAuth 2 libraries.

5.7k113.1M1.0k](/packages/laravel-socialite)[fleetbase/core-api

Core Framework and Resources for Fleetbase API

1239.7k25](/packages/fleetbase-core-api)[laravel/cashier

Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.

2.5k31.8M163](/packages/laravel-cashier)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

80427.1M249](/packages/laravel-mcp)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
