web-agent-bridge 3.17.0 → 3.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.ar.md +27 -8
  2. package/README.md +95 -0
  3. package/bin/wab-init.js +38 -0
  4. package/package.json +1 -1
  5. package/public/atp-semantics.html +216 -0
  6. package/public/benchmarks.html +151 -0
  7. package/public/docs.html +113 -43
  8. package/public/index.html +142 -8
  9. package/public/key-rotation.html +184 -0
  10. package/public/llms.txt +54 -0
  11. package/public/notary.html +94 -0
  12. package/public/observatory.html +103 -0
  13. package/public/research.html +57 -0
  14. package/public/researchers.html +113 -0
  15. package/public/responsible-disclosure.html +294 -0
  16. package/public/robots.txt +17 -0
  17. package/public/security.html +157 -0
  18. package/public/threat-model.html +153 -0
  19. package/public/viral-coefficient.html +533 -0
  20. package/public/wab-dataset.html +501 -0
  21. package/public/wab-email.html +78 -0
  22. package/public/wab-lens.html +61 -0
  23. package/public/wab-p2p.html +96 -0
  24. package/public/wab-registry.html +481 -0
  25. package/public/wab-today.html +448 -0
  26. package/public/wab-uri.html +88 -0
  27. package/script/ai-agent-bridge.js +24 -4
  28. package/server/index.js +1193 -827
  29. package/server/models/db.js +2 -1
  30. package/server/routes/admin-shieldlink.js +1 -1
  31. package/server/routes/admin-shieldqr.js +1 -1
  32. package/server/routes/admin-trust-monitor.js +1 -1
  33. package/server/routes/api-keys.js +2 -1
  34. package/server/routes/customer-shieldlink.js +1 -1
  35. package/server/routes/enterprise-mesh.js +2 -1
  36. package/server/routes/genius-bridge.js +256 -0
  37. package/server/routes/genius-gateway.js +137 -0
  38. package/server/routes/governance-saas.js +2 -1
  39. package/server/routes/notary.js +309 -0
  40. package/server/routes/observatory.js +109 -0
  41. package/server/routes/partners.js +2 -1
  42. package/server/routes/registry.js +352 -0
  43. package/server/routes/research.js +83 -0
  44. package/server/routes/ring4.js +2 -1
  45. package/server/routes/runtime.js +98 -25
  46. package/server/routes/security-researchers.js +161 -0
  47. package/server/routes/shieldqr.js +1 -1
  48. package/server/routes/traces.js +247 -0
  49. package/server/services/agent-tasks.js +9 -7
  50. package/server/services/email.js +50 -2
  51. package/server/services/marketplace.js +27 -8
  52. package/server/services/plans.js +1 -1
  53. package/server/services/shieldlink.js +1 -1
  54. package/server/services/ssl-ct-monitor.js +1 -1
  55. package/server/services/ssl-monitor.js +1 -1
  56. package/server/services/stripe.js +29 -4
  57. package/server/utils/migrate.js +1 -1
  58. package/server/utils/safe-compare.js +26 -0
