surfnet/stepup-saml-bundle
Symfony bundle for adding SAML 2.0 authentication to SURFnet Step-up applications, with configuration and integration for SURFconext and federation single sign-on via the Stepup gateway.
Architecture fit — the core caveat first. This is a Symfony bundle, not a Laravel package, and the distinction is not cosmetic. Laravel consumes Symfony components (HttpFoundation, Routing, Console, VarDumper) but deliberately does not implement the Symfony bundle mechanism: no Bundle registration, no DependencyInjection\Extension, no Configuration tree, no services.yaml container compilation pass, no Kernel::registerBundles(). The package's value-add over simplesamlphp/saml2 is precisely that wiring — DI service definitions, a config tree mapping saml.yaml keys to the SP/IdP objects, route/controller wiring for the metadata and Assertion Consumer Service (ACS) endpoints, and integration with the Symfony Security firewall via a guard/authenticator. None of that glue is portable to Laravel. What is portable is the substrate: simplesamlphp/saml2 is a framework-agnostic PHP library implementing SAML 2.0 profiles, XML-DSig validation, and metadata parsing. So the honest architectural read is: this repo is a reference implementation of the glue you would need to write, plus a maintained dependency tree you can inherit.
Integration feasibility. Two credible paths, with very different risk profiles:
simplesamlphp/saml2 directly). Reimplement ACS endpoint, metadata endpoint, AuthnRequest builder, SP/IdP config object mapping, cert handling, attribute extraction. Realistically 400–900 LOC plus tests for a single-IdP SP. This is tractable — the repo is a useful blueprint — but it puts XML signature validation, replay protection, and clock-skew handling in your team's hands, which is exactly where SAML integrations historically go wrong.Technical risk. Material, and concentrated in three places. (1) Vendor concentration: 14 stars, 0 dependents, and an intimate coupling to the OpenConext/Stepup product family (stepup-gateway, stepup-selfservice). This bundle is maintained as an internal component of that ecosystem, not as a general-purpose library — releases track SURF's needs and its "last release 2026-01-29" cadence tells you nothing about response time to a security report. (2) Version coupling: Symfony 7 implies a hard PHP 8.2+ floor; Laravel versions carry their own PHP floors and their own Symfony component version pins, so a composer resolution conflict is plausible even for the sidecar-lite approach of pulling in only simplesamlphp/saml2. (3) Security surface: SAML is a high-CVE-density protocol (XML signature wrapping, comment injection in NameID, XXE). Every line of glue you write or fork is an attack surface you now own patching.
Key questions to resolve before committing. Does the bundle cover the full Web Browser SSO profile with both HTTP-Redirect and HTTP-POST bindings, and does it support Single Logout? Encrypted assertions, signed metadata, and metadata refresh — supported or left to the integrator? Is it usable as a standalone SP, or does it assume a Stepup gateway context for attribute enrichment and level-of-assurance handling? What is the CI/test story and is there any published security-advisory history? Which exact Symfony and simplesamlphp/saml2 constraints are pinned, and are they compatible with the target Laravel version's transitive Symfony components? Is there an IdP discovery / multi-IdP story, or is it single-IdP by design? Finally: does the target IdP federation (SURFconext, eduGAIN, or a corporate IdP) require entity registration and metadata exchange that adds calendar time independent of engineering effort?
Stack fit: partial — split the package in two. Reusable and genuinely valuable: simplesamlphp/saml2 (profiles, signature validation, metadata model) and the bundle's configuration semantics as a design reference for SP/IdP settings. Not reusable: bundle registration, the DI extension and config tree, Symfony Security authenticator/firewall integration, Symfony routing and controllers. Anything built on Laravel's Auth/Guard/Middleware must be written from scratch.
Migration path, in preference order.
simplesamlphp/saml2, model the SP config on this bundle's schema, and implement ACS + metadata + AuthnRequest. Budget 3–4 weeks including tests and a security review. Inherit the bundle's config vocabulary so a future swap stays cheap.Compatibility work to schedule explicitly. Bridge PSR-3 logging to Laravel's logger and PSR-6/PSR-16 caching to a Laravel cache store (the bundle will expect PSR services). Reconcile session semantics — Symfony's HttpFoundation session versus Laravel's session driver, cookie scoping, and SameSite settings on the ACS POST. Verify composer can resolve simplesamlphp/saml2 alongside the Laravel-pinned Symfony components; if not, isolate in the sidecar. Confirm cert/key storage against your secrets manager rather than filesystem paths.
Sequencing. (1) One-week spike: bare Laravel app + simplesamlphp/saml2 + one real IdP, prove a full login round-trip. This de-risks everything downstream. (2) Decide port vs. sidecar on the spike's evidence, not on preference. (3) Build metadata + ACS endpoints and get the SP registered with the IdP — start this early, it is calendar-bound, not code-bound. (4) Wire into Laravel's auth guard, map attributes to users/roles, define JIT provisioning behavior. (5) Harden: replay cache, clock skew tolerance, certificate rotation procedure, signed-assertion requirements. (6) Observability: structured auth-event logging, error-rate alerts. (7) Load/failure test, including IdP-unreachable and expired-cert scenarios.
Maintenance. You are adopting an actively released but narrowly-scoped component. Because the bundle tracks Symfony majors, its release notes will be driven by framework upgrades and OpenConext feature needs — not by your backlog. Critically, simplesamlphp/saml2 will receive security fixes on its own schedule, and the bundle may lag; a forked glue layer means you now own cherry-picking those fixes. Plan for a named owner and a quarterly dependency review, and treat any SAML-related CVE as a same-week triage item. With zero dependents and 14 stars, do not expect upstream responsiveness to your issue; assume you are the only consumer who cares about your specific use case.
Support. Apache-2.0, no commercial backing, no vendor SLA. The effective support channel is the OpenConext/SURF community and its documentation — good if you are in the Dutch research/education federation, thin otherwise. Budget for internal expertise, not external support: at minimum two engineers who can read a SAML assertion and reason about signature validation, so you are not single-pointed on the person who did the spike.
Scaling. SAML SSO is a low-QPS, high-CPU-per-request workload — signature verification and XML canonicalization are not cheap, but login volume rarely justifies concern. Horizontal scaling is straightforward provided sessions and the replay cache are shared (Redis), not process-local. The real scaling constraints are: (a) do not fetch IdP metadata per request — cache it with a refresh TTL; (b) cache parsed IdP certificates; (c) keep the SP stateless between the AuthnRequest and ACS calls apart from the correlation record. If you take the sidecar route, budget for its availability as a hard dependency of login — it becomes a tier-0 service.
Failure modes to instrument and runbook. Ranked by observed frequency in SAML deployments: expired or rotated IdP signing certificate (the single most common outage); clock skew beyond tolerance; ACS URL or entity ID mismatch after an environment promotion; NameID format or attribute-mapping drift after an IdP-side change; metadata refresh failing silently; replay cache unavailable, causing either hard failures or, worse, silently disabled replay protection; session store outage mid-flow; XML signature wrapping vulnerabilities in hand-rolled validation. Each needs a named alert and a documented fix. Alert on authentication error rate and on certificate expiry at T-30/T-7/T-1 days.
Ramp-up. The code is not the hard part — the protocol is. A competent Laravel engineer with SAML guidance should reach productive contribution in 2–4 weeks; deeper features (SLO, encrypted assertions, multi-IdP discovery) extend that meaningfully. Add federation registration and IdP-side testing coordination as separate calendar time. The pragmatic recommendation: run the spike, and if the org has no federation obligation pulling it toward OpenConext, evaluate a managed broker before committing engineering to porting this bundle — the integration cost is real, and this package's specific advantages are largely unavailable to a Laravel stack.
How can I help you explore Laravel packages today?