@agent-custody/receipts 0.6.9 → 0.6.10

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.
package/dist/log-admin.js CHANGED
@@ -104,7 +104,7 @@ export function adminRoutes(opts) {
104
104
  return json(401, { error: "admin token required" }, { "www-authenticate": 'Basic realm="agent-custody log admin", charset="UTF-8"' }), true;
105
105
  }
106
106
  if (req.method === "GET" && url.pathname === "/admin") {
107
- res.writeHead(200, { "content-type": "text/html; charset=utf-8", "cache-control": "no-store", "x-frame-options": "DENY", "content-security-policy": "default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; connect-src 'self'" });
107
+ res.writeHead(200, { "content-type": "text/html; charset=utf-8", "cache-control": "no-store", "x-frame-options": "DENY", "content-security-policy": "default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; img-src 'self'; connect-src 'self'" });
108
108
  res.end(ADMIN_PAGE);
109
109
  return true;
110
110
  }
@@ -337,7 +337,7 @@ const ADMIN_PAGE = `<!doctype html>
337
337
  $("rcsv").href = "/admin/registrations.csv?month=" + encodeURIComponent(month);
338
338
  $("sTenants").textContent = r.totals.tenants; $("sRegistered").textContent = r.totals.registered; $("sAppends").textContent = r.totals.appends; $("sLeaves").textContent = r.totals.totalLeaves;
339
339
  const who = (x) => x.email ? esc(x.name || "") + (x.company ? " <span class=muted>· " + esc(x.company) + (x.role ? ", " + esc(x.role) : "") + "</span>" : "") : "<span class=muted>onboarded by script</span>";
340
- const reach = (x) => [x.email ? "<a href=\"mailto:" + esc(x.email) + "\">" + esc(x.email) + "</a>" : "", x.phone ? esc(x.phone) : "", x.telegram ? "telegram @" + esc(x.telegram) : ""].filter(Boolean).join("<br>");
340
+ const reach = (x) => [x.email ? "<a href=\\"mailto:" + esc(x.email) + "\\">" + esc(x.email) + "</a>" : "", x.phone ? esc(x.phone) : "", x.telegram ? "telegram @" + esc(x.telegram) : ""].filter(Boolean).join("<br>");
341
341
  $("regs").innerHTML = r.rows.map((x) => "<tr><td>" + who(x) + "</td><td>" + reach(x) + "</td><td><code>" + esc(x.tenant) + "</code>" + (x.disabled ? " <span class=muted>disabled</span>" : "") + "</td><td>" + esc(x.plan) + "</td><td>" + (x.registeredAt ? esc(x.registeredAt.slice(0, 10)) : "") + "</td><td>" + (x.billing ? esc(x.billing) : "<span class=muted>none</span>") + "</td><td>" + x.appends + (x.quota === null ? "" : " <span class=muted>/ " + x.quota + "</span>") + "</td><td>" + x.totalLeaves + "</td><td>" + x.liveTokens + "</td></tr>").join("") || "<tr><td colspan=9 class=muted>no tenants</td></tr>";
342
342
  };
343
343
  const loadAudit = async () => {
package/dist/portal.js CHANGED
@@ -246,7 +246,7 @@ export function portalHandler(o) {
246
246
  return void res.end(FAVICON);
247
247
  }
248
248
  if (req.method === "GET" && url.pathname === "/") {
249
- res.writeHead(200, { "content-type": "text/html; charset=utf-8", "cache-control": "no-store", "x-frame-options": "DENY", "content-security-policy": "default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; connect-src 'self'; form-action 'self'; base-uri 'none'" });
249
+ res.writeHead(200, { "content-type": "text/html; charset=utf-8", "cache-control": "no-store", "x-frame-options": "DENY", "content-security-policy": "default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; img-src 'self'; connect-src 'self'; form-action 'self'; base-uri 'none'" });
250
250
  return void res.end(PORTAL_PAGE.replace("__LOG_BASE__", base.replace(/[&<>"]/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" })[c])));
251
251
  }
252
252
  // ---- Stripe's webhook: the only caller that is not a browser with a session ----
@@ -616,13 +616,13 @@ const PORTAL_PAGE = `<!doctype html>
616
616
  const step = (n, title, body) => "<div class=step><span class=n>" + n + "</span><div><h3>" + title + "</h3>" + body + "</div></div>";
