@dnsid-ai/web-bot-auth

中文文档
0.37.0发布于 2026/11/12Apache-2.0TypeScriptESM + CJS构建来源已验证近 30 天下载 2158

DNSid Web Bot Auth profile helpers.

原始使用文档
文档目录4 节
  1. Install
  2. Example
  3. Verify a request
  4. Options

@dnsid-ai/web-bot-auth

DNSid Web Bot Auth profile helpers.

This package signs and verifies DNSid Web Bot Auth requests (RFC 9421 HTTP Message Signatures with the web-bot-auth tag), serves signed key directories, and verifies discovered directories against current DNSid operational (ku) keys. It targets published draft-ietf-webbotauth-httpsig-protocol-00, including its directory format, not the editor's copy or a finalized WBA standard. This is a narrower DNSid profile, not a general WBA implementation. External partner interoperability has not been tested.

It builds on @dnsid-ai/http-signatures and @dnsid-ai/protocol contracts and performs no DNS or HTTPS transport itself. Signing requires an Ed25519 operational key; the profile throws ArgumentError for other key types.

Install

npm install @dnsid-ai/web-bot-auth @dnsid-ai/protocol

Example

Sign an outbound request:

import { createWebBotAuthProfile } from '@dnsid-ai/web-bot-auth';

const profile = createWebBotAuthProfile({
  domain: 'agent.example',
  keyProvider, // Ed25519 operational key
});

const signed = await profile.createWebBotAuthSignedRequest(
  new Request('https://origin.example/api'),
);
await fetch(signed);

Serve the key directory (mount at /.well-known/http-message-signatures-directory):

const response = await profile.serveHttpMessageSignaturesDirectory(request);

The directory response is signed with the http-message-signatures-directory tag and served as application/http-message-signatures-directory+json. Signatures are backdated by min(5, ttl - 1) seconds without extending their lifetime. The default response has at most 295 seconds of freshness and signed Cache-Control: max-age=295, must-revalidate. Disable CDN stale-serving overrides, stale-while-revalidate, and stale-if-error for this endpoint.

Verify a request

Verification-only construction does not need a local identity or signing key:

import { createSsrfSafeFetch } from '@dnsid-ai/transport'; // Node transport

const safeFetch = createSsrfSafeFetch({}, { decompress: false });
const verifier = createWebBotAuthProfile({
  identityResolver, // RefreshingIdentityResolver, including configured entity acceptance
  discoveryFetch: request => safeFetch(request),
});
const identity = await verifier.verifyWebBotAuthSignedRequest(request, {
  signerDomain: 'agent.example', // trusted application policy
  requiredComponents: ['@method', '@target-uri'], // enforce operation binding
  peerCert, // current application peer certificate, required for fl=mtls
  timeoutMs: 30_000,
  signal,
});

Install @dnsid-ai/transport to use this Node transport. The package stays runtime-neutral: discoveryFetch is required and must enforce valid Web PKI, public-address DNS checks and connection pinning on every connection, rejection of all redirects (including same-host HTTPS), cancellation, and unmodified response bytes and headers without decompression. Coded directories are rejected. Ordinary server-side fetch is not safe for untrusted discovery. Do not enable private-address exceptions for WBA discovery.

Alternatively, explicitly set allowSignatureAgentDomain: true to let the signed HTTPS discovery host identify the signer. Cross-host delegation is rejected. Signature-Agent and its exact keyed coverage are mandatory, even with trusted discovery: { uri, type }, which now constrains the signed endpoint rather than replacing it. Missing, uncovered, invalid, or unsupported discovery rejects before network work. The default type is directory and requires an exact ASCII HTTPS origin without a trailing slash, path, query, or fragment; jwks_uri addresses a direct signed directory endpoint, not an unsigned JWKS. Signature relabeling preserves the original covered discovery member.

Every invocation verifies request and directory signatures, content digests, and current DNSid key binding and acceptance. There is no directory-only fallback or internal directory cache. Every discovery request uses cache: 'no-store' and Cache-Control: no-cache. Injected transports must bypass local caches and revalidate upstream on each call. A fresh directory missing the key fails without a retry. Even newly fetched responses are rejected when HTTP-stale. max-age, Date, Age, and fetch latency establish a deadline that is checked again before return. A revalidated max-age=0 response with absent or zero Age may serve its acquiring invocation, as may fresh no-store or no-cache responses. Injected caching transports must enforce RFC 9111 freshness using original acquisition timing and HTTP age metadata, reject reuse without sufficient metadata, and never restart freshness when returning the same response. Key attribution must use the normalized discovery URL and thumbprint within the policy context. Newer resolutions replace older key sets, including removed keys; order signed proofs by created. Failed refreshes must neither evict evidence nor extend freshness. The verifier does not infer cache reuse or derive an HTTP deadline from signed creation time. Results authenticate identity but do not grant application permissions. Default required coverage is @authority, not method or path. Use signing additionalComponents to add bindings and verifier requiredComponents to require them, with exact parameter equality. Nested WBA signing is unsupported. Coverage policy is checked before discovery; malformed policy raises ArgumentError. Covered keyed Content-Digest components must select sha-256; unsupported members are rejected. Profile configuration, including nested discovery settings, is snapshotted and validated on construction.

