{"id":10764,"library":"dpop","title":"DPoP for JavaScript Runtimes","description":"dpop is a JavaScript library providing a robust implementation of the OAuth 2.0 Demonstration of Proof-of-Possession at the Application Layer (DPoP), as specified by RFC9449. It facilitates the secure generation of DPoP key pairs and proofs, which are crucial for enhancing API security by binding access tokens to the client's cryptographic key. The library is designed for broad compatibility, supporting various JavaScript runtimes including modern browsers, Node.js (v20.x and higher), Bun, Deno, Cloudflare Workers, Electron, and Vercel's Edge Runtime. The current stable version is 2.1.1, with an active development cycle that includes regular feature additions, bug fixes, and adherence to evolving standards. Its primary differentiators are its comprehensive runtime support and strict compliance with RFC9449, ensuring interoperable and reliable DPoP implementations across different environments.","status":"active","version":"2.1.1","language":"javascript","source_language":"en","source_url":"https://github.com/panva/dpop","tags":["javascript","dpop","rfc9449","typescript"],"install":[{"cmd":"npm install dpop","lang":"bash","label":"npm"},{"cmd":"yarn add dpop","lang":"bash","label":"yarn"},{"cmd":"pnpm add dpop","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Since v2.0.0, the package primarily uses named exports. Using `import * as DPoP` is the recommended way to import all functionalities. CommonJS `require('dpop')` is only fully supported in Node.js versions where `require(esm)` is enabled by default (e.g., ^20.19.0 || ^22.12.0 || >= 23.0.0).","wrong":"const DPoP = require('dpop');","symbol":"DPoP","correct":"import * as DPoP from 'dpop';"},{"note":"As of v2.0.0, the library moved to named exports exclusively. Functions like `generateKeyPair` and `generateProof` must be destructured from the 'dpop' module. Attempting a default import will result in `undefined`.","wrong":"import DPoP, { generateKeyPair, generateProof } from 'dpop';","symbol":"generateKeyPair, generateProof","correct":"import { generateKeyPair, generateProof } from 'dpop';"},{"note":"The `calculateThumbprint` function, introduced in v2.1.0, is specifically for computing the `dpop_jkt`. It is a named export and should be imported directly or accessed via `DPoP.calculateThumbprint` after a `* as DPoP` import. There is no top-level `dpop_jkt` function.","wrong":"import * as DPoP from 'dpop'; const dpop_jkt = await DPoP.dpop_jkt(publicKey);","symbol":"calculateThumbprint","correct":"import { calculateThumbprint } from 'dpop';"}],"quickstart":{"code":"import * as DPoP from 'dpop';\n\nasync function runDPoPExample() {\n  console.log('Starting DPoP example...');\n\n  // 1. Generate a DPoP Key Pair (e.g., ES256 algorithm)\n  // The 'extractable: false' option is good practice for non-exportable keys\n  const keyPair = await DPoP.generateKeyPair('ES256', { extractable: false });\n  console.log('DPoP Key Pair generated using ES256.');\n\n  // 2. Calculate the dpop_jkt (Key Thumbprint) for authorization code binding\n  // This identifies the public key associated with the DPoP proof\n  const dpop_jkt = await DPoP.calculateThumbprint(keyPair.publicKey);\n  console.log('Calculated dpop_jkt:', dpop_jkt);\n\n  // 3. Generate a DPoP proof for an Authorization Server (AS) token request\n  // This proof is sent with the token request to the AS\n  const asTokenUrl = 'https://as.example.com/token';\n  const asProof = await DPoP.generateProof(keyPair, asTokenUrl, 'POST');\n  console.log('DPoP Proof for AS Token Request:', asProof.slice(0, 100), '...'); // Truncate for display\n\n  // 4. Simulate an Access Token from the AS and generate a DPoP proof for a Resource Server (RS) API request\n  // The access token is bound to the DPoP key when making requests to the RS\n  const rsApiUrl = 'https://rs.example.com/api/data';\n  const accessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJhY2Nlc3NfdG9rZW4iOnRydWV9.SflKxwRJSMeKKF2F8DGD_dPOk_W5dZg_qkX-zHjN_W0'; // Example dummy token\n  const nonceFromRS = undefined; // In a real scenario, this might come from a 'DPoP-Nonce' header\n  const rsProof = await DPoP.generateProof(\n    keyPair,\n    rsApiUrl,\n    'GET',\n    nonceFromRS,\n    accessToken\n  );\n  console.log('DPoP Proof for RS API Request:', rsProof.slice(0, 100), '...'); // Truncate for display\n}\n\nrunDPoPExample().catch(console.error);\n","lang":"typescript","description":"Demonstrates DPoP key pair generation, dpop_jkt calculation, and DPoP proof generation for both Authorization Server token requests and Resource Server API calls."},"warnings":[{"fix":"Update your import statements: change `import DPoP from 'dpop';` to `import * as DPoP from 'dpop';` or `import { functionName } from 'dpop';`.","message":"Version 2.0.0 removed default exports in favor of named exports. All functions must now be imported via destructuring (e.g., `import { generateKeyPair } from 'dpop';`) or by importing all as a namespace (e.g., `import * as DPoP from 'dpop';`).","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Remove the `modulusLength` option from your `generateKeyPair` calls. If you need RSA keys with specific modulus lengths, consider generating them externally and importing them, or use algorithms like ES256, Ed25519.","message":"The `modulusLength` option for key generation has been removed in v2.0.0. This option was specific to RSA keys and its removal streamlines the API, focusing on more modern and recommended algorithms.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Migrate any usage of the deprecated EdDSA algorithm to Ed25519 or another supported algorithm like ES256.","message":"Support for the deprecated EdDSA algorithm was removed in v2.0.0. The library now supports the fully-specified Ed25519 JWS Algorithm.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Ensure your Node.js environment is version 20.x or newer. Use a version manager like `nvm` to upgrade if necessary.","message":"Node.js v20.x or higher is required as a baseline runtime environment for `dpop` v2.x. This is due to the library's reliance on modern Web API globals and standard built-in objects.","severity":"gotcha","affected_versions":">=2.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Change your import from `import DPoP from 'dpop';` to `import * as DPoP from 'dpop';` or `import { generateKeyPair } from 'dpop';`.","cause":"Attempting to call functions as properties of a default import, but `dpop` uses named exports since v2.0.0.","error":"TypeError: DPoP.generateKeyPair is not a function"},{"fix":"Ensure `generateKeyPair` is properly imported: `import { generateKeyPair } from 'dpop';` or accessed via a namespace: `import * as DPoP from 'dpop'; DPoP.generateKeyPair(...)`.","cause":"Trying to use a named export function without importing it explicitly or via a namespace import.","error":"ReferenceError: generateKeyPair is not defined"},{"fix":"Remove the `modulusLength` option from your `generateKeyPair` call. The library no longer supports it.","cause":"Using the `modulusLength` option in `generateKeyPair` after it was removed in v2.0.0.","error":"Error: 'modulusLength' option is not supported for key generation."}],"ecosystem":"npm"}