{"id":16204,"library":"samlp","title":"SAML Protocol Identity Provider Middleware","description":"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.","status":"active","version":"8.0.0","language":"javascript","source_language":"en","source_url":"https://github.com/auth0/node-samlp","tags":["javascript","saml","auth"],"install":[{"cmd":"npm install samlp","lang":"bash","label":"npm"},{"cmd":"yarn add samlp","lang":"bash","label":"yarn"},{"cmd":"pnpm add samlp","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"While older versions might have been CJS-only, modern Node.js development strongly favors ESM. The library's `package.json` 'main' points to 'lib/samlp.js' which exports `module.exports`, so `require` is still the primary method for Node < 16 or mixed setups, but ESM import is increasingly preferred.","wrong":"const samlp = require('samlp');","symbol":"samlp","correct":"import samlp from 'samlp';"},{"note":"The `auth` method is a property of the default `samlp` export, not a named export. It's the primary entry point for configuring the SAML IdP authentication flow.","wrong":"import { auth } from 'samlp';","symbol":"auth","correct":"import samlp from 'samlp';\napp.get('/samlp', samlp.auth({...}));"},{"note":"Similar to `auth`, `metadata` is a property of the default `samlp` export, used for exposing the IdP's SAML metadata endpoint. Ensure correct path for the metadata endpoint.","wrong":"import { metadata } from 'samlp';","symbol":"metadata","correct":"import samlp from 'samlp';\napp.get('/FederationMetadata/2007-06/FederationMetadata.xml', samlp.metadata({...}));"}],"quickstart":{"code":"import express from 'express';\nimport samlp from 'samlp';\nimport fs from 'fs';\nimport path from 'path';\n\nconst app = express();\nconst PORT = process.env.PORT || 3000;\n\n// Dummy user object for demonstration\nconst dummyUser = { id: 'user123', email: 'test@example.com', name: 'Test User' };\n\n// Minimal SAMLP configuration\nconst samlpOptions = {\n  issuer: 'http://localhost:3000/samlp',\n  cert: fs.readFileSync(path.join(process.cwd(), 'some-cert.pem'), 'utf8'), // Ensure 'some-cert.pem' exists\n  key: fs.readFileSync(path.join(process.cwd(), 'some-cert.key'), 'utf8'),   // Ensure 'some-cert.key' exists\n  getPostURL: function (audience, samlRequestDom, req, callback) {\n    // In a real scenario, this would dynamically determine the SP's AssertionConsumerService URL\n    // For quickstart, we'll just return a placeholder or a mock SP URL.\n    // Usually, the `audience` from SAMLRequest can help determine the SP.\n    console.log('SAML Request received from audience:', audience);\n    // For a minimal example, let's assume a fixed SP URL for posting the assertion\n    const spAcsUrl = 'http://localhost:8080/saml/acs'; // Replace with a real SP's ACS URL\n    return callback(null, spAcsUrl);\n  },\n  getUserFromRequest: function (req) {\n    // In a real app, this would get the authenticated user from req.user or session\n    return dummyUser;\n  },\n  profileMapper: samlp.PassportProfileMapper,\n  signatureAlgorithm: 'rsa-sha256',\n  digestAlgorithm: 'sha256',\n  signResponse: false,\n  signAssertion: true\n};\n\napp.get('/samlp', (req, res, next) => {\n  // Simulate a pre-authenticated user for the IdP flow\n  req.user = dummyUser;\n  samlp.auth(samlpOptions)(req, res, next);\n});\n\n// SAML IdP Metadata endpoint\napp.get('/samlp/FederationMetadata/2007-06/FederationMetadata.xml', samlp.metadata(samlpOptions));\n\napp.listen(PORT, () => {\n  console.log(`SAML IdP listening on port ${PORT}`);\n  console.log('Access SAML Login Initiator via: http://localhost:3000/samlp');\n  console.log('Access SAML Metadata via: http://localhost:3000/samlp/FederationMetadata/2007-06/FederationMetadata.xml');\n});\n","lang":"javascript","description":"This quickstart sets up a basic SAML Identity Provider (IdP) using Express and samlp, exposing login and metadata endpoints. It demonstrates how to configure the core `samlp.auth` middleware with required options like issuer, certificates, and a placeholder for the `getPostURL` and `getUserFromRequest` functions. It assumes a pre-authenticated `req.user` for simplicity. **Note**: Requires `some-cert.pem` and `some-cert.key` in the project root."},"warnings":[{"fix":"Review and update your `encryptionAlgorithm` and `disallowEncryptionWithInsecureAlgorithm` options. If you need to use a different algorithm, explicitly set `encryptionAlgorithm`. To allow less secure algorithms (not recommended), set `disallowEncryptionWithInsecureAlgorithm` to `false` and consider `warnOnInsecureEncryptionAlgorithm` to `true` for logging.","message":"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.","severity":"breaking","affected_versions":">=8.0.0"},{"fix":"Ensure your project is running on Node.js version 12 or newer. Update your Node.js environment if it's older.","message":"Version 7.0.0 raised the minimum Node.js requirement to `node >= 12`. Older Node.js versions are no longer supported.","severity":"breaking","affected_versions":">=7.0.0"},{"fix":"Always provide valid `cert` and `key` values as Buffer or string (from `fs.readFileSync`). Ensure the keys match and are correctly formatted. For development, you can generate self-signed certificates using OpenSSL (e.g., `openssl genrsa -out some-cert.key 2048`, `openssl req -new -x509 -key some-cert.key -out some-cert.pem -days 365`).","message":"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.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Implement `getPostURL` to dynamically resolve the correct ACS URL based on the SAML request's audience or other SP-identifying information. Avoid hardcoding this URL in production environments where multiple Service Providers might be interacting with your IdP. The function signature is `f(audience, samlRequestDom, req, callback)`.","message":"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.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always keep `samlp` updated to the latest minor/patch versions within your major release, especially following dependency security updates (e.g., v7.0.2 fixed `node-saml` and `ejs` vulnerabilities, v7.1.1 fixed a signed logout response bug). Regularly check the release notes for security-related fixes.","message":"Security vulnerability fixes often involve upgrading underlying dependencies like `node-saml`. Older versions of `samlp` might contain known vulnerabilities inherited from these dependencies.","severity":"gotcha","affected_versions":"<7.0.2, <7.1.1 (for specific issues)"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Verify 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.","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.","error":"Error: certificate and private key do not match"},{"fix":"Ensure `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`).","cause":"Attempting to call `samlp.auth` or `samlp.metadata` without `samlp` being correctly imported or `samlp` itself being undefined.","error":"TypeError: Cannot read properties of undefined (reading 'auth')"},{"fix":"Double-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.","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.","error":"SAML response not posting to Service Provider (blank page, or client-side error)"},{"fix":"Upgrade 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.","cause":"You are trying to run `samlp` on a Node.js version older than 12.","error":"RangeError: The value of \"node\" is out of range. It must be >= 12. Received ..."}],"ecosystem":"npm"}