@atbash/sdk 0.10.0-dev.0 → 0.10.4-dev.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.
@@ -11,6 +11,23 @@ interface ValidatedEndpoint {
11
11
  policy: "default" | "self-hosted";
12
12
  verifyPubKey: string | null;
13
13
  }
14
+ /**
15
+ * Builds the trusted judge host set.
16
+ *
17
+ * The compiled-in default is always trusted: a `prod` build resolves it to
18
+ * atbash.ai, a dev build to whatever DEV_ENDPOINT was set at build time. No
19
+ * dev host is spelled out in source, and dev builds still validate their own
20
+ * default.
21
+ *
22
+ * Exported for tests only. The set is a build-time value and is deliberately
23
+ * never read from the process environment — an env var would let anyone widen
24
+ * the allowlist of an already-shipped artifact, which is the silent-redirection
25
+ * attack the allowlist exists to prevent (F-003). Asserting that requires
26
+ * calling this with the environment set, so it cannot stay module-private.
27
+ *
28
+ * @internal
29
+ */
30
+ declare function buildAllowedJudgeHosts(): ReadonlySet<string>;
14
31
  declare function validateJudgeEndpoint(judge?: JudgeEndpointConfig): ValidatedEndpoint;
15
32
 
16
33
  /**
@@ -395,6 +412,8 @@ declare class Atbash {
395
412
  readonly orgEncryptionPubKey?: string;
396
413
  /** When true (default), `auditToolCall` denies on any error. */
397
414
  readonly failClosed: boolean;
415
+ /** Org key learned from the last agent-exists check, for this agent only. */
416
+ private _orgKeyFromChain;
398
417
  private readonly logger;
399
418
  private readonly http;
400
419
  /**
@@ -1049,35 +1068,16 @@ declare function flushTelemetry(): Promise<void>;
1049
1068
  declare function shutdownTelemetry(): Promise<void>;
1050
1069
 
1051
1070
  /**
1052
- * Signs `log_encrypted_tool_call` the ciphertext-only counterpart of
1053
- * `log_tool_call`. Rust core owns the encrypt + hash + GTX sign flow;
1054
- * this module is a thin wrapper. Browser callers get the pure-TS shim
1055
- * at `src-ts/browser/encrypted-toolcall.ts` (NAPI can't run in-browser).
1056
- */
1057
- /** Plaintext fields of a tool call, sealed into a single ECIES payload. */
1058
- interface ToolCallPlaintext {
1059
- tool_name: string;
1060
- action: string;
1061
- context: string;
1062
- tool_args_json: string;
1063
- }
1064
- /**
1065
- * Canonical form of an action for the retry-cache hash. Byte-identical to
1066
- * the dashboard's `normalizeActionForHash` — diverging silently breaks
1067
- * YELLOW-hold retry resolution.
1071
+ * Rust core does the work; `browser/encrypted-toolcall.ts` mirrors it for the
1072
+ * browser and must produce the same columns.
1068
1073
  */
1074
+ /** Must match `column_aad` in the core — the label binds a ciphertext to its column. */
1075
+ declare function columnAad(toolCallId: string, column: string): string;
1076
+ /** Byte-identical to the dashboard's copy — diverging breaks hold-retry resolution. */
1069
1077
  declare function normalizeActionForHash(action: string): string;
1070
- /**
1071
- * Signed commitment to the plaintext claims the caller sends alongside the
1072
- * ciphertext. The judge reads plaintext from the request body but holds no
1073
- * org key; this hash lets it verify body-vs-ciphertext without decrypting.
1074
- * Byte-identical to the dashboard's `claimHashHex`.
1075
- */
1078
+ /** Lets the judge check the request body against the ciphertext without an org key. */
1076
1079
  declare function claimHashHex(toolName: string, action: string, context: string, toolArgsJson: string): string;
1077
- /**
1078
- * Build + sign a `log_encrypted_tool_call` transaction. Returns hex-encoded
1079
- * signed tx, ready to POST as `signed_log_tool_call`.
1080
- */
1080
+ /** @returns hex-encoded signed tx, ready to POST as `signed_log_tool_call`. */
1081
1081
  declare function signEncryptedToolCall(toolCallId: string, action: string, context: string, toolName: string, toolArgsJson: string, orgEncryptionPubKey: string, privkeyHex: string, blockchainRidHex: string): string;
