Repository files navigation

web-bot-auth (Go)

Verify and produce Web Bot Auth signatures in Go — cryptographic identity for bots and AI agents, with zero dependencies.

CI

Web Bot Auth replaces spoofable user-agent strings with cryptographic proof: agents sign each request with RFC 9421 HTTP Message Signatures (tag web-bot-auth), publish their public keys in an HTTP Message Signatures directory, and identify the directory via the Signature-Agent header. OpenAI signs Operator requests today; Cloudflare, Vercel, and AWS WAF verify at their edges. This module lets any Go service do the same.

Built and maintained by WebDecoy. Ported from and cross-validated against cloudflare/web-bot-auth — the reference implementation's test vectors run in this repo's CI.

  • Zero dependenciescrypto/ed25519, crypto/rsa, and the standard library only.
  • Both draft generations — the current Signature-Agent dictionary form with key="..." member extraction, and the earlier bare-string form deployed signers still send.
  • Verification is a verdict, not an errorno-signature / verified / invalid, designed for detection pipelines where an invalid claim of agent identity is the most interesting outcome.
  • SSRF-guarded key discovery — https-only, host allowlist (or explicit open mode with a non-global-address dialer), size caps, per-hop redirect re-validation, TTL + stale-while-revalidate caching.

Install

go get github.com/WebDecoy/web-bot-auth

Verify inbound requests

import (
"net/http"
webbotauth "github.com/WebDecoy/web-bot-auth"
)
verifier:=webbotauth.NewVerifier(
// Fetch keys only from directories you trust:webbotauth.WithDirectoryAllowlist("operator.openai.com", ".webdecoy.com"),
// ...or verify anything that signs (guarded dialer): webbotauth.WithOpenDirectories(),
)
funchandler(w http.ResponseWriter, r*http.Request) {
res:=verifier.Verify(r.Context(), webbotauth.RequestFromHTTP(r))
switchres.Status {
casewebbotauth.StatusVerified:
// res.Agent, res.KeyID, res.Algorithm identify the signer.casewebbotauth.StatusInvalid:
// The request *claimed* a signed identity and failed to prove it.// res.Errors says why. Treat as a detection signal.casewebbotauth.StatusNoSignature:
// Plain traffic.
}
}

Behind a TLS-terminating proxy pass the original scheme: webbotauth.RequestFromHTTP(r, webbotauth.WithScheme("https")).

Sign outbound requests (operate a bot)

signer, _:=webbotauth.NewSigner(ed25519Key,
webbotauth.WithSignatureAgent("https://mybot.example"), // origin serving your key directory
)
req, _:=http.NewRequest("GET", "https://example.com/page", nil)
_=signer.SignRequest(req) // sets Signature, Signature-Input, Signature-Agent

Publish signer.PublicJWK() in a JWK Set at https://mybot.example/.well-known/http-message-signatures-directory.

Packages

