SAML Protocol Identity Provider Middleware
samlp is a Node.js middleware library designed to facilitate the creation of SAML Protocol Identity Provider (IdP) endpoints. It handles the complexities of generating SAML responses and metadata, allowing developers to focus on user authentication mechanisms. The current stable version is 8.0.0, released March 31, 2026. This library is actively maintained by Auth0 and sees releases for new features, bug fixes, and dependency updates, typically on a monthly to quarterly cadence. Its key differentiator is its focus specifically on the IdP side of SAML, providing a configurable Express/Koa-compatible middleware, in contrast to libraries that are more general-purpose or service provider-centric. It requires Node.js version 12 or greater, reflecting modern Node.js ecosystem practices.
Common errors
-
Error: certificate and private key do not match
cause The public certificate (`cert`) and private key (`key`) provided to `samlp.auth` or `samlp.metadata` do not correspond to each other, or are malformed.fixVerify that `some-cert.pem` contains the public certificate corresponding to `some-cert.key`. Ensure both files are correctly formatted PEM files. Regenerate the key pair if necessary. -
TypeError: Cannot read properties of undefined (reading 'auth')
cause Attempting to call `samlp.auth` or `samlp.metadata` without `samlp` being correctly imported or `samlp` itself being undefined.fixEnsure `import samlp from 'samlp';` or `const samlp = require('samlp');` is at the top of your file and executes correctly. This error can also happen if `samlp` is not properly installed (`npm install samlp`). -
SAML response not posting to Service Provider (blank page, or client-side error)
cause The `getPostURL` function is returning an incorrect or inaccessible URL, or the Service Provider is not configured to receive SAML assertions at the specified endpoint.fixDouble-check the implementation of your `getPostURL` function to ensure it returns the correct Assertion Consumer Service (ACS) URL for the target Service Provider. Verify that the Service Provider's ACS endpoint is correctly configured and publicly accessible. -
RangeError: The value of "node" is out of range. It must be >= 12. Received ...
cause You are trying to run `samlp` on a Node.js version older than 12.fixUpgrade your Node.js environment to version 12 or higher. Use a Node.js version manager like `nvm` to easily switch and manage Node.js versions.
Warnings
- breaking Version 8.0.0 introduces new encryption algorithm options and a `disallowEncryptionWithInsecureAlgorithm` flag. The default encryption algorithm is now `http://www.w3.org/2009/xmlenc11#aes256-gcm`. If you were relying on implicit or less secure encryption algorithms, this might change behavior or require explicit configuration.
- breaking Version 7.0.0 raised the minimum Node.js requirement to `node >= 12`. Older Node.js versions are no longer supported.
- gotcha The `cert` and `key` options for the `samlp.auth` middleware are `REQUIRED` and must be valid PEM-encoded public and private keys, respectively. Misconfigured or missing keys are a common source of errors during SAML assertion signing or encryption.
- gotcha The `getPostURL` option is `REQUIRED` and is a function that determines where the SAML assertion should be posted (the Service Provider's Assertion Consumer Service URL). Incorrect implementation or static URLs can lead to failed SAML flows or security vulnerabilities if not dynamically resolved.
- gotcha Security vulnerability fixes often involve upgrading underlying dependencies like `node-saml`. Older versions of `samlp` might contain known vulnerabilities inherited from these dependencies.
Install
-
npm install samlp -
yarn add samlp -
pnpm add samlp
Imports
- samlp
const samlp = require('samlp');import samlp from 'samlp';
- auth
import { auth } from 'samlp';import samlp from 'samlp'; app.get('/samlp', samlp.auth({...})); - metadata
import { metadata } from 'samlp';import samlp from 'samlp'; app.get('/FederationMetadata/2007-06/FederationMetadata.xml', samlp.metadata({...}));
Quickstart
import express from 'express';
import samlp from 'samlp';
import fs from 'fs';
import path from 'path';
const app = express();
const PORT = process.env.PORT || 3000;
// Dummy user object for demonstration
const dummyUser = { id: 'user123', email: 'test@example.com', name: 'Test User' };
// Minimal SAMLP configuration
const samlpOptions = {
issuer: 'http://localhost:3000/samlp',
cert: fs.readFileSync(path.join(process.cwd(), 'some-cert.pem'), 'utf8'), // Ensure 'some-cert.pem' exists
key: fs.readFileSync(path.join(process.cwd(), 'some-cert.key'), 'utf8'), // Ensure 'some-cert.key' exists
getPostURL: function (audience, samlRequestDom, req, callback) {
// In a real scenario, this would dynamically determine the SP's AssertionConsumerService URL
// For quickstart, we'll just return a placeholder or a mock SP URL.
// Usually, the `audience` from SAMLRequest can help determine the SP.
console.log('SAML Request received from audience:', audience);
// For a minimal example, let's assume a fixed SP URL for posting the assertion
const spAcsUrl = 'http://localhost:8080/saml/acs'; // Replace with a real SP's ACS URL
return callback(null, spAcsUrl);
},
getUserFromRequest: function (req) {
// In a real app, this would get the authenticated user from req.user or session
return dummyUser;
},
profileMapper: samlp.PassportProfileMapper,
signatureAlgorithm: 'rsa-sha256',
digestAlgorithm: 'sha256',
signResponse: false,
signAssertion: true
};
app.get('/samlp', (req, res, next) => {
// Simulate a pre-authenticated user for the IdP flow
req.user = dummyUser;
samlp.auth(samlpOptions)(req, res, next);
});
// SAML IdP Metadata endpoint
app.get('/samlp/FederationMetadata/2007-06/FederationMetadata.xml', samlp.metadata(samlpOptions));
app.listen(PORT, () => {
console.log(`SAML IdP listening on port ${PORT}`);
console.log('Access SAML Login Initiator via: http://localhost:3000/samlp');
console.log('Access SAML Metadata via: http://localhost:3000/samlp/FederationMetadata/2007-06/FederationMetadata.xml');
});