@@ -0,0 +1,294 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Responsible Disclosure — Web Agent Bridge</title>
7
+ <meta name="description" content="How to report a security vulnerability in WAB. Safe-harbor, response SLAs, encrypted contact, hall-of-fame opt-in.">
8
+ <link rel="canonical" href="https://webagentbridge.com/responsible-disclosure">
9
+ <link rel="preload" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" as="style" onload="this.onload=null;this.rel='stylesheet'">
10
+ <link rel="stylesheet" href="/css/styles.css?v=3.0.1">
11
+ <style>
12
+ .trust-page { max-width: 920px; margin: 0 auto; padding: 48px 24px 80px; }
13
+ .trust-page h1 { font-size: clamp(1.9rem, 4vw, 2.6rem); margin: 0 0 10px; }
14
+ .trust-page .lead { color: #94a3b8; font-size: 1.1rem; max-width: 760px; }
15
+ .trust-page h2 { margin-top: 48px; border-bottom: 1px solid #1f2937; padding-bottom: 8px; }
16
+ .trust-page table { width: 100%; border-collapse: collapse; margin: 16px 0; background: #10172a; border: 1px solid #1f2937; border-radius: 10px; overflow: hidden; }
17
+ .trust-page th, .trust-page td { padding: 12px 16px; text-align: left; border-bottom: 1px solid #1f2937; vertical-align: top; }
18
+ .trust-page th { background: #0d1322; color: #94a3b8; font-weight: 600; font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.05em; }
19
+ .trust-page code { background: rgba(34,211,238,.08); padding: 2px 6px; border-radius: 4px; font-family: 'JetBrains Mono', monospace; }
20
+ .callout { background: rgba(34,211,238,.07); border: 1px solid rgba(34,211,238,.25); border-radius: 12px; padding: 14px 18px; margin: 18px 0; }
21
+ .callout.danger { background: rgba(248,113,113,.08); border-color: rgba(248,113,113,.35); }
22
+ .callout.soft { background: rgba(168,85,247,.07); border-color: rgba(168,85,247,.30); }
23
+ .contact-card { background: #10172a; border: 1px solid #1f2937; border-radius: 14px; padding: 24px; margin: 24px 0; }
24
+ .contact-card .row { display:flex; justify-content:space-between; padding: 10px 0; border-bottom: 1px solid #1f2937; gap: 16px; flex-wrap: wrap; }
25
+ .contact-card .row:last-child { border-bottom: none; }
26
+ .contact-card .k { color: #94a3b8; font-size: 0.9rem; }
27
+ .contact-card .v { color: #e2e8f0; font-family: 'JetBrains Mono', monospace; font-size: 0.92rem; }
28
+ .form-grid { display: grid; gap: 14px; }
29
+ .form-grid label { display: block; font-size: 0.85rem; color: #94a3b8; margin-bottom: 4px; }
30
+ .form-grid input, .form-grid select, .form-grid textarea {
31
+ width: 100%; background: #0d1322; border: 1px solid #1f2937; border-radius: 8px;
32
+ color: #e2e8f0; padding: 10px 12px; font: inherit; box-sizing: border-box;
33
+ }
34
+ .form-grid textarea { min-height: 80px; resize: vertical; }
35
+ .form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
36
+ @media (max-width: 600px) { .form-row { grid-template-columns: 1fr; } }
37
+ .submit-btn { background: #22d3ee; color: #0b0f17; border: 0; padding: 12px 22px; border-radius: 8px; font-weight: 700; cursor: pointer; }
38
+ .submit-btn[disabled] { opacity: 0.6; cursor: wait; }
39
+ .status-msg { margin-top: 12px; padding: 10px 14px; border-radius: 8px; font-size: 0.9rem; }
40
+ .status-msg.ok { background: rgba(34,197,94,.10); color: #86efac; border:1px solid rgba(34,197,94,.30); }
41
+ .status-msg.err { background: rgba(248,113,113,.10); color: #fca5a5; border:1px solid rgba(248,113,113,.30); }
42
+ </style>
43
+ </head>
44
+ <body>
45
+
46
+ <nav class="navbar">
47
+ <div class="container">
48
+ <a href="/" class="navbar-brand"><div class="brand-icon">⚡</div><span>WAB</span></a>
49
+ <ul class="navbar-links">
50
+ <li><a href="/docs">Docs</a></li>
51
+ <li><a href="/security">Security</a></li>
52
+ <li><a href="/responsible-disclosure" style="color:#f0f4ff;">Disclosure</a></li>
53
+ <li><a href="/researchers">Researchers</a></li>
54
+ </ul>
55
+ <div class="navbar-actions">
56
+ <a href="/login" class="btn btn-ghost">Sign In</a>
57
+ <a href="/register" class="btn btn-primary btn-sm">Get Started</a>
58
+ </div>
59
+ </div>
60
+ </nav>
61
+
62
+ <main class="trust-page">
63
+
64
+ <h1>Responsible Disclosure</h1>
65
+ <p class="lead">
66
+ WAB is an open-core project. We treat security reports as a partnership. If you have found a
67
+ vulnerability in the protocol, the SDK, the server, or our hosted infrastructure, please tell us
68
+ privately first — we will respond, fix it, and credit you (with your permission) on our
69
+ <a href="/researchers" style="color:#22d3ee;">researchers page</a>.
70
+ </p>
71
+
72
+ <h2 id="contact">1. How to report</h2>
73
+ <div class="contact-card">
74
+ <div class="row"><span class="k">Email</span><span class="v">security@webagentbridge.com</span></div>
75
+ <div class="row"><span class="k">PGP key</span><span class="v"><a href="/.well-known/pgp-key.txt" style="color:#22d3ee;">/.well-known/pgp-key.txt</a></span></div>
76
+ <div class="row"><span class="k">security.txt</span><span class="v"><a href="/.well-known/security.txt" style="color:#22d3ee;">/.well-known/security.txt</a></span></div>
77
+ <div class="row"><span class="k">Acknowledge SLA</span><span class="v">≤ 72 hours</span></div>
78
+ <div class="row"><span class="k">Triage SLA</span><span class="v">≤ 7 days</span></div>
79
+ <div class="row"><span class="k">Fix SLA (critical)</span><span class="v">≤ 14 days from triage</span></div>
80
+ </div>
81
+
82
+ <div class="callout danger">
83
+ <strong>Please encrypt</strong> reports of critical issues with our PGP key. If PGP is impractical,
84
+ send an unencrypted summary plus a request for a secure channel, and we will set one up within 24 hours.
85
+ </div>
86
+
87
+ <h2 id="scope">2. Scope</h2>
88
+ <p><strong>In scope:</strong></p>
89
+ <ul>
90
+ <li><code>webagentbridge.com</code> and any subdomain we operate.</li>
91
+ <li>The <code>web-agent-bridge</code> npm package and its SDK packages.</li>
92
+ <li>The WAB protocol itself — signature, discovery, ATP semantics, replay protection, auth middleware.</li>
93
+ <li>The browser SDK (<code>wab.min.js</code>) and the WordPress / Hydrogen / Elementor integrations we publish.</li>
94
+ </ul>
95
+ <p><strong>Out of scope:</strong></p>
96
+ <ul>
97
+ <li>Findings that require a compromised user device, browser extension, or stolen credentials with no further escalation.</li>
98
+ <li>Volumetric DoS without an amplification primitive.</li>
99
+ <li>Self-XSS, missing best-practice headers without a concrete exploit, or social engineering of staff.</li>
100
+ <li>Third-party services we depend on (Stripe, Cloudflare, registrars) — please report those upstream.</li>
101
+ </ul>
102
+
103
+ <h2 id="safe-harbor">3. Safe harbor</h2>
104
+ <p>
105
+ Researchers acting in good faith under this policy are authorised to perform their work and will not be
106
+ pursued under the CFAA, equivalents elsewhere, or our own terms of service, provided they:
107
+ </p>
108
+ <ul>
109
+ <li>Do not access, modify, or destroy data that is not theirs.</li>
110
+ <li>Do not run automated scanning at a rate that materially harms availability.</li>
111
+ <li>Do not extort, threaten, or publicly disclose before coordinated release.</li>
112
+ <li>Stop testing and contact us if they encounter sensitive data unexpectedly.</li>
113
+ </ul>
114
+ <p>We will not pursue legal action against good-faith research that follows this policy.</p>
115
+
116
+ <h2 id="reward">4. Recognition &amp; discretionary rewards</h2>
117
+ <p>
118
+ WAB does <strong>not</strong> currently run a formal Bug Bounty programme. What we offer instead:
119
+ </p>
120
+ <ul>
121
+ <li><strong>Public credit</strong> on <a href="/researchers" style="color:#22d3ee;">/researchers</a> (opt-in; anonymous credit is welcome too).</li>
122
+ <li><strong>A discretionary appreciation reward</strong> may be granted after we verify and fix the issue, based on its real-world severity and our project budget at the time. Typical range for medium findings on an open-source project at this stage is symbolic (e.g. USD 50–200); higher amounts are possible for clearly high-impact, first-reporter findings but are not promised.</li>
123
+ <li><strong>Co-author credit</strong> in the CHANGELOG and the matching CVE / advisory.</li>
124
+ </ul>
125
+ <p style="color:#94a3b8;font-size:0.9rem;">
126
+ By submitting a report you understand that any reward is offered at WAB's sole discretion and is
127
+ not a contractual obligation. Duplicates, low-severity issues, already-patched issues, and reports
128
+ that violate scope or safe-harbor rules are not eligible. The first reporter of a unique, valid
129
+ issue is the one credited and (if applicable) rewarded.
130
+ </p>
131
+
132
+ <div class="callout soft">
133
+ <strong>One friendly ask, not a hard requirement:</strong> if you enjoy what we are building, a
134
+ GitHub ⭐ on
135
+ <a href="https://github.com/web-agent-bridge/web-agent-bridge" target="_blank" rel="noopener" style="color:#a78bfa;">
136
+ github.com/web-agent-bridge/web-agent-bridge</a>
137
+ means a lot for an early-stage open-source project — it helps more sites adopt the WAB protocol,
138
+ which makes the whole web safer for agents. Your report is welcome either way.
139
+ </div>
140
+
141
+ <h2 id="process">5. Process</h2>
142
+ <ol>
143
+ <li><strong>Report</strong> — email <code>security@webagentbridge.com</code> with reproduction steps, affected version, and impact.</li>
144
+ <li><strong>Acknowledge</strong> — we reply within 72 hours.</li>
145
+ <li><strong>Triage</strong> — within 7 days we confirm severity and assign a tracking ID.</li>
146
+ <li><strong>Remediate</strong> — fix and deploy. Critical within 14 days, others within 90 days.</li>
147
+ <li><strong>Credit</strong> — coordinated public advisory after the fix ships, naming the reporter (with permission) on <a href="/researchers" style="color:#22d3ee;">/researchers</a>.</li>
148
+ </ol>
149
+
150
+ <h2 id="hof">6. Hall of fame — submit your name</h2>
151
+ <p>
152
+ Once your report has been verified and fixed, please submit your preferred credit below. Entries are
153
+ reviewed manually before they appear on the public
154
+ <a href="/researchers" style="color:#22d3ee;">/researchers</a> page — this keeps the list meaningful
155
+ and spam-free. Choose <em>Anonymous</em> if you prefer not to be named publicly.
156
+ </p>
157
+
158
+ <form id="hofForm" class="form-grid" autocomplete="off" novalidate>
159
+ <div class="form-row">
160
+ <div>
161
+ <label for="hofName">Display name</label>
162
+ <input id="hofName" name="name" type="text" maxlength="60" placeholder="e.g. Miro Hatachi">
163
+ </div>
164
+ <div>
165
+ <label for="hofHandle">GitHub handle <span style="color:#64748b;">(optional)</span></label>
166
+ <input id="hofHandle" name="githubHandle" type="text" maxlength="40" placeholder="e.g. miro-h">
167
+ </div>
168
+ </div>
169
+ <div class="form-row">
170
+ <div>
171
+ <label for="hofUrl">Profile URL <span style="color:#64748b;">(optional — github / x / linkedin / mastodon)</span></label>
172
+ <input id="hofUrl" name="url" type="url" maxlength="200" placeholder="https://github.com/miro-h">
173
+ </div>
174
+ <div>
175
+ <label for="hofSeverity">Reported severity</label>
176
+ <select id="hofSeverity" name="severity">
177
+ <option value="low">Low</option>
178
+ <option value="medium" selected>Medium</option>
179
+ <option value="high">High</option>
180
+ <option value="critical">Critical</option>
181
+ </select>
182
+ </div>
183
+ </div>
184
+ <div class="form-row">
185
+ <div>
186
+ <label for="hofEmail">Contact email <span style="color:#64748b;">(private — never published)</span></label>
187
+ <input id="hofEmail" name="email" type="email" maxlength="120" placeholder="you@example.com">
188
+ </div>
189
+ <div>
190
+ <label for="hofRef">Report reference <span style="color:#64748b;">(optional)</span></label>
191
+ <input id="hofRef" name="reportRef" type="text" maxlength="120" placeholder="ticket ID, CVE, etc.">
192
+ </div>
193
+ </div>
194
+ <div>
195
+ <label for="hofNote">Short note <span style="color:#64748b;">(optional, max 240 chars — what you reported)</span></label>
196
+ <textarea id="hofNote" name="note" maxlength="240" placeholder="e.g. SSRF on /badge endpoint via DNS-deceptive hostnames"></textarea>
197
+ </div>
198
+ <div>
199
+ <label style="display:flex;align-items:center;gap:8px;cursor:pointer;">
200
+ <input id="hofAnon" name="anonymous" type="checkbox">
201
+ <span>Credit me anonymously (we will publish "Anonymous" only)</span>
202
+ </label>
203
+ </div>
204
+ <div>
205
+ <button id="hofSubmit" type="submit" class="submit-btn">Submit for review</button>
206
+ <span style="color:#64748b;font-size:0.85rem;margin-left:12px;">No reward is paid via this form. Email <code>security@…</code> for the actual report.</span>
207
+ </div>
208
+ <div id="hofStatus" class="status-msg" style="display:none;"></div>
209
+ </form>
210
+
211
+ <h2 id="changelog">7. Document history</h2>
212
+ <ul>
213
+ <li><strong>2026-06-04</strong> — Reworded rewards section to "discretionary appreciation" (no formal bounty programme). Added hall-of-fame opt-in form. Added friendly GitHub-star ask.</li>
214
+ <li><strong>2026-05-25</strong> — Initial publication.</li>
215
+ </ul>
216
+
217
+ <p style="margin-top: 48px; color:#94a3b8;">
218
+ Related: <a href="/security">/security</a> · <a href="/threat-model">/threat-model</a> · <a href="/key-rotation">/key-rotation</a> · <a href="/researchers">/researchers</a>
219
+ </p>
220
+
221
+ </main>
222
+
223
+ <footer class="footer" style="margin-top:32px;">
224
+ <div class="container">
225
+ <div class="footer-bottom">
226
+ <span>© 2026 Web Agent Bridge. Open Core.</span>
227
+ <a href="/" class="btn btn-ghost btn-sm">Back to Home</a>
228
+ </div>
229
+ </div>
230
+ </footer>
231
+
232
+ <script>
233
+ (function () {
234
+ const form = document.getElementById('hofForm');
235
+ const btn = document.getElementById('hofSubmit');
236
+ const status = document.getElementById('hofStatus');
237
+ const anon = document.getElementById('hofAnon');
238
+ const name = document.getElementById('hofName');
239
+
240
+ function setStatus(kind, msg) {
241
+ status.className = 'status-msg ' + kind;
242
+ status.textContent = msg;
243
+ status.style.display = 'block';
244
+ }
245
+
246
+ anon.addEventListener('change', () => {
247
+ name.disabled = anon.checked;
248
+ if (anon.checked) name.value = '';
249
+ });
250
+
251
+ form.addEventListener('submit', async (ev) => {
252
+ ev.preventDefault();
253
+ status.style.display = 'none';
254
+ const payload = {
255
+ name: name.value.trim(),
256
+ githubHandle: document.getElementById('hofHandle').value.trim(),
257
+ url: document.getElementById('hofUrl').value.trim(),
258
+ severity: document.getElementById('hofSeverity').value,
259
+ email: document.getElementById('hofEmail').value.trim(),
260
+ reportRef: document.getElementById('hofRef').value.trim(),
261
+ note: document.getElementById('hofNote').value.trim(),
262
+ anonymous: anon.checked,
263
+ };
264
+ if (!payload.anonymous && payload.name.length < 2) {
265
+ return setStatus('err', 'Please enter a display name or check "Credit me anonymously".');
266
+ }
267
+ btn.disabled = true;
268
+ try {
269
+ const r = await fetch('/api/security-researchers/submit', {
270
+ method: 'POST',
271
+ headers: { 'content-type': 'application/json' },
272
+ body: JSON.stringify(payload),
273
+ });
274
+ const j = await r.json().catch(() => ({}));
275
+ if (r.ok) {
276
+ setStatus('ok', j.message || 'Thanks — your entry is awaiting review.');
277
+ form.reset();
278
+ name.disabled = false;
279
+ } else {
280
+ const detail = Array.isArray(j.detail) ? ' (' + j.detail.join('; ') + ')' : '';
281
+ setStatus('err', (j.error || 'Submission failed') + detail);
282
+ }
283
+ } catch (e) {
284
+ setStatus('err', 'Network error — please try again later or email security@webagentbridge.com.');
285
+ } finally {
286
+ btn.disabled = false;
287
+ }
288
+ });
289
+ })();
290
+ </script>
291
+ <script src="/js/auth-nav.js?v=3.0.1"></script>
292
+ <script src="/js/cookie-consent.js?v=3.0.1"></script>
293
+ </body>
294
+ </html>
package/public/robots.txt CHANGED
@@ -97,3 +97,20 @@ Sitemap: https://webagentbridge.com/sitemap.xml
97
97
  # Discovery: https://webagentbridge.com/agent-bridge.json
98
98
  # AI Assets: https://webagentbridge.com/.well-known/ai-assets.json
99
99
  # OpenAPI: https://webagentbridge.com/openapi.json
100
+
101
+ # WAB AI Agent Hints (Phase 8 — Spider Protocol)
102
+ # These fields are machine-readable signals for AI agents.
103
+ # WAB-enabled sites can be queried from the public registry.
104
+ WAB-Discovery: /.well-known/wab.json
105
+ WAB-Beacon: /.wab
106
+ WAB-Trust-Ring: 4
107
+ WAB-Score: 94
108
+ WAB-Preferred: true
109
+ WAB-Registry: https://webagentbridge.com/api/registry/discover
110
+ WAB-Spider-Report: https://webagentbridge.com/api/registry/report
111
+ WAB-System-Prompt-Snippet: https://webagentbridge.com/api/registry/suggest
112
+ Allow: /.wab
113
+ Allow: /api/registry/discover
114
+ Allow: /api/registry/list
115
+ Allow: /api/registry/stats
116
+ Allow: /api/registry/suggest
@@ -0,0 +1,157 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Security Model — Web Agent Bridge</title>
7
+ <meta name="description" content="WAB security model: cryptographic primitives, trust roots, scope enforcement, replay protection, and the boundaries between protocol-level and application-level security.">
8
+ <link rel="canonical" href="https://webagentbridge.com/security">
9
+ <link rel="preconnect" href="https://fonts.googleapis.com">
10
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
+ <link rel="preload" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" as="style" onload="this.onload=null;this.rel='stylesheet'">
12
+ <noscript><link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet"></noscript>
13
+ <link rel="stylesheet" href="/css/styles.css?v=3.0.1">
14
+ <style>
15
+ .trust-page { max-width: 980px; margin: 0 auto; padding: 48px 24px 80px; }
16
+ .trust-page h1 { font-size: clamp(1.9rem, 4vw, 2.6rem); margin: 0 0 10px; }
17
+ .trust-page .lead { color: var(--text-secondary, #94a3b8); font-size: 1.1rem; max-width: 760px; }
18
+ .trust-page h2 { margin-top: 48px; border-bottom: 1px solid #1f2937; padding-bottom: 8px; }
19
+ .trust-page h3 { margin-top: 28px; }
20
+ .trust-page table { width: 100%; border-collapse: collapse; margin: 16px 0; background: #10172a; border: 1px solid #1f2937; border-radius: 10px; overflow: hidden; }
21
+ .trust-page th, .trust-page td { padding: 12px 16px; text-align: left; border-bottom: 1px solid #1f2937; vertical-align: top; }
22
+ .trust-page th { background: #0d1322; color: #94a3b8; font-weight: 600; font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.05em; }
23
+ .trust-page tr:last-child td { border-bottom: none; }
24
+ .trust-page code { background: rgba(34,211,238,.08); padding: 2px 6px; border-radius: 4px; font-family: 'JetBrains Mono', monospace; font-size: 0.9em; }
25
+ .callout { background: rgba(34,211,238,.07); border: 1px solid rgba(34,211,238,.25); border-radius: 12px; padding: 14px 18px; margin: 18px 0; }
26
+ .callout.warn { background: rgba(245,158,11,.08); border-color: rgba(245,158,11,.35); }
27
+ .callout.danger { background: rgba(248,113,113,.08); border-color: rgba(248,113,113,.35); }
28
+ .meta-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 14px; margin: 20px 0; }
29
+ .meta-box { background: #10172a; border: 1px solid #1f2937; border-radius: 10px; padding: 16px; }
30
+ .meta-box .k { color: #94a3b8; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.08em; }
31
+ .meta-box .v { color: #e2e8f0; font-weight: 600; margin-top: 4px; }
32
+ </style>
33
+ </head>
34
+ <body>
35
+
36
+ <nav class="navbar">
37
+ <div class="container">
38
+ <a href="/" class="navbar-brand">
39
+ <div class="brand-icon">⚡</div>
40
+ <span>WAB</span>
41
+ </a>
42
+ <ul class="navbar-links">
43
+ <li><a href="/#features">Features</a></li>
44
+ <li><a href="/docs">Docs</a></li>
45
+ <li><a href="/security" style="color:var(--text-primary,#f0f4ff);">Security</a></li>
46
+ <li><a href="/whitepaper">Whitepaper</a></li>
47
+ </ul>
48
+ <div class="navbar-actions">
49
+ <a href="/login" class="btn btn-ghost">Sign In</a>
50
+ <a href="/register" class="btn btn-primary btn-sm">Get Started</a>
51
+ </div>
52
+ </div>
53
+ </nav>
54
+
55
+ <main class="trust-page">
56
+
57
+ <h1>WAB Security Model</h1>
58
+ <p class="lead">
59
+ This page defines the cryptographic primitives, trust roots, and verification boundaries
60
+ that the WAB protocol provides — and, just as importantly, what it does <em>not</em> guarantee.
61
+ For the explicit adversary model see <a href="/threat-model">/threat-model</a>.
62
+ </p>
63
+
64
+ <div class="meta-grid">
65
+ <div class="meta-box"><div class="k">Signature</div><div class="v">Ed25519 (RFC 8032)</div></div>
66
+ <div class="meta-box"><div class="k">Canonicalization</div><div class="v">JCS (RFC 8785)</div></div>
67
+ <div class="meta-box"><div class="k">Discovery</div><div class="v">DNS TXT + DNSSEC-aware</div></div>
68
+ <div class="meta-box"><div class="k">Replay window</div><div class="v">±300 s, nonce burn</div></div>
69
+ <div class="meta-box"><div class="k">Status</div><div class="v">Production v3.x</div></div>
70
+ </div>
71
+
72
+ <h2 id="goals">1. Security goals</h2>
73
+ <p>The WAB protocol is designed to provide, by construction, the following properties:</p>
74
+ <ul>
75
+ <li><strong>Origin authenticity</strong> — agents can prove that a <code>wab.json</code> manifest, capability response, or ATP receipt was produced by the legitimate site operator (or someone holding its private key).</li>
76
+ <li><strong>Scope enforcement</strong> — every signed intent declares an explicit, auditable scope (actions, spend cap, expiry, single-use nonce). The server refuses anything outside the declared scope.</li>
77
+ <li><strong>Idempotency</strong> — for any <code>(intent_id, idempotency_key)</code> pair, the system executes at most once, regardless of retries, network partitions, or duplicate client submissions.</li>
78
+ <li><strong>Verifiable receipts</strong> — every transaction terminates in an Ed25519-signed JSON receipt that any third party can verify with no shared secret, via the public endpoint <code>/api/atp/receipts/verify</code>.</li>
79
+ <li><strong>Auditability</strong> — every accepted intent, transition, receipt and compensation is logged with an append-only nonce; the audit trail is replay-resistant by design.</li>
80
+ </ul>
81
+
82
+ <h2 id="non-goals">2. Non-goals (what WAB does <em>not</em> claim)</h2>
83
+ <p>The protocol is honest about its boundaries. The following are deliberately <em>out of scope</em>:</p>
84
+ <ul>
85
+ <li><strong>Confidentiality of payloads at the application layer.</strong> WAB rides on TLS but does not add end-to-end encryption on top. If your intent body is sensitive, encrypt it at the application layer.</li>
86
+ <li><strong>Defense against a compromised site key.</strong> If the site's Ed25519 private key is stolen, the attacker can sign valid manifests and receipts until the key is rotated. See <a href="/key-rotation">/key-rotation</a>.</li>
87
+ <li><strong>Defense against a malicious site operator.</strong> WAB authenticates that an action came from the declared origin; it does not stop that origin from declaring malicious capabilities. Agents and users must still evaluate trust at the policy layer (Ring 4 trust graph helps).</li>
88
+ <li><strong>Network-layer DoS resistance.</strong> Rate limits and replay nonces protect against floods of <em>signed</em> requests; raw network DoS belongs to your edge (CDN/WAF).</li>
89
+ <li><strong>Cross-chain or on-chain finality.</strong> ATP provides cryptographic receipts, not consensus. Settlement on top of payment rails (Stripe, ACH, etc.) is handled by those systems and reflected in the receipt body.</li>
90
+ </ul>
91
+
92
+ <h2 id="primitives">3. Cryptographic primitives</h2>
93
+ <table>
94
+ <thead><tr><th>Use</th><th>Primitive</th><th>Notes</th></tr></thead>
95
+ <tbody>
96
+ <tr><td>Manifest signature</td><td>Ed25519</td><td>Over JCS-canonicalized JSON of <code>wab.json</code> with <code>signature</code> removed.</td></tr>
97
+ <tr><td>Receipt signature</td><td>Ed25519</td><td>Over JCS-canonicalized JSON of the receipt body. Verified at <code>/api/atp/receipts/verify</code>.</td></tr>
98
+ <tr><td>Intent authorization</td><td>HMAC-SHA256 + Ed25519</td><td>HMAC for per-session integrity, Ed25519 for cross-party verifiability.</td></tr>
99
+ <tr><td>Nonce / replay</td><td>UUIDv4 + 300 s window</td><td>Server burns nonce on first accept; reuse rejected with <code>409 nonce_consumed</code>.</td></tr>
100
+ <tr><td>Webhook delivery</td><td>Stripe-style <code>t=&lt;ts&gt;,v1=&lt;hmac&gt;</code></td><td>5-minute timestamp tolerance, constant-time compare.</td></tr>
101
+ <tr><td>Discovery</td><td>DNS TXT</td><td>DNSSEC validation strongly recommended at the resolver.</td></tr>
102
+ </tbody>
103
+ </table>
104
+
105
+ <h2 id="trust-roots">4. Trust roots</h2>
106
+ <p>The protocol intentionally has <strong>two distinct trust roots</strong>:</p>
107
+ <ul>
108
+ <li><strong>Per-site root</strong> — the site's own Ed25519 key, published via its DNS zone and <code>/.well-known/wab.json</code>. Authority over the site is bounded by control of its DNS zone (same trust boundary as TLS).</li>
109
+ <li><strong>Ring 4 trust graph</strong> — an optional reputation overlay (<code>webagentbridge.com</code>-anchored today, federated over time) that lets agents reason about <em>which</em> sites to honor without taking on individual trust decisions per request. Trust signals are softening: they bias scoring, they never override a hard refusal.</li>
110
+ </ul>
111
+ <div class="callout warn">
112
+ <strong>Trust anchor disclosure.</strong> Today the Ring 4 root key is published by webagentbridge.com.
113
+ This is comparable to early Let's Encrypt, Cloudflare, or Apple notarization — a single anchor is the
114
+ pragmatic bootstrap. Federation, weighted quorum and emergency rotation are documented at
115
+ <a href="/key-rotation">/key-rotation</a>. We will publish governance changes before activating them.
116
+ </div>
117
+
118
+ <h2 id="boundaries">5. Boundaries we enforce by construction</h2>
119
+ <ul>
120
+ <li><strong>Scope</strong> — intents cannot exceed the declared <code>actions</code>, <code>max_spend_cents</code>, and <code>expires_at</code>. The server rejects, never silently truncates.</li>
121
+ <li><strong>Single-use</strong> — every intent contract burns its nonce on the first <code>authorize</code>. Re-authorize fails closed.</li>
122
+ <li><strong>Idempotent execution</strong> — <code>UNIQUE (intent_id, idempotency_key)</code> in the transactions table makes double-execution structurally impossible.</li>
123
+ <li><strong>Receipt immutability</strong> — receipts are append-only. Compensation is a separate signed event, never a mutation.</li>
124
+ <li><strong>Time-bounded sessions</strong> — JWT access tokens default to 15 min; refresh tokens are bound to the device fingerprint.</li>
125
+ </ul>
126
+
127
+ <h2 id="reporting">6. Reporting vulnerabilities</h2>
128
+ <p>See <a href="/responsible-disclosure">/responsible-disclosure</a>. In short: email <code>security@webagentbridge.com</code>, encrypt with our published PGP key, and expect an initial response within 72 hours.</p>
129
+
130
+ <h2 id="changelog">7. Document history</h2>
131
+ <ul>
132
+ <li><strong>2026-05-25</strong> — Initial publication. Reflects v3.17.x protocol.</li>
133
+ </ul>
134
+
135
+ <p style="margin-top: 48px; color:#94a3b8;">
136
+ Related: <a href="/threat-model">/threat-model</a> ·
137
+ <a href="/responsible-disclosure">/responsible-disclosure</a> ·
138
+ <a href="/key-rotation">/key-rotation</a> ·
139
+ <a href="/atp-semantics">/atp-semantics</a> ·
140
+ <a href="/spec">Full spec</a>
141
+ </p>
142
+
143
+ </main>
144
+
145
+ <footer class="footer" style="margin-top:32px;">
146
+ <div class="container">
147
+ <div class="footer-bottom">
148
+ <span>© 2026 Web Agent Bridge. Open Core.</span>
149
+ <a href="/" class="btn btn-ghost btn-sm">Back to Home</a>
150
+ </div>
151
+ </div>
152
+ </footer>
153
+
154
+ <script src="/js/auth-nav.js?v=3.0.1"></script>
155
+ <script src="/js/cookie-consent.js?v=3.0.1"></script>
156
+ </body>
157
+ </html>
@@ -0,0 +1,153 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Threat Model — Web Agent Bridge</title>
7
+ <meta name="description" content="Explicit adversary model for the WAB protocol: who we defend against, who we do not, and where Sybil, key-compromise, and replay risks live.">
8
+ <link rel="canonical" href="https://webagentbridge.com/threat-model">
9
+ <link rel="preload" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" as="style" onload="this.onload=null;this.rel='stylesheet'">
10
+ <link rel="stylesheet" href="/css/styles.css?v=3.0.1">
11
+ <style>
12
+ .trust-page { max-width: 980px; margin: 0 auto; padding: 48px 24px 80px; }
13
+ .trust-page h1 { font-size: clamp(1.9rem, 4vw, 2.6rem); margin: 0 0 10px; }
14
+ .trust-page .lead { color: #94a3b8; font-size: 1.1rem; max-width: 760px; }
15
+ .trust-page h2 { margin-top: 48px; border-bottom: 1px solid #1f2937; padding-bottom: 8px; }
16
+ .trust-page h3 { margin-top: 28px; }
17
+ .trust-page table { width: 100%; border-collapse: collapse; margin: 16px 0; background: #10172a; border: 1px solid #1f2937; border-radius: 10px; overflow: hidden; }
18
+ .trust-page th, .trust-page td { padding: 12px 16px; text-align: left; border-bottom: 1px solid #1f2937; vertical-align: top; }
19
+ .trust-page th { background: #0d1322; color: #94a3b8; font-weight: 600; font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.05em; }
20
+ .trust-page tr:last-child td { border-bottom: none; }
21
+ .trust-page code { background: rgba(34,211,238,.08); padding: 2px 6px; border-radius: 4px; font-family: 'JetBrains Mono', monospace; font-size: 0.9em; }
22
+ .callout { background: rgba(34,211,238,.07); border: 1px solid rgba(34,211,238,.25); border-radius: 12px; padding: 14px 18px; margin: 18px 0; }
23
+ .callout.warn { background: rgba(245,158,11,.08); border-color: rgba(245,158,11,.35); }
24
+ .callout.danger { background: rgba(248,113,113,.08); border-color: rgba(248,113,113,.35); }
25
+ .pill { display: inline-block; padding: 2px 10px; border-radius: 999px; font-size: 0.78rem; font-weight: 600; }
26
+ .pill.def { background: rgba(52,211,153,.15); color:#34d399; }
27
+ .pill.par { background: rgba(245,158,11,.15); color:#fbbf24; }
28
+ .pill.no { background: rgba(248,113,113,.15); color:#f87171; }
29
+ </style>
30
+ </head>
31
+ <body>
32
+
33
+ <nav class="navbar">
34
+ <div class="container">
35
+ <a href="/" class="navbar-brand"><div class="brand-icon">⚡</div><span>WAB</span></a>
36
+ <ul class="navbar-links">
37
+ <li><a href="/docs">Docs</a></li>
38
+ <li><a href="/security">Security</a></li>
39
+ <li><a href="/threat-model" style="color:#f0f4ff;">Threat Model</a></li>
40
+ <li><a href="/whitepaper">Whitepaper</a></li>
41
+ </ul>
42
+ <div class="navbar-actions">
43
+ <a href="/login" class="btn btn-ghost">Sign In</a>
44
+ <a href="/register" class="btn btn-primary btn-sm">Get Started</a>
45
+ </div>
46
+ </div>
47
+ </nav>
48
+
49
+ <main class="trust-page">
50
+
51
+ <h1>WAB Threat Model</h1>
52
+ <p class="lead">
53
+ An explicit, falsifiable description of the adversaries WAB defends against, the ones it
54
+ only partially mitigates, and the ones it does not address at all. Companion to
55
+ <a href="/security">/security</a>.
56
+ </p>
57
+
58
+ <h2 id="assumptions">1. Trust assumptions</h2>
59
+ <ul>
60
+ <li><strong>TLS works.</strong> We assume the TLS PKI is sound enough for HTTPS to bind the site identity, just as the rest of the web does.</li>
61
+ <li><strong>DNS resolution is observable.</strong> An attacker on-path may see DNS queries; with DNSSEC (recommended) they cannot forge responses.</li>
62
+ <li><strong>The site's private key is held by the site operator.</strong> Key compromise is treated as an incident, not a normal state.</li>
63
+ <li><strong>Clocks are loosely synchronized.</strong> ±300 s tolerance on signature timestamps.</li>
64
+ <li><strong>Storage is honest.</strong> The site's database honors the <code>UNIQUE</code> constraints that anchor idempotency. (Server-side DBs do; eventual-consistency stores do not — see <a href="/atp-semantics">/atp-semantics</a>.)</li>
65
+ </ul>
66
+
67
+ <h2 id="adversaries">2. Adversary model</h2>
68
+ <table>
69
+ <thead><tr><th>Adversary</th><th>Defense</th><th>Notes</th></tr></thead>
70
+ <tbody>
71
+ <tr><td>Passive network observer</td><td><span class="pill def">DEFENDED</span></td><td>TLS confidentiality; signatures don't leak secrets.</td></tr>
72
+ <tr><td>Active MITM on HTTPS</td><td><span class="pill def">DEFENDED</span></td><td>Inherits TLS PKI protection.</td></tr>
73
+ <tr><td>Off-path forger (no key, no zone control)</td><td><span class="pill def">DEFENDED</span></td><td>Ed25519 forgery is infeasible.</td></tr>
74
+ <tr><td>Replay of captured signed request</td><td><span class="pill def">DEFENDED</span></td><td>±300 s window + single-use nonce burn.</td></tr>
75
+ <tr><td>Duplicate / out-of-order client retries</td><td><span class="pill def">DEFENDED</span></td><td>Idempotency key + DB <code>UNIQUE</code>.</td></tr>
76
+ <tr><td>Cross-origin agent confusion</td><td><span class="pill def">DEFENDED</span></td><td>Receipts and intents bind <code>site</code>; agents reject mismatches.</td></tr>
77
+ <tr><td>DNS spoofing without DNSSEC</td><td><span class="pill par">PARTIAL</span></td><td>Fallback verification via <code>/.well-known/wab.json</code> over HTTPS; DNSSEC strongly recommended.</td></tr>
78
+ <tr><td>Compromised site private key</td><td><span class="pill par">PARTIAL</span></td><td>Detected via key-rotation log + receipt audit. Mitigated by rotation. See <a href="/key-rotation">/key-rotation</a>.</td></tr>
79
+ <tr><td>Sybil at the Reality Anchor / trust-graph layer</td><td><span class="pill par">PARTIAL</span></td><td>Weighted quorum and admission cost discussed in §4. Current production weighting favors long-lived, DNSSEC-validated origins.</td></tr>
80
+ <tr><td>Malicious site operator (declares lies)</td><td><span class="pill no">OUT OF SCOPE</span></td><td>WAB authenticates the origin; the policy layer (Ring 4, user consent, agent rules) must judge intent.</td></tr>
81
+ <tr><td>Compromised user device</td><td><span class="pill no">OUT OF SCOPE</span></td><td>Standard endpoint security applies; we limit blast radius via short-lived tokens.</td></tr>
82
+ <tr><td>Quantum adversary against Ed25519</td><td><span class="pill no">OUT OF SCOPE</span></td><td>Post-quantum migration tracked at <code>schema_version</code>; not a 2026 threat.</td></tr>
83
+ <tr><td>Network-layer DoS</td><td><span class="pill no">OUT OF SCOPE</span></td><td>Belongs to your edge (CDN/WAF).</td></tr>
84
+ </tbody>
85
+ </table>
86
+
87
+ <h2 id="sybil">3. Sybil &amp; reputation considerations</h2>
88
+ <p>
89
+ The Ring 4 trust graph is a <em>signal</em>, not a vote. To resist Sybil inflation we currently weight
90
+ contributions by:
91
+ </p>
92
+ <ul>
93
+ <li><strong>Origin age</strong> — first-seen timestamp of the DNS TXT record, validated by an independent passive observer.</li>
94
+ <li><strong>DNSSEC-validated chain</strong> — origins with a validated chain receive higher weight.</li>
95
+ <li><strong>Receipt history</strong> — origins with a non-trivial history of verifiable ATP receipts (Ed25519, no compensations beyond the ambient rate) accumulate weight.</li>
96
+ <li><strong>Independent attestors</strong> — when more than one attestor is online, no single attestor's vote can exceed 1/3 of the weight (BFT-style cap).</li>
97
+ </ul>
98
+ <p>
99
+ Admission has a real, non-zero cost: a registered domain, a functioning DNS zone, and a published key.
100
+ This makes farm-scale Sybils economically unattractive, but it is not free — high-value scenarios should
101
+ layer additional policy at the agent.
102
+ </p>
103
+ <div class="callout warn">
104
+ <strong>Honest status:</strong> the Reality Anchor weighting algorithm is implemented and live, but the
105
+ formal quorum proof and a public dashboard of attestor diversity are still in progress. We will publish
106
+ the algorithm before promoting it from <em>signal</em> to <em>gate</em>.
107
+ </div>
108
+
109
+ <h2 id="key-compromise">4. Site-key compromise scenarios</h2>
110
+ <p>If a site's Ed25519 private key leaks, an attacker can issue valid-looking manifests and receipts. WAB responds in four layers:</p>
111
+ <ol>
112
+ <li><strong>Detect</strong> — the site operator publishes a signed <code>revoked_keys</code> list in their next manifest version. Agents that already cached the old key learn of the revocation on next discovery refresh (TTL ≤ 1 h recommended).</li>
113
+ <li><strong>Rotate</strong> — a new keypair is generated; the new public key replaces <code>public_key</code> and is co-signed by the old key during a grace window.</li>
114
+ <li><strong>Revoke</strong> — old key is added to a published revocation list at <code>/.well-known/wab-revocations.json</code> and to the Ring 4 trust graph.</li>
115
+ <li><strong>Reconcile</strong> — receipts signed by the revoked key remain mathematically valid but are marked <em>distrusted</em> in the trust graph from the revocation timestamp forward. Downstream parties decide whether to accept them.</li>
116
+ </ol>
117
+ <p>Full procedure: <a href="/key-rotation">/key-rotation</a>.</p>
118
+
119
+ <h2 id="abuse">5. Abuse scenarios at the application layer</h2>
120
+ <ul>
121
+ <li><strong>Spam intents</strong> — bounded by per-user rate limit (default 60/min) and per-IP request budget at the edge.</li>
122
+ <li><strong>Pre-emptive nonce burns</strong> — an attacker submits a malformed intent to burn the nonce. The intent table records the burn but does not advance state; the legitimate retry simply uses a fresh nonce.</li>
123
+ <li><strong>Receipt griefing</strong> — an attacker calls the public <code>verify</code> endpoint with garbage. The endpoint is constant-time and rate-limited; verification is stateless and cheap.</li>
124
+ <li><strong>Compensation race</strong> — two parties try to compensate the same transaction. The first wins; the second receives <code>409 already_compensated</code>. The audit log records both attempts.</li>
125
+ </ul>
126
+
127
+ <h2 id="changelog">6. Document history</h2>
128
+ <ul>
129
+ <li><strong>2026-05-25</strong> — Initial publication. Reflects v3.17.x protocol.</li>
130
+ </ul>
131
+
132
+ <p style="margin-top: 48px; color:#94a3b8;">
133
+ Related: <a href="/security">/security</a> ·
134
+ <a href="/responsible-disclosure">/responsible-disclosure</a> ·
135
+ <a href="/key-rotation">/key-rotation</a> ·
136
+ <a href="/atp-semantics">/atp-semantics</a>
137
+ </p>
138
+
139
+ </main>
140
+
141
+ <footer class="footer" style="margin-top:32px;">
142
+ <div class="container">
143
+ <div class="footer-bottom">
144
+ <span>© 2026 Web Agent Bridge. Open Core.</span>
145
+ <a href="/" class="btn btn-ghost btn-sm">Back to Home</a>
146
+ </div>
147
+ </div>
148
+ </footer>
149
+
150
+ <script src="/js/auth-nav.js?v=3.0.1"></script>
151
+ <script src="/js/cookie-consent.js?v=3.0.1"></script>
152
+ </body>
153
+ </html>