1082
1082
 
1083
1083
  /**
@@ -1126,6 +1126,29 @@ declare function decryptForOrg(payload: Uint8Array, orgPrivKeyHex: string, aad:
1126
1126
  */
1127
1127
  declare function encryptedLength(plaintextByteLength: number): number;
1128
1128
 
1129
+ /**
1130
+ * atb1.<key-fingerprint>.<claim-hash>.<base64 ciphertext>
1131
+ *
1132
+ * Normative spec: `core/src/crypto_envelope.rs`. This mirrors it for the browser.
1133
+ */
1134
+ interface Envelope {
1135
+ /** First 8 bytes of the recipient public key, hex. May be empty. */
1136
+ keyFingerprint: string;
1137
+ /** Commitment to the accompanying plaintext claims. May be empty. */
1138
+ claimHash: string;
1139
+ /** Raw ECIES payload. */
1140
+ payload: Uint8Array;
1141
+ }
1142
+ declare function packEnvelope(payload: Uint8Array, keyFingerprint?: string, claimHash?: string): string;
1143
+ /**
1144
+ * Stays true for a truncated envelope that `parseEnvelope` rejects — a severed
1145
+ * ciphertext is not plaintext, so callers must show a placeholder.
1146
+ */
1147
+ declare function isEnvelope(value: string): boolean;
1148
+ /** Null, not a throw — pre-encryption records are plaintext. */
1149
+ declare function parseEnvelope(value: string): Envelope | null;
1150
+ declare function keyFingerprintOf(pubKeyHex: string): string;
1151
+
1129
1152
  declare function isValidPrivateKey(hex: string): boolean;
1130
1153
  declare function derivePublicKey(privkey: string): string;
1131
1154
  declare function generateKeypair(): KeyPair;
@@ -1141,4 +1164,4 @@ declare function containsSecret(text: string): boolean;
1141
1164
  declare function createMemorySnapshot(entries: MemoryEntry[], takenAt: number): MemorySnapshot;
1142
1165
  declare function diffMemorySnapshots(before: MemorySnapshot, after: MemorySnapshot): MemoryDiffResult;
1143
1166
 