617
617
  const renderSetup = (el, s, atRegistration) => {
618
618
  el.innerHTML =
619
- step(1, "Keep the key where your gateway runs", (atRegistration ? "<p>The key above is shown once; we keep only its hash. Put it in the environment of the machine that runs your gateway or SDK:</p>" : "<p>Your key was shown once at registration. If it is gone, mint another under <a href=\"#keys\" data-view=\"keys\">API keys</a>. It lives in the environment of the machine that runs your gateway or SDK:</p>") + snip(s.env)) +
619
+ step(1, "Keep the key where your gateway runs", (atRegistration ? "<p>The key above is shown once; we keep only its hash. Put it in the environment of the machine that runs your gateway or SDK:</p>" : "<p>Your key was shown once at registration. If it is gone, mint another under <a href=\\"#keys\\" data-view=\\"keys\\">API keys</a>. It lives in the environment of the machine that runs your gateway or SDK:</p>") + snip(s.env)) +
620
620
  step(2, "Point your gateway or SDK at your log", "<p>Add this to <code>gateway.json</code> or <code>sdk.json</code>. <code>hashOnly</code> means this log receives the hash of each receipt and never the receipt.</p>" + snip(s.config)) +
621
- step(3, "Send the first receipt", "<p>Run your agent through the gateway once. The <a href=\"#overview\" data-view=\"overview\">Overview</a> shows the append within seconds, and the first signed checkpoint follows within minutes. New to the gateway? <a href=\"https://agent-custody.dev/guide/getting-started\">Getting started</a> takes ten minutes.</p>") +
621
+ step(3, "Send the first receipt", "<p>Run your agent through the gateway once. The <a href=\\"#overview\\" data-view=\\"overview\\">Overview</a> shows the append within seconds, and the first signed checkpoint follows within minutes. New to the gateway? <a href=\\"https://agent-custody.dev/guide/getting-started\\">Getting started</a> takes ten minutes.</p>") +
622
622
  step(4, "Hand this to whoever verifies your receipts", "<p>Both commands fetch this log's published keys and pin them; <code>--log-id</code> makes sure the tree heads are this log's.</p>" + snip(s.verify) + snip(s.audit)) +
623
623
  step(5, "Take your data, any time", "<p>Every leaf hash, the signed head, the keys, the checkpoints, your usage, and the actions taken on your tenant, checked against each other and written as a log copy the verifier reads offline.</p>" + snip(s.export)) +
624
624
  "<h2>Your log's addresses</h2><div class=panel><table class=addr><tbody>" + [["Your log", s.log], ["Log id on tree heads", s.logId], ["Your checkpoints", s.checkpoints || "published after your first append"], ["The log's keys", s.keys + (s.keyid ? " (current keyid " + s.keyid.slice(0, 12) + "…)" : "")]].map(([k, v]) => "<tr><th>" + esc(k) + "</th><td class=mono>" + esc(v) + "</td></tr>").join("") + "</tbody></table></div>" +
625
- "<h2>What this log does not do</h2><p class=muted>Hold receipt contents; forge a receipt, since your gateway key signs those; or, today, countersign with a second independent witness. <a href=\"https://agent-custody.dev/receipts/#what-a-receipt-proves-and-what-it-does-not\">What a receipt proves and what it does not.</a></p>";
625
+ "<h2>What this log does not do</h2><p class=muted>Hold receipt contents; forge a receipt, since your gateway key signs those; or, today, countersign with a second independent witness. <a href=\\"https://agent-custody.dev/receipts/#what-a-receipt-proves-and-what-it-does-not\\">What a receipt proves and what it does not.</a></p>";
626
626
  };
627
627
  document.addEventListener("click", (e) => {
628
628
  const b = e.target.closest("button[data-copy]"); if (b) { navigator.clipboard.writeText(b.previousElementSibling.textContent).then(() => { b.textContent = "Copied"; setTimeout(() => { b.textContent = "Copy"; }, 1500); }); return; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-custody/receipts",
3
- "version": "0.6.9",
3
+ "version": "0.6.10",
4
4
  "description": "Chain of custody for AI agents: signed, independently verifiable receipts for tool calls. MCP gateway + Cedar policy + Merkle transparency log",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {