Web Bot Authentication

raw JSON →
0.1.3 verified Thu Apr 23 auth: no javascript

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.

error TypeError: signerFromJWK is not a function
cause Attempting to import `signerFromJWK` from the main `web-bot-auth` package path instead of its specific crypto subpath.
fix
Change your import statement from import { signerFromJWK } from 'web-bot-auth'; to import { signerFromJWK } from 'web-bot-auth/crypto';.
error ReferenceError: Request is not defined
cause The code is being run in a Node.js environment without a global `Request` object being present, which the library expects.
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';
error Error: Signature verification failed: Signature-Input parameter 'sig1' is missing 'keyid'
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.
fix
Ensure your JWK includes a unique 'kid' property and that the signing process correctly includes this 'keyid' in the 'Signature-Input' headers.
gotcha 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.
fix Do not use in production without a thorough security audit. Closely monitor for updates and security advisories.
breaking 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.
fix Pin your dependency to an exact version and review release notes thoroughly for any updates. Be prepared for refactoring when upgrading.
gotcha 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.
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.
npm install web-bot-auth
yarn add web-bot-auth
pnpm add web-bot-auth

Demonstrates how to sign an HTTP request using a test JWK, adding 'Signature' and 'Signature-Input' headers for Web Bot Authentication.

import { signatureHeaders } from 'web-bot-auth';
import { signerFromJWK } from 'web-bot-auth/crypto';

const RFC_9421_ED25519_TEST_KEY = {
  kty: 'OKP',
  crv: 'Ed25519',
  kid: 'test-key-ed25519',
  d: 'n4Ni-HpISpVObnQMW0wOhCKROaIKqKtW_2ZYb2p9KcU',
  x: 'JrQLj5P_89iXES9-vFgrIy29clF9CC_oPPsw3c5D0bs'
};

async function signRequest() {
  const request = new Request('https://example.com');
  const now = new Date();

  const headers = await signatureHeaders(
    request,
    await signerFromJWK(RFC_9421_ED25519_TEST_KEY),
    {
      created: now,
      expires: new Date(now.getTime() + 300_000) // now + 5 min
    }
  );

  const signedRequest = new Request('https://example.com', {
    headers: {
      'Signature': headers['Signature'],
      'Signature-Input': headers['Signature-Input']
    }
  });

  console.log('Signed Request Headers:', Object.fromEntries(signedRequest.headers.entries()));
  return signedRequest;
}

signRequest().catch(console.error);