1144
- export { type ActionType, type AgentAuth, type AgentMemoryEntry, type AgentPolicy, type AnomalySeverity, type AnomalyType, Atbash, AtbashAPIError, type AtbashLogger, type AtbashOptions, type AtbashUserConfig, type ChainOpts, type ClassifierToolContext, type ClassifierToolEvent, type ClassifyMemoryReadOptions, type ClassifyMemoryWriteOptions, type ClientSource, type CommitMemoryOptions, DEFAULT_BLOCKCHAIN_RID, DEFAULT_CHROMIA_NODE_URLS, DEFAULT_ENDPOINT, DEFAULT_MEMORY_PATH_PATTERNS, DEFAULT_MEMORY_READ_TOOL_NAMES, DEFAULT_MEMORY_WRITE_TOOL_NAMES, type Decision, type DecisionVerdict, EciesDomain, type EncryptedMemory, type FromConfigOptions, type GuardLogger, type GuardMemoryDecision, type GuardMemoryWriteInput, type GuardMemoryWriteResult, type HeldAction, type HeldActionReview, type HookDecision, type JudgeEndpointConfig, type JudgeOptions, type JudgeResult, type JudgmentState, type JudgmentStatus, type KeyPair, type LogToolCallOptions, type LogToolCallResult, type MemoryAnomaly, type MemoryDiffResult, type MemoryEntry, MemoryGuardManager, type MemoryGuardManagerOptions, MemoryIntegrityError, type MemoryPointer, type MemoryRollbackEvent, type MemoryScanOptions, type MemoryScanResult, type MemoryScanVerdict, type MemorySnapshot, type ModifiedEntry, type Network, type OrgSubscription, PointerStore, type Provider, type PubkeyValue, type RedactResult, type RollbackMemoryOptions, type SecretKind, type SecretMatch, SignatureVerificationError, type Subscription, type SyncMemoryOptions, type SyncMemoryResult, type TelemetryConfig, type TierInfo, type ToolCallFull, type ToolCallInput, type ToolCallPlaintext, type ToolCallRecord, type ValidatedEndpoint, type Verdict, type WrappedLogger, claimHashHex, classifyMemoryRead, classifyMemoryWrite, commitMemoryVersion, containsEvasionCharacters, containsSecret, createFileLogger, createMemoryGuardManager, createMemorySnapshot, decryptForOrg, decryptMemoryContent, defaultPluginLogPath, defaultPointerPath, deriveMemoryKey, derivePublicKey, diffMemorySnapshots, encryptForOrg, encryptMemoryContent, encryptedLength, flushTelemetry, generateKeypair, getActiveMemory, getActiveMemoryId, getAllAgentMemory, getConfigDir, getConfigPath, getMemoryById, getMemoryHistory, getRollbackHistory, guardMemoryWrite, isValidPrivateKey, loadAgent, loadAgentFromFile, loadUserConfig, normalizeActionForHash, normalizeForMatching, normalizeStatus, normalizeVerdict, pubkeyToHex, recordCall, recordDuration, redactJsonStrings, redactSecrets, resolve, resolveKeyPath, rollbackMemory, saveUserConfig, scanMemory, scanMemoryBatch, setupTelemetry, shutdownTelemetry, signEncryptedToolCall, signJudgeAction, signLogToolCall, syncLocalMemory, validateJudgeEndpoint, verifyJudgeResponseSignature, verifySignature };
1167
+ export { type ActionType, type AgentAuth, type AgentMemoryEntry, type AgentPolicy, type AnomalySeverity, type AnomalyType, Atbash, AtbashAPIError, type AtbashLogger, type AtbashOptions, type AtbashUserConfig, type ChainOpts, type ClassifierToolContext, type ClassifierToolEvent, type ClassifyMemoryReadOptions, type ClassifyMemoryWriteOptions, type ClientSource, type CommitMemoryOptions, DEFAULT_BLOCKCHAIN_RID, DEFAULT_CHROMIA_NODE_URLS, DEFAULT_ENDPOINT, DEFAULT_MEMORY_PATH_PATTERNS, DEFAULT_MEMORY_READ_TOOL_NAMES, DEFAULT_MEMORY_WRITE_TOOL_NAMES, type Decision, type DecisionVerdict, EciesDomain, type EncryptedMemory, type Envelope, type FromConfigOptions, type GuardLogger, type GuardMemoryDecision, type GuardMemoryWriteInput, type GuardMemoryWriteResult, type HeldAction, type HeldActionReview, type HookDecision, type JudgeEndpointConfig, type JudgeOptions, type JudgeResult, type JudgmentState, type JudgmentStatus, type KeyPair, type LogToolCallOptions, type LogToolCallResult, type MemoryAnomaly, type MemoryDiffResult, type MemoryEntry, MemoryGuardManager, type MemoryGuardManagerOptions, MemoryIntegrityError, type MemoryPointer, type MemoryRollbackEvent, type MemoryScanOptions, type MemoryScanResult, type MemoryScanVerdict, type MemorySnapshot, type ModifiedEntry, type Network, type OrgSubscription, PointerStore, type Provider, type PubkeyValue, type RedactResult, type RollbackMemoryOptions, type SecretKind, type SecretMatch, SignatureVerificationError, type Subscription, type SyncMemoryOptions, type SyncMemoryResult, type TelemetryConfig, type TierInfo, type ToolCallFull, type ToolCallInput, type ToolCallRecord, type ValidatedEndpoint, type Verdict, type WrappedLogger, buildAllowedJudgeHosts, claimHashHex, classifyMemoryRead, classifyMemoryWrite, columnAad, commitMemoryVersion, containsEvasionCharacters, containsSecret, createFileLogger, createMemoryGuardManager, createMemorySnapshot, decryptForOrg, decryptMemoryContent, defaultPluginLogPath, defaultPointerPath, deriveMemoryKey, derivePublicKey, diffMemorySnapshots, encryptForOrg, encryptMemoryContent, encryptedLength, flushTelemetry, generateKeypair, getActiveMemory, getActiveMemoryId, getAllAgentMemory, getConfigDir, getConfigPath, getMemoryById, getMemoryHistory, getRollbackHistory, guardMemoryWrite, isEnvelope, isValidPrivateKey, keyFingerprintOf, loadAgent, loadAgentFromFile, loadUserConfig, normalizeActionForHash, normalizeForMatching, normalizeStatus, normalizeVerdict, packEnvelope, parseEnvelope, pubkeyToHex, recordCall, recordDuration, redactJsonStrings, redactSecrets, resolve, resolveKeyPath, rollbackMemory, saveUserConfig, scanMemory, scanMemoryBatch, setupTelemetry, shutdownTelemetry, signEncryptedToolCall, signJudgeAction, signLogToolCall, syncLocalMemory, validateJudgeEndpoint, verifyJudgeResponseSignature, verifySignature };
package/dist/browser.mjs CHANGED
@@ -43233,9 +43233,9 @@ var index = /* @__PURE__ */ getDefaultExportFromCjs(builtExports);
43233
43233
 