For one-time requests, supply consumeNonce(entry, signal). It must atomically consume (signerDomain, keyid, nonce) and retain the entry until retainUntil (expires + clockSkew). Return false for reuse; store errors reject verification. Without this hook, time-valid requests can be replayed.

The overall timeout defaults to 30 seconds and covers discovery, reads, DNSid verification, and replay storage. Redirects are rejected. Limits are 256 KiB directory content, 64 keys, JSON depth 16, 16 KiB signature/discovery/digest headers and URLs, 64 KiB aggregate header characters, and 1 MiB request content. The hosting layer must bound incoming request streams before cloning them; verification preserves the original request body. Signature lifetimes cannot exceed 300 seconds. Directory signature creation cannot be in the future, even within configured clock skew. Evidence freshness is checked again before return, including both certificates and key age. Fresh zero-TTL DNS evidence is valid only within the acquiring invocation. Directory timeouts and temporary HTTP failures are transient; invalid TLS, unsafe destinations, and invalid signatures remain permanent.

Options

  • signatureAgent — the discovery URI and type advertised in Signature-Agent. It defaults to the domain's HTTPS origin with type=directory; use type=jwks_uri for a direct JWKS endpoint.
  • directoryURL — deprecated compatibility option interpreted as a direct jwks_uri endpoint. Use signatureAgent.uri instead.
  • signatureTTL / directorySignatureTTL — signature lifetimes in seconds (defaults: 60 for requests, 300 for the directory).
  • clockSkew — non-negative verification tolerance in seconds (default: 5); never permits future directory creation.

You can also build the profile from a signing identity manager with WebBotAuthProfile.fromIdentityManager(idm).

The includeSignatureAgent configuration and per-request signatureAgent omission options have been removed. Only the current DNSid operational key is accepted, without overlapping-key grace. Verification requires RefreshingIdentityResolver; missing refreshDomain raises ArgumentError on construction. After valid request and directory signatures, a current-key mismatch permits one refreshDomain attempt per normalized signer domain per five seconds, shared across concurrent calls and discovery URLs. Failed attempts consume the allowance; concurrent retries are suppressed. Admission state is capped at 1024 domains and fails closed when full. Refreshed evidence must pass normal acceptance, current-peer, current-key, and freshness checks. There is no eviction workaround or stale fallback. Propagation and availability can still interrupt rotation, and learning the new key rejects outstanding old-key requests.

The agent domain is the identity FQDN, not its accountable entity or request destination. WBA discovery must be separate from the live ku JWKS, including query/fragment variants. fromIdentityManager rejects locally configured ku discovery; verification checks the authenticated ku endpoint. Validated HTTPS at the agent's public ku endpoint supplies DNSid's agent-FQDN TLS check without inbound access to the crawler process. With fl=mtls, current application-peer evidence remains required.

Use the shared managed rotation/recovery workflow: its pause hook must block new request/directory signing and wait for existing signing operations before resolving. Probe new-key requests through a verifier caching the old key. The shared HTTP signer verifies each returned signature against the public key selected for its metadata and fails on mismatch. Built-in local and AWS providers drain in-flight signatures and reject new signing during activation; custom providers must enforce the same contract. For a lost or suspected compromised key, stop signing and use revocation/reissuance, not routine rotation. Short TTLs and mismatch refresh do not revoke stolen keys. The same ku also authorizes KEY_ROTATION: unrestricted key access on a signing node can authorize identity rotation, not just forge requests. Keeping ek off the fleet does not remove this exposure; dedicated fleet-key delegation requires a separate security design.

版本与发布记录

@dnsid-ai/web-bot-auth 共发布 22 个版本,首次发布于 2026/09/22;过去 12 个月发布了 22 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.37.0latest2026/11/121 天前
0.36.02026/11/112 天前
0.35.02026/11/067 天前
0.34.02026/10/3014 天前
0.33.02026/10/2815 天前
0.32.02026/10/2716 天前

关于 @dnsid-ai/web-bot-auth 的常见问题

@dnsid-ai/web-bot-auth 是什么?

DNSid Web Bot Auth profile helpers.

如何安装 @dnsid-ai/web-bot-auth?

在项目目录运行 npm install @dnsid-ai/web-bot-auth,或使用 pnpm add / yarn add / bun add。

@dnsid-ai/web-bot-auth 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@dnsid-ai/web-bot-auth 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@dnsid-ai/web-bot-auth 可以商用吗?

@dnsid-ai/web-bot-auth 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@dnsid-ai/web-bot-auth 的下载量有多少?

根据 npm 官方下载统计,@dnsid-ai/web-bot-auth 在 2026/10/13 – 2026/11/11 这 30 天内被下载 2,158 次,日均约 72 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@dnsid-ai/web-bot-auth 还在维护吗?

最新版本 0.37.0 发布于 2026/11/12(1 天前);至今共发布 22 个版本,其中过去 12 个月发布了 22 个;首次发布于 2026/09/22。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。