{"id":18002,"library":"web-bot-auth","title":"Web Bot Authentication","description":"web-bot-auth is a TypeScript library developed by Cloudflare Research that implements HTTP Message Signatures for the purpose of Web Bot Authentication. It adheres to the draft-meunier-web-bot-auth-architecture specification. Currently at version 0.1.3, the library provides utilities for signing and verifying HTTP requests using cryptographic keys, including features like JWK (JSON Web Key) thumbprint pre-computation. Its release cadence is likely tied to research advancements and RFC progression, as it's an early-stage project. Key differentiators include its specific focus on bot authentication, direct implementation of a draft RFC, and shipping with full TypeScript type definitions, making it suitable for type-safe applications. It is designed to work with standard Web API `Request` objects.","status":"active","version":"0.1.3","language":"javascript","source_language":"en","source_url":"https://github.com/cloudflare/web-bot-auth","tags":["javascript","web-bot-auth","cryptography","typescript"],"install":[{"cmd":"npm install web-bot-auth","lang":"bash","label":"npm"},{"cmd":"yarn add web-bot-auth","lang":"bash","label":"yarn"},{"cmd":"pnpm add web-bot-auth","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The library is primarily designed for ESM environments. Use named imports for core signing functionality.","wrong":"const { signatureHeaders } = require('web-bot-auth');","symbol":"signatureHeaders","correct":"import { signatureHeaders } from 'web-bot-auth';"},{"note":"Crypto utility functions are located in a subpath import. Forgetting `/crypto` is a common mistake.","wrong":"import { signerFromJWK } from 'web-bot-auth';","symbol":"signerFromJWK","correct":"import { signerFromJWK } from 'web-bot-auth/crypto';"},{"note":"Verification functions are named exports from the main package entry point.","wrong":"import verify from 'web-bot-auth';","symbol":"verify","correct":"import { verify } from 'web-bot-auth';"},{"note":"Like `signerFromJWK`, verifier utilities require the `/crypto` subpath and are named exports.","wrong":"const verifierFromJWK = require('web-bot-auth/crypto').verifierFromJWK;","symbol":"verifierFromJWK","correct":"import { verifierFromJWK } from 'web-bot-auth/crypto';"}],"quickstart":{"code":"import { signatureHeaders } from 'web-bot-auth';\nimport { signerFromJWK } from 'web-bot-auth/crypto';\n\nconst RFC_9421_ED25519_TEST_KEY = {\n  kty: 'OKP',\n  crv: 'Ed25519',\n  kid: 'test-key-ed25519',\n  d: 'n4Ni-HpISpVObnQMW0wOhCKROaIKqKtW_2ZYb2p9KcU',\n  x: 'JrQLj5P_89iXES9-vFgrIy29clF9CC_oPPsw3c5D0bs'\n};\n\nasync function signRequest() {\n  const request = new Request('https://example.com');\n  const now = new Date();\n\n  const headers = await signatureHeaders(\n    request,\n    await signerFromJWK(RFC_9421_ED25519_TEST_KEY),\n    {\n      created: now,\n      expires: new Date(now.getTime() + 300_000) // now + 5 min\n    }\n  );\n\n  const signedRequest = new Request('https://example.com', {\n    headers: {\n      'Signature': headers['Signature'],\n      'Signature-Input': headers['Signature-Input']\n    }\n  });\n\n  console.log('Signed Request Headers:', Object.fromEntries(signedRequest.headers.entries()));\n  return signedRequest;\n}\n\nsignRequest().catch(console.error);","lang":"typescript","description":"Demonstrates how to sign an HTTP request using a test JWK, adding 'Signature' and 'Signature-Input' headers for Web Bot Authentication."},"warnings":[{"fix":"Do not use in production without a thorough security audit. Closely monitor for updates and security advisories.","message":"This software has not been audited for security. It is developed by Cloudflare Research and should be used with extreme caution, especially in production environments, until it has undergone independent security reviews.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Pin your dependency to an exact version and review release notes thoroughly for any updates. Be prepared for refactoring when upgrading.","message":"As a pre-1.0 release (current version 0.1.3), the API is subject to significant changes without prior warning. Breaking changes may be introduced in minor or patch versions.","severity":"breaking","affected_versions":">=0.1.0"},{"fix":"Ensure `Request` and `Response` are globally available (e.g., using `node-fetch` or a web framework that provides them) or explicitly import them if your environment supports it.","message":"The library heavily relies on standard Web API `Request` and `Response` objects. If used in a Node.js environment, these globals might not be available, leading to runtime errors.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"last_verified":"2026-04-23T00:00:00.000Z","next_check":"2026-07-22T00:00:00.000Z","problems":[{"fix":"Change your import statement from `import { signerFromJWK } from 'web-bot-auth';` to `import { signerFromJWK } from 'web-bot-auth/crypto';`.","cause":"Attempting to import `signerFromJWK` from the main `web-bot-auth` package path instead of its specific crypto subpath.","error":"TypeError: signerFromJWK is not a function"},{"fix":"Install a polyfill like `node-fetch` and ensure `Request` is made globally available, or manually import it if your environment permits. For example: `import { Request } from 'node-fetch';`","cause":"The code is being run in a Node.js environment without a global `Request` object being present, which the library expects.","error":"ReferenceError: Request is not defined"},{"fix":"Ensure your JWK includes a unique 'kid' property and that the signing process correctly includes this 'keyid' in the 'Signature-Input' headers.","cause":"The JWK used for signing or verification does not contain a 'kid' (Key ID) property, or the 'keyid' parameter was omitted from the 'Signature-Input' during signing.","error":"Error: Signature verification failed: Signature-Input parameter 'sig1' is missing 'keyid'"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}