43234
43234
  // src-ts/browser/native.ts
43235
43235
  var { Buffer: Buffer3, gtx: pcgtx } = index;
43236
- var DEV_ENDPOINT = "https://chromia-verified-ai-dev-two.vercel.app";
43237
- var DEV_BLOCKCHAIN_RID = "02668C5218871F69A93CC0F7032DCFFE06EF0D35EF2F0B07A92A3D83A3F23A7D";
43238
- var DEV_PRIVATE_BLOCKCHAIN_RID = "2603569AE8DC3F254323F719C8D4347BBA964E874E781291F8474236BE8B6493";
43236
+ var PROD_ENDPOINT = "https://atbash.ai";
43237
+ var PROD_BLOCKCHAIN_RID = "0163241D9AF137638E63E48EFCDE15510F38C2426F7AD5DC726AF60351BF4DFE";
43238
+ var PROD_PRIVATE_BLOCKCHAIN_RID = "39FFD3557D0296CB2C57FDC6A3B8C024E95639CF4964DA08141AC20C6344D408";
43239
43239
  var DEFAULT_CHROMIA_NODE_URLS_ARR = [
43240
43240
  "https://node0.testnet.chromia.com:7740",
43241
43241
  "https://node1.testnet.chromia.com:7740",
@@ -43394,9 +43394,9 @@ var native = {
43394
43394
  deriveMemoryKey,
43395
43395
  encryptMemoryContent,
43396
43396
  decryptMemoryContent,
43397
- DEFAULT_BLOCKCHAIN_RID: DEV_BLOCKCHAIN_RID,
43398
- DEFAULT_PRIVATE_BLOCKCHAIN_RID: DEV_PRIVATE_BLOCKCHAIN_RID,
43399
- DEFAULT_ENDPOINT: DEV_ENDPOINT,
43397
+ DEFAULT_BLOCKCHAIN_RID: PROD_BLOCKCHAIN_RID,
43398
+ DEFAULT_PRIVATE_BLOCKCHAIN_RID: PROD_PRIVATE_BLOCKCHAIN_RID,
43399
+ DEFAULT_ENDPOINT: PROD_ENDPOINT,
43400
43400
  // Browser has no NAPI channel to Rust's HONEYCOMB_KEY — telemetry
43401
43401
  // silently no-ops. `HONEYCOMB_API_KEY` env var still overrides at runtime.
43402
43402
  HONEYCOMB_KEY: "",
@@ -44126,6 +44126,44 @@ function encryptedLength(plaintextByteLength) {
44126
44126
  return HEADER_LEN + plaintextByteLength + GCM_TAG_LEN;
44127
44127
  }
44128
44128
 
44129
+ // src-ts/crypto/envelope.ts
44130
+ var PREFIX = "atb1";
44131
+ var SEPARATOR = ".";
44132
+ function toBase64(bytes) {
44133
+ let binary = "";
44134
+ for (const b of bytes) binary += String.fromCharCode(b);
44135
+ return btoa(binary);
44136
+ }
44137
+ function fromBase64(text) {
44138
+ const binary = atob(text);
44139
+ const out = new Uint8Array(binary.length);
44140
+ for (let i = 0; i < binary.length; i++) out[i] = binary.charCodeAt(i);
44141
+ return out;
44142
+ }
44143
+ function packEnvelope(payload, keyFingerprint = "", claimHash = "") {
44144
+ return [PREFIX, keyFingerprint, claimHash, toBase64(payload)].join(SEPARATOR);
44145
+ }
44146
+ function fieldWidthOk(value, hexChars) {
44147
+ return value.length === 0 ? true : value.length === hexChars && /^[0-9a-f]+$/.test(value);
44148
+ }
44149
+ function isEnvelope(value) {
44150
+ if (typeof value !== "string" || !value.startsWith(PREFIX + SEPARATOR)) return false;
44151
+ const parts = value.split(SEPARATOR);
44152
+ return parts.length >= 4 && fieldWidthOk(parts[1], 16) && fieldWidthOk(parts[2], 64);
44153
+ }
44154
+ function parseEnvelope(value) {
44155
+ if (!isEnvelope(value)) return null;
44156
+ const [, keyFingerprint, claimHash, ...rest] = value.split(SEPARATOR);
44157
+ try {
44158
+ return { keyFingerprint, claimHash, payload: fromBase64(rest.join(SEPARATOR)) };
44159
+ } catch {
44160
+ return null;
44161
+ }
44162
+ }
44163
+ function keyFingerprintOf(pubKeyHex) {
44164
+ return pubKeyHex.trim().replace(/^0x/i, "").toLowerCase().slice(0, 16);
44165
+ }
44166
+
44129
44167
  // src-ts/browser/encrypted-toolcall.ts
44130
44168
  var { Buffer: PolyBuffer, gtx: pcgtx2 } = index;
44131
44169
  var MERKLE_HASH_VERSION2 = 2;
@@ -44138,6 +44176,9 @@ function claimHashHex(toolName, action, context, toolArgsJson) {
44138
44176
  ]);
44139
44177
  return bytesToHex2(sha256(new TextEncoder().encode(canonical)));
44140
44178
  }