PackageContents
webbotauth (root)Verifier, Signer, JWK/KeySet, Signature-Agent parsing, directory client
httpsigThe RFC 9421 profile Web Bot Auth uses: signature base construction, header parsing, Ed25519 + RSASSA-PSS-SHA512
thumbprintRFC 7638 / RFC 8037 JWK thumbprints (Web Bot Auth's keyid)

Spec status

Implements draft-meunier-webbotauth-httpsig-protocol-02 (August 2026) and draft-meunier-webbotauth-httpsig-directory-00 (June 2026), plus the earlier architecture draft's wire forms for compatibility with deployed signers. The IETF webbotauth working group is active; releases are tagged against draft revisions and this README states the pinned revision.

Profile boundary (deliberate non-goals)

This is a Web Bot Auth implementation, not a general RFC 9421 library: no response signing, no request-response binding, no Accept-Signature negotiation, no HMAC/ECDSA, derived components limited to the request set. If a future draft needs more, the profile grows with it — the point is that what's here is exactly what the protocol exercises, tested against the reference vectors.

Security model

  • Directory URLs come from the request under verification — they are attacker-controlled input. The default fetch client is https-only, refuses loopback/private/link-local addresses in open mode, caps responses at 1 MiB, and re-checks policy on every redirect hop. Supplying your own http.Client transfers that responsibility to you.
  • Verification failures never panic and never error out of Verify; malformed input from the network is a classification, not an exception. Both parsers are fuzzed in CI.
  • Replay defense is delegated: signatures carry nonces, and WithNonceChecker hands enforcement to your store (memory, Redis, ...). The default accepts any nonce within the signature's validity window, per the draft's baseline.

License

Apache 2.0. Portions ported from cloudflare/web-bot-auth (Apache 2.0) — see NOTICE. Test vectors copied verbatim from that repository.

About

Web Bot Auth for Go — verify and produce RFC 9421 signatures for bots and AI agents. Zero dependencies, cross-validated against the reference implementation.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

web-bot-auth (Go)

Verify and produce Web Bot Auth signatures in Go — cryptographic identity for bots and AI agents, with zero dependencies.

CI

Web Bot Auth replaces spoofable user-agent strings with cryptographic proof: agents sign each request with RFC 9421 HTTP Message Signatures (tag web-bot-auth), publish their public keys in an HTTP Message Signatures directory, and identify the directory via the Signature-Agent header. OpenAI signs Operator requests today; Cloudflare, Vercel, and AWS WAF verify at their edges. This module lets any Go service do the same.

Built and maintained by WebDecoy. Ported from and cross-validated against cloudflare/web-bot-auth — the reference implementation's test vectors run in this repo's CI.

  • Zero dependenciescrypto/ed25519, crypto/rsa, and the standard library only.
  • Both draft generations — the current Signature-Agent dictionary form with key="..." member extraction, and the earlier bare-string form deployed signers still send.
  • Verification is a verdict, not an errorno-signature / verified / invalid, designed for detection pipelines where an invalid claim of agent identity is the most interesting outcome.
  • SSRF-guarded key discovery — https-only, host allowlist (or explicit open mode with a non-global-address dialer), size caps, per-hop redirect re-validation, TTL + stale-while-revalidate caching.

Install

go get github.com/WebDecoy/web-bot-auth

Verify inbound requests

import (
"net/http"
webbotauth "github.com/WebDecoy/web-bot-auth"
)
verifier:=webbotauth.NewVerifier(
// Fetch keys only from directories you trust:webbotauth.WithDirectoryAllowlist("operator.openai.com", ".webdecoy.com"),
// ...or verify anything that signs (guarded dialer): webbotauth.WithOpenDirectories(),
)
funchandler(w http.ResponseWriter, r*http.Request) {
res:=verifier.Verify(r.Context(), webbotauth.RequestFromHTTP(r))
switchres.Status {
casewebbotauth.StatusVerified:
// res.Agent, res.KeyID, res.Algorithm identify the signer.casewebbotauth.StatusInvalid:
// The request *claimed* a signed identity and failed to prove it.// res.Errors says why. Treat as a detection signal.casewebbotauth.StatusNoSignature:
// Plain traffic.
}
}

Behind a TLS-terminating proxy pass the original scheme: webbotauth.RequestFromHTTP(r, webbotauth.WithScheme("https")).

Sign outbound requests (operate a bot)

signer, _:=webbotauth.NewSigner(ed25519Key,
webbotauth.WithSignatureAgent("https://mybot.example"), // origin serving your key directory
)
req, _:=http.NewRequest("GET", "https://example.com/page", nil)
_=signer.SignRequest(req) // sets Signature, Signature-Input, Signature-Agent

Publish signer.PublicJWK() in a JWK Set at https://mybot.example/.well-known/http-message-signatures-directory.

Packages

PackageContents
webbotauth (root)Verifier, Signer, JWK/KeySet, Signature-Agent parsing, directory client
httpsigThe RFC 9421 profile Web Bot Auth uses: signature base construction, header parsing, Ed25519 + RSASSA-PSS-SHA512
thumbprintRFC 7638 / RFC 8037 JWK thumbprints (Web Bot Auth's keyid)

Spec status

Implements draft-meunier-webbotauth-httpsig-protocol-02 (August 2026) and draft-meunier-webbotauth-httpsig-directory-00 (June 2026), plus the earlier architecture draft's wire forms for compatibility with deployed signers. The IETF webbotauth working group is active; releases are tagged against draft revisions and this README states the pinned revision.

Profile boundary (deliberate non-goals)

This is a Web Bot Auth implementation, not a general RFC 9421 library: no response signing, no request-response binding, no Accept-Signature negotiation, no HMAC/ECDSA, derived components limited to the request set. If a future draft needs more, the profile grows with it — the point is that what's here is exactly what the protocol exercises, tested against the reference vectors.

Security model

  • Directory URLs come from the request under verification — they are attacker-controlled input. The default fetch client is https-only, refuses loopback/private/link-local addresses in open mode, caps responses at 1 MiB, and re-checks policy on every redirect hop. Supplying your own http.Client transfers that responsibility to you.
  • Verification failures never panic and never error out of Verify; malformed input from the network is a classification, not an exception. Both parsers are fuzzed in CI.
  • Replay defense is delegated: signatures carry nonces, and WithNonceChecker hands enforcement to your store (memory, Redis, ...). The default accepts any nonce within the signature's validity window, per the draft's baseline.

License

Apache 2.0. Portions ported from cloudflare/web-bot-auth (Apache 2.0) — see NOTICE. Test vectors copied verbatim from that repository.

About

Web Bot Auth for Go — verify and produce RFC 9421 signatures for bots and AI agents. Zero dependencies, cross-validated against the reference implementation.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

web-bot-auth (Go)

Verify and produce Web Bot Auth signatures in Go — cryptographic identity for bots and AI agents, with zero dependencies.

CI

Web Bot Auth replaces spoofable user-agent strings with cryptographic proof: agents sign each request with RFC 9421 HTTP Message Signatures (tag web-bot-auth), publish their public keys in an HTTP Message Signatures directory, and identify the directory via the Signature-Agent header. OpenAI signs Operator requests today; Cloudflare, Vercel, and AWS WAF verify at their edges. This module lets any Go service do the same.

Built and maintained by WebDecoy. Ported from and cross-validated against cloudflare/web-bot-auth — the reference implementation's test vectors run in this repo's CI.

  • Zero dependenciescrypto/ed25519, crypto/rsa, and the standard library only.
  • Both draft generations — the current Signature-Agent dictionary form with key="..." member extraction, and the earlier bare-string form deployed signers still send.
  • Verification is a verdict, not an errorno-signature / verified / invalid, designed for detection pipelines where an invalid claim of agent identity is the most interesting outcome.
  • SSRF-guarded key discovery — https-only, host allowlist (or explicit open mode with a non-global-address dialer), size caps, per-hop redirect re-validation, TTL + stale-while-revalidate caching.

Install

go get github.com/WebDecoy/web-bot-auth

Verify inbound requests

import (
"net/http"
webbotauth "github.com/WebDecoy/web-bot-auth"
)
verifier:=webbotauth.NewVerifier(
// Fetch keys only from directories you trust:webbotauth.WithDirectoryAllowlist("operator.openai.com", ".webdecoy.com"),
// ...or verify anything that signs (guarded dialer): webbotauth.WithOpenDirectories(),
)
funchandler(w http.ResponseWriter, r*http.Request) {
res:=verifier.Verify(r.Context(), webbotauth.RequestFromHTTP(r))
switchres.Status {
casewebbotauth.StatusVerified:
// res.Agent, res.KeyID, res.Algorithm identify the signer.casewebbotauth.StatusInvalid:
// The request *claimed* a signed identity and failed to prove it.// res.Errors says why. Treat as a detection signal.casewebbotauth.StatusNoSignature:
// Plain traffic.
}
}

Behind a TLS-terminating proxy pass the original scheme: webbotauth.RequestFromHTTP(r, webbotauth.WithScheme("https")).

Sign outbound requests (operate a bot)

signer, _:=webbotauth.NewSigner(ed25519Key,
webbotauth.WithSignatureAgent("https://mybot.example"), // origin serving your key directory
)
req, _:=http.NewRequest("GET", "https://example.com/page", nil)
_=signer.SignRequest(req) // sets Signature, Signature-Input, Signature-Agent

Publish signer.PublicJWK() in a JWK Set at https://mybot.example/.well-known/http-message-signatures-directory.

Packages

PackageContents
webbotauth (root)Verifier, Signer, JWK/KeySet, Signature-Agent parsing, directory client
httpsigThe RFC 9421 profile Web Bot Auth uses: signature base construction, header parsing, Ed25519 + RSASSA-PSS-SHA512
thumbprintRFC 7638 / RFC 8037 JWK thumbprints (Web Bot Auth's keyid)

Spec status

Implements draft-meunier-webbotauth-httpsig-protocol-02 (August 2026) and draft-meunier-webbotauth-httpsig-directory-00 (June 2026), plus the earlier architecture draft's wire forms for compatibility with deployed signers. The IETF webbotauth working group is active; releases are tagged against draft revisions and this README states the pinned revision.

Profile boundary (deliberate non-goals)

This is a Web Bot Auth implementation, not a general RFC 9421 library: no response signing, no request-response binding, no Accept-Signature negotiation, no HMAC/ECDSA, derived components limited to the request set. If a future draft needs more, the profile grows with it — the point is that what's here is exactly what the protocol exercises, tested against the reference vectors.

Security model

  • Directory URLs come from the request under verification — they are attacker-controlled input. The default fetch client is https-only, refuses loopback/private/link-local addresses in open mode, caps responses at 1 MiB, and re-checks policy on every redirect hop. Supplying your own http.Client transfers that responsibility to you.
  • Verification failures never panic and never error out of Verify; malformed input from the network is a classification, not an exception. Both parsers are fuzzed in CI.
  • Replay defense is delegated: signatures carry nonces, and WithNonceChecker hands enforcement to your store (memory, Redis, ...). The default accepts any nonce within the signature's validity window, per the draft's baseline.

License

Apache 2.0. Portions ported from cloudflare/web-bot-auth (Apache 2.0) — see NOTICE. Test vectors copied verbatim from that repository.

About

Web Bot Auth for Go — verify and produce RFC 9421 signatures for bots and AI agents. Zero dependencies, cross-validated against the reference implementation.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

web-bot-auth (Go)

Verify and produce Web Bot Auth signatures in Go — cryptographic identity for bots and AI agents, with zero dependencies.

CI

Web Bot Auth replaces spoofable user-agent strings with cryptographic proof: agents sign each request with RFC 9421 HTTP Message Signatures (tag web-bot-auth), publish their public keys in an HTTP Message Signatures directory, and identify the directory via the Signature-Agent header. OpenAI signs Operator requests today; Cloudflare, Vercel, and AWS WAF verify at their edges. This module lets any Go service do the same.

Built and maintained by WebDecoy. Ported from and cross-validated against cloudflare/web-bot-auth — the reference implementation's test vectors run in this repo's CI.

  • Zero dependenciescrypto/ed25519, crypto/rsa, and the standard library only.
  • Both draft generations — the current Signature-Agent dictionary form with key="..." member extraction, and the earlier bare-string form deployed signers still send.
  • Verification is a verdict, not an errorno-signature / verified / invalid, designed for detection pipelines where an invalid claim of agent identity is the most interesting outcome.
  • SSRF-guarded key discovery — https-only, host allowlist (or explicit open mode with a non-global-address dialer), size caps, per-hop redirect re-validation, TTL + stale-while-revalidate caching.

Install

go get github.com/WebDecoy/web-bot-auth

Verify inbound requests

import (
"net/http"
webbotauth "github.com/WebDecoy/web-bot-auth"
)
verifier:=webbotauth.NewVerifier(
// Fetch keys only from directories you trust:webbotauth.WithDirectoryAllowlist("operator.openai.com", ".webdecoy.com"),
// ...or verify anything that signs (guarded dialer): webbotauth.WithOpenDirectories(),
)
funchandler(w http.ResponseWriter, r*http.Request) {
res:=verifier.Verify(r.Context(), webbotauth.RequestFromHTTP(r))
switchres.Status {
casewebbotauth.StatusVerified:
// res.Agent, res.KeyID, res.Algorithm identify the signer.casewebbotauth.StatusInvalid:
// The request *claimed* a signed identity and failed to prove it.// res.Errors says why. Treat as a detection signal.casewebbotauth.StatusNoSignature:
// Plain traffic.
}
}

Behind a TLS-terminating proxy pass the original scheme: webbotauth.RequestFromHTTP(r, webbotauth.WithScheme("https")).

Sign outbound requests (operate a bot)

signer, _:=webbotauth.NewSigner(ed25519Key,
webbotauth.WithSignatureAgent("https://mybot.example"), // origin serving your key directory
)
req, _:=http.NewRequest("GET", "https://example.com/page", nil)
_=signer.SignRequest(req) // sets Signature, Signature-Input, Signature-Agent

Publish signer.PublicJWK() in a JWK Set at https://mybot.example/.well-known/http-message-signatures-directory.

Packages

PackageContents
webbotauth (root)Verifier, Signer, JWK/KeySet, Signature-Agent parsing, directory client
httpsigThe RFC 9421 profile Web Bot Auth uses: signature base construction, header parsing, Ed25519 + RSASSA-PSS-SHA512
thumbprintRFC 7638 / RFC 8037 JWK thumbprints (Web Bot Auth's keyid)

Spec status

Implements draft-meunier-webbotauth-httpsig-protocol-02 (August 2026) and draft-meunier-webbotauth-httpsig-directory-00 (June 2026), plus the earlier architecture draft's wire forms for compatibility with deployed signers. The IETF webbotauth working group is active; releases are tagged against draft revisions and this README states the pinned revision.

Profile boundary (deliberate non-goals)

This is a Web Bot Auth implementation, not a general RFC 9421 library: no response signing, no request-response binding, no Accept-Signature negotiation, no HMAC/ECDSA, derived components limited to the request set. If a future draft needs more, the profile grows with it — the point is that what's here is exactly what the protocol exercises, tested against the reference vectors.

Security model

  • Directory URLs come from the request under verification — they are attacker-controlled input. The default fetch client is https-only, refuses loopback/private/link-local addresses in open mode, caps responses at 1 MiB, and re-checks policy on every redirect hop. Supplying your own http.Client transfers that responsibility to you.
  • Verification failures never panic and never error out of Verify; malformed input from the network is a classification, not an exception. Both parsers are fuzzed in CI.
  • Replay defense is delegated: signatures carry nonces, and WithNonceChecker hands enforcement to your store (memory, Redis, ...). The default accepts any nonce within the signature's validity window, per the draft's baseline.

License

Apache 2.0. Portions ported from cloudflare/web-bot-auth (Apache 2.0) — see NOTICE. Test vectors copied verbatim from that repository.

About

Web Bot Auth for Go — verify and produce RFC 9421 signatures for bots and AI agents. Zero dependencies, cross-validated against the reference implementation.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

web-bot-auth (Go)

Verify and produce Web Bot Auth signatures in Go — cryptographic identity for bots and AI agents, with zero dependencies.

CI

Web Bot Auth replaces spoofable user-agent strings with cryptographic proof: agents sign each request with RFC 9421 HTTP Message Signatures (tag web-bot-auth), publish their public keys in an HTTP Message Signatures directory, and identify the directory via the Signature-Agent header. OpenAI signs Operator requests today; Cloudflare, Vercel, and AWS WAF verify at their edges. This module lets any Go service do the same.

Built and maintained by WebDecoy. Ported from and cross-validated against cloudflare/web-bot-auth — the reference implementation's test vectors run in this repo's CI.

  • Zero dependenciescrypto/ed25519, crypto/rsa, and the standard library only.
  • Both draft generations — the current Signature-Agent dictionary form with key="..." member extraction, and the earlier bare-string form deployed signers still send.
  • Verification is a verdict, not an errorno-signature / verified / invalid, designed for detection pipelines where an invalid claim of agent identity is the most interesting outcome.
  • SSRF-guarded key discovery — https-only, host allowlist (or explicit open mode with a non-global-address dialer), size caps, per-hop redirect re-validation, TTL + stale-while-revalidate caching.

Install

go get github.com/WebDecoy/web-bot-auth

Verify inbound requests

import (
"net/http"
webbotauth "github.com/WebDecoy/web-bot-auth"
)
verifier:=webbotauth.NewVerifier(
// Fetch keys only from directories you trust:webbotauth.WithDirectoryAllowlist("operator.openai.com", ".webdecoy.com"),
// ...or verify anything that signs (guarded dialer): webbotauth.WithOpenDirectories(),
)
funchandler(w http.ResponseWriter, r*http.Request) {
res:=verifier.Verify(r.Context(), webbotauth.RequestFromHTTP(r))
switchres.Status {
casewebbotauth.StatusVerified:
// res.Agent, res.KeyID, res.Algorithm identify the signer.casewebbotauth.StatusInvalid:
// The request *claimed* a signed identity and failed to prove it.// res.Errors says why. Treat as a detection signal.casewebbotauth.StatusNoSignature:
// Plain traffic.
}
}

Behind a TLS-terminating proxy pass the original scheme: webbotauth.RequestFromHTTP(r, webbotauth.WithScheme("https")).

Sign outbound requests (operate a bot)

signer, _:=webbotauth.NewSigner(ed25519Key,
webbotauth.WithSignatureAgent("https://mybot.example"), // origin serving your key directory
)
req, _:=http.NewRequest("GET", "https://example.com/page", nil)
_=signer.SignRequest(req) // sets Signature, Signature-Input, Signature-Agent

Publish signer.PublicJWK() in a JWK Set at https://mybot.example/.well-known/http-message-signatures-directory.

Packages

PackageContents
webbotauth (root)Verifier, Signer, JWK/KeySet, Signature-Agent parsing, directory client
httpsigThe RFC 9421 profile Web Bot Auth uses: signature base construction, header parsing, Ed25519 + RSASSA-PSS-SHA512
thumbprintRFC 7638 / RFC 8037 JWK thumbprints (Web Bot Auth's keyid)

Spec status

Implements draft-meunier-webbotauth-httpsig-protocol-02 (August 2026) and draft-meunier-webbotauth-httpsig-directory-00 (June 2026), plus the earlier architecture draft's wire forms for compatibility with deployed signers. The IETF webbotauth working group is active; releases are tagged against draft revisions and this README states the pinned revision.

Profile boundary (deliberate non-goals)

This is a Web Bot Auth implementation, not a general RFC 9421 library: no response signing, no request-response binding, no Accept-Signature negotiation, no HMAC/ECDSA, derived components limited to the request set. If a future draft needs more, the profile grows with it — the point is that what's here is exactly what the protocol exercises, tested against the reference vectors.

Security model

  • Directory URLs come from the request under verification — they are attacker-controlled input. The default fetch client is https-only, refuses loopback/private/link-local addresses in open mode, caps responses at 1 MiB, and re-checks policy on every redirect hop. Supplying your own http.Client transfers that responsibility to you.
  • Verification failures never panic and never error out of Verify; malformed input from the network is a classification, not an exception. Both parsers are fuzzed in CI.
  • Replay defense is delegated: signatures carry nonces, and WithNonceChecker hands enforcement to your store (memory, Redis, ...). The default accepts any nonce within the signature's validity window, per the draft's baseline.

License

Apache 2.0. Portions ported from cloudflare/web-bot-auth (Apache 2.0) — see NOTICE. Test vectors copied verbatim from that repository.

About

Web Bot Auth for Go — verify and produce RFC 9421 signatures for bots and AI agents. Zero dependencies, cross-validated against the reference implementation.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

web-bot-auth (Go)

Verify and produce Web Bot Auth signatures in Go — cryptographic identity for bots and AI agents, with zero dependencies.

CI

Web Bot Auth replaces spoofable user-agent strings with cryptographic proof: agents sign each request with RFC 9421 HTTP Message Signatures (tag web-bot-auth), publish their public keys in an HTTP Message Signatures directory, and identify the directory via the Signature-Agent header. OpenAI signs Operator requests today; Cloudflare, Vercel, and AWS WAF verify at their edges. This module lets any Go service do the same.

Built and maintained by WebDecoy. Ported from and cross-validated against cloudflare/web-bot-auth — the reference implementation's test vectors run in this repo's CI.

  • Zero dependenciescrypto/ed25519, crypto/rsa, and the standard library only.
  • Both draft generations — the current Signature-Agent dictionary form with key="..." member extraction, and the earlier bare-string form deployed signers still send.
  • Verification is a verdict, not an errorno-signature / verified / invalid, designed for detection pipelines where an invalid claim of agent identity is the most interesting outcome.
  • SSRF-guarded key discovery — https-only, host allowlist (or explicit open mode with a non-global-address dialer), size caps, per-hop redirect re-validation, TTL + stale-while-revalidate caching.

Install

go get github.com/WebDecoy/web-bot-auth

Verify inbound requests

import (
"net/http"
webbotauth "github.com/WebDecoy/web-bot-auth"
)
verifier:=webbotauth.NewVerifier(
// Fetch keys only from directories you trust:webbotauth.WithDirectoryAllowlist("operator.openai.com", ".webdecoy.com"),
// ...or verify anything that signs (guarded dialer): webbotauth.WithOpenDirectories(),
)
funchandler(w http.ResponseWriter, r*http.Request) {
res:=verifier.Verify(r.Context(), webbotauth.RequestFromHTTP(r))
switchres.Status {
casewebbotauth.StatusVerified:
// res.Agent, res.KeyID, res.Algorithm identify the signer.casewebbotauth.StatusInvalid:
// The request *claimed* a signed identity and failed to prove it.// res.Errors says why. Treat as a detection signal.casewebbotauth.StatusNoSignature:
// Plain traffic.
}
}

Behind a TLS-terminating proxy pass the original scheme: webbotauth.RequestFromHTTP(r, webbotauth.WithScheme("https")).

Sign outbound requests (operate a bot)

signer, _:=webbotauth.NewSigner(ed25519Key,
webbotauth.WithSignatureAgent("https://mybot.example"), // origin serving your key directory
)
req, _:=http.NewRequest("GET", "https://example.com/page", nil)
_=signer.SignRequest(req) // sets Signature, Signature-Input, Signature-Agent

Publish signer.PublicJWK() in a JWK Set at https://mybot.example/.well-known/http-message-signatures-directory.

Packages

PackageContents
webbotauth (root)Verifier, Signer, JWK/KeySet, Signature-Agent parsing, directory client
httpsigThe RFC 9421 profile Web Bot Auth uses: signature base construction, header parsing, Ed25519 + RSASSA-PSS-SHA512
thumbprintRFC 7638 / RFC 8037 JWK thumbprints (Web Bot Auth's keyid)

Spec status

Implements draft-meunier-webbotauth-httpsig-protocol-02 (August 2026) and draft-meunier-webbotauth-httpsig-directory-00 (June 2026), plus the earlier architecture draft's wire forms for compatibility with deployed signers. The IETF webbotauth working group is active; releases are tagged against draft revisions and this README states the pinned revision.

Profile boundary (deliberate non-goals)

This is a Web Bot Auth implementation, not a general RFC 9421 library: no response signing, no request-response binding, no Accept-Signature negotiation, no HMAC/ECDSA, derived components limited to the request set. If a future draft needs more, the profile grows with it — the point is that what's here is exactly what the protocol exercises, tested against the reference vectors.

Security model

  • Directory URLs come from the request under verification — they are attacker-controlled input. The default fetch client is https-only, refuses loopback/private/link-local addresses in open mode, caps responses at 1 MiB, and re-checks policy on every redirect hop. Supplying your own http.Client transfers that responsibility to you.
  • Verification failures never panic and never error out of Verify; malformed input from the network is a classification, not an exception. Both parsers are fuzzed in CI.
  • Replay defense is delegated: signatures carry nonces, and WithNonceChecker hands enforcement to your store (memory, Redis, ...). The default accepts any nonce within the signature's validity window, per the draft's baseline.

License

Apache 2.0. Portions ported from cloudflare/web-bot-auth (Apache 2.0) — see NOTICE. Test vectors copied verbatim from that repository.

About

Web Bot Auth for Go — verify and produce RFC 9421 signatures for bots and AI agents. Zero dependencies, cross-validated against the reference implementation.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

web-bot-auth (Go)

Verify and produce Web Bot Auth signatures in Go — cryptographic identity for bots and AI agents, with zero dependencies.

CI

Web Bot Auth replaces spoofable user-agent strings with cryptographic proof: agents sign each request with RFC 9421 HTTP Message Signatures (tag web-bot-auth), publish their public keys in an HTTP Message Signatures directory, and identify the directory via the Signature-Agent header. OpenAI signs Operator requests today; Cloudflare, Vercel, and AWS WAF verify at their edges. This module lets any Go service do the same.

Built and maintained by WebDecoy. Ported from and cross-validated against cloudflare/web-bot-auth — the reference implementation's test vectors run in this repo's CI.

  • Zero dependenciescrypto/ed25519, crypto/rsa, and the standard library only.
  • Both draft generations — the current Signature-Agent dictionary form with key="..." member extraction, and the earlier bare-string form deployed signers still send.
  • Verification is a verdict, not an errorno-signature / verified / invalid, designed for detection pipelines where an invalid claim of agent identity is the most interesting outcome.
  • SSRF-guarded key discovery — https-only, host allowlist (or explicit open mode with a non-global-address dialer), size caps, per-hop redirect re-validation, TTL + stale-while-revalidate caching.

Install

go get github.com/WebDecoy/web-bot-auth

Verify inbound requests

import (
"net/http"
webbotauth "github.com/WebDecoy/web-bot-auth"
)
verifier:=webbotauth.NewVerifier(
// Fetch keys only from directories you trust:webbotauth.WithDirectoryAllowlist("operator.openai.com", ".webdecoy.com"),
// ...or verify anything that signs (guarded dialer): webbotauth.WithOpenDirectories(),
)
funchandler(w http.ResponseWriter, r*http.Request) {
res:=verifier.Verify(r.Context(), webbotauth.RequestFromHTTP(r))
switchres.Status {
casewebbotauth.StatusVerified:
// res.Agent, res.KeyID, res.Algorithm identify the signer.casewebbotauth.StatusInvalid:
// The request *claimed* a signed identity and failed to prove it.// res.Errors says why. Treat as a detection signal.casewebbotauth.StatusNoSignature:
// Plain traffic.
}
}

Behind a TLS-terminating proxy pass the original scheme: webbotauth.RequestFromHTTP(r, webbotauth.WithScheme("https")).

Sign outbound requests (operate a bot)

signer, _:=webbotauth.NewSigner(ed25519Key,
webbotauth.WithSignatureAgent("https://mybot.example"), // origin serving your key directory
)
req, _:=http.NewRequest("GET", "https://example.com/page", nil)
_=signer.SignRequest(req) // sets Signature, Signature-Input, Signature-Agent

Publish signer.PublicJWK() in a JWK Set at https://mybot.example/.well-known/http-message-signatures-directory.

Packages

PackageContents
webbotauth (root)Verifier, Signer, JWK/KeySet, Signature-Agent parsing, directory client
httpsigThe RFC 9421 profile Web Bot Auth uses: signature base construction, header parsing, Ed25519 + RSASSA-PSS-SHA512
thumbprintRFC 7638 / RFC 8037 JWK thumbprints (Web Bot Auth's keyid)

Spec status

Implements draft-meunier-webbotauth-httpsig-protocol-02 (August 2026) and draft-meunier-webbotauth-httpsig-directory-00 (June 2026), plus the earlier architecture draft's wire forms for compatibility with deployed signers. The IETF webbotauth working group is active; releases are tagged against draft revisions and this README states the pinned revision.

Profile boundary (deliberate non-goals)

This is a Web Bot Auth implementation, not a general RFC 9421 library: no response signing, no request-response binding, no Accept-Signature negotiation, no HMAC/ECDSA, derived components limited to the request set. If a future draft needs more, the profile grows with it — the point is that what's here is exactly what the protocol exercises, tested against the reference vectors.

Security model

  • Directory URLs come from the request under verification — they are attacker-controlled input. The default fetch client is https-only, refuses loopback/private/link-local addresses in open mode, caps responses at 1 MiB, and re-checks policy on every redirect hop. Supplying your own http.Client transfers that responsibility to you.
  • Verification failures never panic and never error out of Verify; malformed input from the network is a classification, not an exception. Both parsers are fuzzed in CI.
  • Replay defense is delegated: signatures carry nonces, and WithNonceChecker hands enforcement to your store (memory, Redis, ...). The default accepts any nonce within the signature's validity window, per the draft's baseline.

License

Apache 2.0. Portions ported from cloudflare/web-bot-auth (Apache 2.0) — see NOTICE. Test vectors copied verbatim from that repository.

About

Web Bot Auth for Go — verify and produce RFC 9421 signatures for bots and AI agents. Zero dependencies, cross-validated against the reference implementation.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

web-bot-auth (Go)

Verify and produce Web Bot Auth signatures in Go — cryptographic identity for bots and AI agents, with zero dependencies.

CI

Web Bot Auth replaces spoofable user-agent strings with cryptographic proof: agents sign each request with RFC 9421 HTTP Message Signatures (tag web-bot-auth), publish their public keys in an HTTP Message Signatures directory, and identify the directory via the Signature-Agent header. OpenAI signs Operator requests today; Cloudflare, Vercel, and AWS WAF verify at their edges. This module lets any Go service do the same.

Built and maintained by WebDecoy. Ported from and cross-validated against cloudflare/web-bot-auth — the reference implementation's test vectors run in this repo's CI.

  • Zero dependenciescrypto/ed25519, crypto/rsa, and the standard library only.
  • Both draft generations — the current Signature-Agent dictionary form with key="..." member extraction, and the earlier bare-string form deployed signers still send.
  • Verification is a verdict, not an errorno-signature / verified / invalid, designed for detection pipelines where an invalid claim of agent identity is the most interesting outcome.
  • SSRF-guarded key discovery — https-only, host allowlist (or explicit open mode with a non-global-address dialer), size caps, per-hop redirect re-validation, TTL + stale-while-revalidate caching.

Install

go get github.com/WebDecoy/web-bot-auth

Verify inbound requests

import (
"net/http"
webbotauth "github.com/WebDecoy/web-bot-auth"
)
verifier:=webbotauth.NewVerifier(
// Fetch keys only from directories you trust:webbotauth.WithDirectoryAllowlist("operator.openai.com", ".webdecoy.com"),
// ...or verify anything that signs (guarded dialer): webbotauth.WithOpenDirectories(),
)
funchandler(w http.ResponseWriter, r*http.Request) {
res:=verifier.Verify(r.Context(), webbotauth.RequestFromHTTP(r))
switchres.Status {
casewebbotauth.StatusVerified:
// res.Agent, res.KeyID, res.Algorithm identify the signer.casewebbotauth.StatusInvalid:
// The request *claimed* a signed identity and failed to prove it.// res.Errors says why. Treat as a detection signal.casewebbotauth.StatusNoSignature:
// Plain traffic.
}
}

Behind a TLS-terminating proxy pass the original scheme: webbotauth.RequestFromHTTP(r, webbotauth.WithScheme("https")).

Sign outbound requests (operate a bot)

signer, _:=webbotauth.NewSigner(ed25519Key,
webbotauth.WithSignatureAgent("https://mybot.example"), // origin serving your key directory
)
req, _:=http.NewRequest("GET", "https://example.com/page", nil)
_=signer.SignRequest(req) // sets Signature, Signature-Input, Signature-Agent

Publish signer.PublicJWK() in a JWK Set at https://mybot.example/.well-known/http-message-signatures-directory.

Packages

PackageContents
webbotauth (root)Verifier, Signer, JWK/KeySet, Signature-Agent parsing, directory client
httpsigThe RFC 9421 profile Web Bot Auth uses: signature base construction, header parsing, Ed25519 + RSASSA-PSS-SHA512
thumbprintRFC 7638 / RFC 8037 JWK thumbprints (Web Bot Auth's keyid)

Spec status

Implements draft-meunier-webbotauth-httpsig-protocol-02 (August 2026) and draft-meunier-webbotauth-httpsig-directory-00 (June 2026), plus the earlier architecture draft's wire forms for compatibility with deployed signers. The IETF webbotauth working group is active; releases are tagged against draft revisions and this README states the pinned revision.

Profile boundary (deliberate non-goals)

This is a Web Bot Auth implementation, not a general RFC 9421 library: no response signing, no request-response binding, no Accept-Signature negotiation, no HMAC/ECDSA, derived components limited to the request set. If a future draft needs more, the profile grows with it — the point is that what's here is exactly what the protocol exercises, tested against the reference vectors.

Security model

  • Directory URLs come from the request under verification — they are attacker-controlled input. The default fetch client is https-only, refuses loopback/private/link-local addresses in open mode, caps responses at 1 MiB, and re-checks policy on every redirect hop. Supplying your own http.Client transfers that responsibility to you.
  • Verification failures never panic and never error out of Verify; malformed input from the network is a classification, not an exception. Both parsers are fuzzed in CI.
  • Replay defense is delegated: signatures carry nonces, and WithNonceChecker hands enforcement to your store (memory, Redis, ...). The default accepts any nonce within the signature's validity window, per the draft's baseline.

License

Apache 2.0. Portions ported from cloudflare/web-bot-auth (Apache 2.0) — see NOTICE. Test vectors copied verbatim from that repository.

About

Web Bot Auth for Go — verify and produce RFC 9421 signatures for bots and AI agents. Zero dependencies, cross-validated against the reference implementation.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages