Getting Started
Start by confirming the stack fit — this is the first and most important step. korotovsky/sso-idp-bundle is a Symfony 2 bundle, not a Laravel package. There is no ServiceProvider, no facade, no config/*.php, and no extra.laravel autoload block. Running composer require korotovsky/sso-idp-bundle inside a Laravel 10/11 app will not bootstrap anything; the bundle class and DI Extension are loaded by Symfony's kernel, which Laravel never builds. Before writing a line of code, decide which of these you are actually doing:
- Evaluating it as a protocol reference (the realistic Laravel path). Clone the repo and read the source to enumerate the IdP surface area: AuthnRequest handling, metadata endpoint, assertion/response signing, certificate configuration, attribute mapping, and the SLO flow. This is the reusable artifact.
- Standing it up in its native environment (Symfony 2.8 / PHP 5.6) as a spike or isolated sidecar, if you genuinely must run it.
Where to look first in the repo:
- The bundle entry class (
*Bundle.php) — what it registers and how it expects to be wired.
- The
DependencyInjection/Extension — the config tree tells you every knob: certificates, user provider, attribute mapping, endpoints.
- Routing / controller endpoints — the login, metadata, and single-logout URLs are the actual contract with downstream service providers.
- Security configuration — how it hooks into Symfony's user provider and firewall.
First use case for a Laravel team: don't try to integrate — use it to answer "how much work is a real IdP?" Read the crypto and certificate handling, then scope your own build (or buy/deploy Keycloak). If a customer has asked whether your product can act as their identity provider, this repo is the evidence for whether the answer is "yes today" or "not without real build work."
Implementation Patterns
If you are on legacy Symfony 2 (the only environment it natively targets):
- Register the bundle in
AppKernel and wire the DI config for certificates, endpoints, and the user provider.
- Point the bundle at Symfony's security user provider; identity and attribute mapping flow through that.
- Publish the metadata endpoint to downstream SPs and hand them the signing certificate out-of-band.
- Use the SLO endpoint consistently — logout propagation is part of the contract, not an afterthought.
If you are on Laravel, the viable patterns are:
- Protocol reverse-engineering (recommended). Extract the endpoint list, message formats, signing scheme, session/ticket lifecycle, and logout semantics into a written spec. That document drives your estimate for a native implementation (Laravel Passport + OIDC layer, or a SAML IdP library).
- Sidecar service. Run the original bundle in an isolated Symfony 2.8 / PHP 5.6 container behind a reverse proxy, exposing only the auth endpoints, and call it over HTTP from Laravel. Only acceptable as a short bridge with a hard decommission date and OS-level patching.
- Fork-and-port. Extract protocol logic behind interfaces, reimplement the DI and HTTP layers with
Illuminate\Container/Illuminate\Http, wrap in a ServiceProvider. Highest control, highest cost — you inherit the security review.
Integration tips regardless of path:
- Treat the metadata endpoint and signing certificate as the interface — those are what downstream SPs actually consume.
- Keep attribute mapping explicit and tested; it's the thing that breaks onboarding for new SPs.
- If you go standard instead (the strong default), OIDC via Passport / Keycloak / a commercial IdP gives you the same customer-facing "we support SSO" answer without owning SAML maintenance.
Gotchas and Tips
- DI container mismatch is a hard stop, not a runtime bug. Symfony 2 XML/YAML service definitions cannot be loaded by Laravel's container. Expect
composer why-not to be your first debugging session — the 2.x pins on http-kernel, dependency-injection, and security-core conflict with the Symfony 6/7 components Laravel already ships.
- PHP 8 breakage is guaranteed, not incidental. Symfony 2 code routinely hits removed
each(), create_function, dynamic-property deprecation, and stricter type juggling. Any port is a rewrite, not a formality.
- The crypto is the risk. SSO IdPs mint bearer credentials; an unaudited ticket format, weak signature algorithm, missing replay protection, or non-constant-time comparison is an account-takeover primitive. There's no visible test suite or CVE history. Get a security review before anything touches a real login.
- Supply-chain signal: zero stars and zero dependents on an auth-path component means no upstream fixes. Every transitive Symfony 2 CVE becomes yours. Budget steady maintenance time for patching.
- Don't over-trust the source as "the spec." If there's no written protocol spec, the code is the protocol — which means any behavior you don't like is a compatibility hazard you have to preserve.
- Debugging the runtime (if you run it in a sidecar):
- Clock skew between IdP and SP causes intermittent validation failures that look like flakiness — check NTP first.
- Session/ticket store outages look like UI bugs but are infrastructure; users authenticate yet never complete the handshake.
- Logout propagation failing is silent and a recurring audit finding — test it explicitly.
- Key expiry/rotation mishandled takes down every downstream SP at once; keep key material in an HSM/secrets manager, not local files, and rehearse rotation.
- Extension points worth knowing: the pluggable user provider and attribute mapping are the intended seams — if you fork, those are the interfaces to preserve. Everything else (DI, HTTP, session) is what you rewrite.
- Bottom line for a Laravel developer: there is no day-to-day leverage here. Read it as a scope estimate and a protocol reference, then stand up a standard IdP (Keycloak self-hosted, or Okta/Auth0/Entra) and integrate over OIDC. That removes a whole class of auth security work from your roadmap.