44179
+ function columnAad(toolCallId, column) {
44180
+ return `${toolCallId}:${column}`;
44181
+ }
44141
44182
  function normalizeActionForHash(action) {
44142
44183
  action = action.trim();
44143
44184
  try {
@@ -44183,31 +44224,34 @@ function signOpWithBytes(opName, args, privkeyHex, blockchainRidHex) {
44183
44224
  return pcgtx2.serialize(g).toString("hex");
44184
44225
  }
44185
44226
  function signEncryptedToolCall(toolCallId, action, context, toolName, toolArgsJson, orgEncryptionPubKey, privkeyHex, blockchainRidHex) {
44186
- const plaintext = {
44187
- tool_name: toolName,
44188
- action,
44189
- context,
44190
- tool_args_json: toolArgsJson
44191
- };
44192
- const contentCipher = encryptForOrg(
44193
- JSON.stringify(plaintext),
44194
- orgEncryptionPubKey,
44195
- toolCallId,
44196
- EciesDomain.toolCall
44227
+ const fingerprint = keyFingerprintOf(orgEncryptionPubKey);
44228
+ const seal = (text, column) => text === "" ? "" : packEnvelope(
44229
+ encryptForOrg(
44230
+ text,
44231
+ orgEncryptionPubKey,
44232
+ columnAad(toolCallId, column),
44233
+ EciesDomain.toolCall
44234
+ ),
44235
+ fingerprint
44197
44236
  );
44198
- const actionHash = bytesToHex2(
44199
- sha256(new TextEncoder().encode(normalizeActionForHash(action)))
44237
+ const actionColumn = packEnvelope(
44238
+ encryptForOrg(
44239
+ action,
44240
+ orgEncryptionPubKey,
44241
+ columnAad(toolCallId, "action"),
44242
+ EciesDomain.toolCall
44243
+ ),
44244
+ fingerprint,
44245
+ claimHashHex(toolName, action, context, toolArgsJson)
44200
44246
  );
44201
44247
  return signOpWithBytes(
44202
- "log_encrypted_tool_call",
44248
+ "log_tool_call",
44203
44249
  [
44204
44250
  toolCallId,
44251
+ actionColumn,
44252
+ seal(context, "context"),
44205
44253
  toolName,
44206
- contentCipher,
44207
- actionHash,
44208
- // Empty = "org's current key"; chain resolves it.
44209
- PolyBuffer.from(new Uint8Array(0)),
44210
- claimHashHex(toolName, action, context, toolArgsJson)
44254
+ seal(toolArgsJson, "tool_args")
44211
44255
  ],
44212
44256
  privkeyHex,
44213
44257
  blockchainRidHex
@@ -44215,11 +44259,14 @@ function signEncryptedToolCall(toolCallId, action, context, toolName, toolArgsJs
44215
44259
  }
44216
44260
 
44217
44261
  // src-ts/endpoint.ts
44218
- var ALLOWED_JUDGE_HOSTS = /* @__PURE__ */ new Set([
44219
- "atbash.ai",
44220
- "www.atbash.ai",
44221
- "chromia-verified-ai-dev-two.vercel.app"
44222
- ]);
44262
+ function buildAllowedJudgeHosts() {
44263
+ return /* @__PURE__ */ new Set([
44264
+ "atbash.ai",
44265
+ "www.atbash.ai",
44266
+ new URL(DEFAULT_ENDPOINT).hostname.toLowerCase()
44267
+ ]);
44268
+ }
44269
+ var ALLOWED_JUDGE_HOSTS = buildAllowedJudgeHosts();
44223
44270
  function validateJudgeEndpoint(judge) {
44224
44271
  const policy = judge?.policy === "self-hosted" ? "self-hosted" : "default";
44225
44272
  const candidate = judge?.endpoint?.trim() || DEFAULT_ENDPOINT;
@@ -44421,6 +44468,8 @@ var Atbash = class _Atbash {
44421
44468
  orgEncryptionPubKey;
44422
44469
  /** When true (default), `auditToolCall` denies on any error. */
44423
44470
  failClosed;
44471
+ /** Org key learned from the last agent-exists check, for this agent only. */
44472
+ _orgKeyFromChain = null;
44424
44473
  logger;
44425
44474
  http;
44426
44475
  /**
@@ -44505,6 +44554,10 @@ var Atbash = class _Atbash {
44505
44554
  );
44506
44555
  await this.raiseIfError(resp);
44507
44556
  const data = await this.json(resp);
44557
+ if (pk === this.auth.pubkey) {
44558
+ const key3 = data?.org_encryption_pubkey;
44559
+ this._orgKeyFromChain = typeof key3 === "string" && key3 ? key3 : null;
44560
+ }
44508
44561
  return Boolean(data?.registered);
44509
44562
  });
44510
44563
  }
@@ -44535,7 +44588,7 @@ var Atbash = class _Atbash {
44535
44588
  }
44536
44589
  const toolCallId = generateToolCallId();
44537
44590
  const brid = this.bridFromChainOpts(options.chainOpts);
44538
- const orgKey = options.orgEncryptionPubKey ?? this.orgEncryptionPubKey;
44591
+ const orgKey = options.orgEncryptionPubKey ?? this.orgEncryptionPubKey ?? this._orgKeyFromChain;
44539
44592
  try {
44540
44593
  const signedHex = orgKey ? signEncryptedToolCall(
44541
44594
  toolCallId,
@@ -45694,9 +45747,11 @@ export {
45694
45747
  MemoryIntegrityError,
45695
45748
  PointerStore,
45696
45749
  SignatureVerificationError,
45750
+ buildAllowedJudgeHosts,
45697
45751
  claimHashHex,
45698
45752
  classifyMemoryRead,
45699
45753
  classifyMemoryWrite,
45754
+ columnAad,
45700
45755
  commitMemoryVersion,
45701
45756
  containsEvasionCharacters2 as containsEvasionCharacters,
45702
45757
  containsSecret2 as containsSecret,
@@ -45724,7 +45779,9 @@ export {
45724
45779
  getMemoryHistory,
45725
45780
  getRollbackHistory,
45726
45781
  guardMemoryWrite,
45782
+ isEnvelope,
45727
45783
  isValidPrivateKey2 as isValidPrivateKey,
45784
+ keyFingerprintOf,
45728
45785
  loadAgent2 as loadAgent,
45729
45786
  loadAgentFromFile,
45730
45787
  loadUserConfig,
@@ -45732,6 +45789,8 @@ export {
45732
45789
  normalizeForMatching2 as normalizeForMatching,
45733
45790
  normalizeStatus,
45734
45791
  normalizeVerdict,
45792
+ packEnvelope,
45793
+ parseEnvelope,
45735
45794
  pubkeyToHex,
45736
45795
  recordCall,
45737
45796
  recordDuration,