node-saml

A framework-agnostic SAML 2.0 authentication library for Node.js, handling AuthnRequest/Response generation, XML signature validation, and single logout.

Library
npm
v5.1.0
135stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
49/100Fair
Development Activity0
Maintenance32
Community84
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
75/100Good
Architecture80
Code Quality78
Innovation65
Learning Curve75

@node-saml/node-saml is a SAML 2.0 implementation for Node.js that isn’t tied to any particular web framework. It builds and parses AuthnRequests and Responses, validates and generates XML digital signatures, decrypts encrypted assertions, and supports both HTTP-Redirect and HTTP-POST protocol bindings — the building blocks that framework-specific packages like passport-saml wrap around.

Originally extracted from the passport-saml strategy, the library pulls the core SAML protocol handling into a standalone package so it can be reused outside of Passport.js. It ships full TypeScript types, an in-memory (and pluggable) InResponseTo cache for replay protection, single logout (SLO) support for both SP- and IdP-initiated flows, and a generateServiceProviderMetadata helper for producing SP metadata documents.

What You Get

  • AuthnRequest and LogoutRequest generation with HTTP-Redirect or HTTP-POST bindings
  • XML digital signature generation and validation (SHA1/SHA256/SHA512) for both requests and responses
  • Assertion and NameID decryption via a configurable decryptionPvk private key
  • Single Logout (SLO) support for SP-initiated and IdP-initiated flows
  • Pluggable CacheProvider interface for InResponseTo replay protection across multiple processes
  • generateServiceProviderMetadata for producing SP metadata XML for IdP registration
  • Full TypeScript type definitions for every configuration option and profile field

Common Use Cases

  • Adding enterprise SSO login to a Node.js app via an identity provider like Okta, Azure AD, or ADFS
  • Building a custom Passport.js SAML strategy without depending on framework-specific glue code
  • Validating and parsing incoming SAML assertions from a third-party IdP in a backend service
  • Generating SP metadata XML to hand to an IdP admin during SAML integration setup
  • Implementing single logout (SLO) flows that need to notify or be notified by an IdP

Under The Hood

Architecture The SAML class in src/saml.ts acts as the central orchestrator, composing pure helper modules rather than doing everything itself: xml.ts owns DOM parsing, xpath queries, XML signature validation, and decryption; metadata.ts builds SP metadata documents; crypto.ts handles PEM/key-info parsing; algorithms.ts maps signature/digest algorithm names; in-memory-cache-provider.ts tracks InResponseTo state; and saml-post-signing.ts signs HTTP-POST-binding requests. Configuration flows through a single SamlOptions object validated at construction via assertRequired/isValidSamlSigningOptions type guards, and both the cache (CacheProvider interface, default InMemoryCacheProvider) and the IdP certificate source (idpCert as a string, array, or async callback) are injected as swappable strategies — a dependency-injection pattern that lets consumers back InResponseTo storage with Redis in multi-process deployments or poll a rotating certificate endpoint. Because AuthnRequest, Response validation, and metadata generation all funnel through xml.ts’s signature and XML-building helpers, that module is the load-bearing layer the rest of the package depends on.

Tech Stack Written in TypeScript, compiled with tsc to a lib/ output, targeting Node >= 18 (LTS-only, enforced via the engines field with major-version bumps on EOL). Its dependencies are almost entirely XML-focused: @xmldom/xmldom with @xmldom/is-dom-node for type-guarded DOM parsing, xml-crypto for XMLDSig signing/verification, xml-encryption for XMLEnc assertion decryption, xml2js for object-based parsing, xmlbuilder for constructing outgoing SAML XML, and xpath for DOM queries. Node’s built-in crypto, zlib (deflate/inflate for the HTTP-Redirect binding), and querystring/url are used directly rather than via extra dependencies, and the package deliberately has no web-framework dependency — it’s designed to be wrapped by Express middleware or a Passport strategy, not to own the HTTP layer itself.

Code Quality An extensive Mocha test suite (eight *.spec.ts files covering request generation, response/signature validation, caching, crypto, and XML handling) runs via ts-node/choma with Chai assertions and Sinon stubs, reported through nyc coverage (no enforced threshold, but coverage is tracked). ESLint 9’s flat config layers typescript-eslint, eslint-plugin-mocha, and eslint-plugin-chai-friendly on top of Prettier formatting, and GitHub Actions runs both a build/test workflow and a CodeQL security-scanning workflow on every change. Source favors typed interfaces over any (the few explicit any escapes are called out with inline eslint-disable comments), a custom SamlStatusError class carries SAML status codes on thrown errors, and runtime assertion helpers (assertRequired, assertBooleanIfPresent) guard config shape at the boundary.

API Design The library’s main contribution is being framework-agnostic — decoupling the SAML 2.0 protocol implementation from any single auth library, which is what let it be extracted from passport-saml and reused across consumers. The idpCert-as-async-callback pattern is a genuinely useful touch for zero-downtime certificate rotation that many comparable SAML libraries don’t expose. The public surface is a single SAML class built from one SamlConfig object plus a couple of named exports (generateServiceProviderMetadata, shared types); getting started means supplying idpCert/issuer/callbackUrl and calling the authorize/validate methods, boilerplate that reflects SAML’s inherent protocol complexity rather than avoidable friction in the library’s own design.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search