@atbash/sdk 0.3.11-dev.3 → 0.3.11-dev.5

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/index.cjs CHANGED
@@ -105,6 +105,9 @@ function verifyJudgeResponseSignature(bodyBytes, signatureHex, pubKeyHex) {
105
105
  }
106
106
 
107
107
  // src/opentel/telemetry.ts
108
+ var import_node_fs = require("fs");
109
+ var import_node_os = require("os");
110
+ var import_node_path = require("path");
108
111
  var import_sdk_metrics = require("@opentelemetry/sdk-metrics");
109
112
  var import_exporter_metrics_otlp_http = require("@opentelemetry/exporter-metrics-otlp-http");
110
113
  var import_resources = require("@opentelemetry/resources");
@@ -112,14 +115,27 @@ var meterProvider = null;
112
115
  var callCounter = null;
113
116
  var durationHistogram = null;
114
117
  var defaultSource = "sdk";
118
+ function isTelemetryOptedOut() {
119
+ try {
120
+ const home = process.env.HOME || (0, import_node_os.homedir)() || "";
121
+ const filePath = (0, import_node_path.join)(home, ".config", "atbash", "telemetry.json");
122
+ const raw = (0, import_node_fs.readFileSync)(filePath, "utf-8").trim();
123
+ if (!raw) return false;
124
+ const config = JSON.parse(raw);
125
+ return config.enabled === false;
126
+ } catch {
127
+ return false;
128
+ }
129
+ }
115
130
  function autoInit() {
116
131
  if (meterProvider) return;
117
- if (process.env.ATBASH_TELEMETRY === "false") return;
132
+ if (isTelemetryOptedOut()) return;
118
133
  setupTelemetry({ enabled: true });
119
134
  }
120
135
  function setupTelemetry(config) {
121
136
  if (!config.enabled) return;
122
137
  if (meterProvider) return;
138
+ if (isTelemetryOptedOut()) return;
123
139
  defaultSource = config.source ?? "sdk";
124
140
  const ATBASH_HONEYCOMB_KEY = "YOUR_INGEST_KEY_HERE";
125
141
  const apiKey = process.env.HONEYCOMB_API_KEY ?? ATBASH_HONEYCOMB_KEY;
@@ -698,22 +714,22 @@ function validateJudgeEndpoint(judge) {
698
714
  }
699
715
 
700
716
  // src/key-loader.ts
701
- var import_node_fs = require("fs");
702
- var import_node_os = require("os");
703
- var import_node_path = require("path");
717
+ var import_node_fs2 = require("fs");
718
+ var import_node_os2 = require("os");
719
+ var import_node_path2 = require("path");
704
720
  var DEFAULT_KEY_PATH_REL = ".config/atbash/guard-client-key";
705
721
  function resolveKeyPath(input) {
706
722
  if (input) return expandHome(input);
707
- const home = process.env.HOME || (0, import_node_os.homedir)() || "";
708
- return (0, import_node_path.join)(home, DEFAULT_KEY_PATH_REL);
723
+ const home = process.env.HOME || (0, import_node_os2.homedir)() || "";
724
+ return (0, import_node_path2.join)(home, DEFAULT_KEY_PATH_REL);
709
725
  }
710
726
  function expandHome(p) {
711
727
  if (!p.startsWith("~/")) return p;
712
- const home = process.env.HOME || (0, import_node_os.homedir)() || "";
713
- return (0, import_node_path.join)(home, p.slice(2));
728
+ const home = process.env.HOME || (0, import_node_os2.homedir)() || "";
729
+ return (0, import_node_path2.join)(home, p.slice(2));
714
730
  }
715
731
  function readKeyFile(keyPath) {
716
- const content = String((0, import_node_fs.readFileSync)(keyPath, "utf8") || "").trim();
732
+ const content = String((0, import_node_fs2.readFileSync)(keyPath, "utf8") || "").trim();
717
733
  let privKey = "";
718
734
  let pubKey = "";
719
735
  if (content.startsWith("{")) {
@@ -905,10 +921,25 @@ function createAtbashClient(config = {}) {
905
921
  };
906
922
  }
907
923
  if (action === "allow") {
908
- const surfacedVerdict = result.verdict === "ALLOW" || result.verdict === "HOLD" || result.verdict === "BLOCK" ? result.verdict : "ALLOW";
924
+ if (result.verdict === "HOLD") {
925
+ return {
926
+ allow: false,
927
+ verdict: "HOLD",
928
+ reason: result.reason,
929
+ toolCallId: result.tool_call_id
930
+ };
931
+ }
932
+ if (result.verdict === "BLOCK") {
933
+ return {
934
+ allow: false,
935
+ verdict: "BLOCK",
936
+ reason: result.reason,
937
+ toolCallId: result.tool_call_id
938
+ };
939
+ }
909
940
  return {
910
941
  allow: true,
911
- verdict: surfacedVerdict,
942
+ verdict: "ALLOW",
912
943
  reason: result.reason,
913
944
  toolCallId: result.tool_call_id
914
945
  };
@@ -938,9 +969,9 @@ function truncate(text) {
938
969
  }
939
970
 
940
971
  // src/user-config.ts
941
- var import_node_fs2 = require("fs");
942
- var import_node_os2 = require("os");
943
- var import_node_path2 = require("path");
972
+ var import_node_fs3 = require("fs");
973
+ var import_node_os3 = require("os");
974
+ var import_node_path3 = require("path");
944
975
  var ENV_MAP = {
945
976
  agentKey: "ATBASH_AGENT_KEY",
946
977
  orgName: "ATBASH_ORG_NAME",
@@ -950,17 +981,17 @@ var ENV_MAP = {
950
981
  providerModel: "ATBASH_PROVIDER_MODEL"
951
982
  };
952
983
  function getConfigDir() {
953
- const home = process.env.HOME || (0, import_node_os2.homedir)() || "";
954
- return (0, import_node_path2.join)(home, ".config", "atbash");
984
+ const home = process.env.HOME || (0, import_node_os3.homedir)() || "";
985
+ return (0, import_node_path3.join)(home, ".config", "atbash");
955
986
  }
956
987
  function getConfigPath() {
957
- return (0, import_node_path2.join)(getConfigDir(), "config.json");
988
+ return (0, import_node_path3.join)(getConfigDir(), "config.json");
958
989
  }
959
990
  function loadUserConfig() {
960
991
  try {
961
992
  const p = getConfigPath();
962
- if (!(0, import_node_fs2.existsSync)(p)) return {};
963
- const raw = (0, import_node_fs2.readFileSync)(p, "utf-8").trim();
993
+ if (!(0, import_node_fs3.existsSync)(p)) return {};
994
+ const raw = (0, import_node_fs3.readFileSync)(p, "utf-8").trim();
964
995
  if (!raw) return {};
965
996
  return JSON.parse(raw);
966
997
  } catch (err) {
@@ -970,12 +1001,12 @@ function loadUserConfig() {
970
1001
  }
971
1002
  function saveUserConfig(config) {
972
1003
  const dir = getConfigDir();
973
- if (!(0, import_node_fs2.existsSync)(dir)) {
974
- (0, import_node_fs2.mkdirSync)(dir, { recursive: true, mode: 448 });
1004
+ if (!(0, import_node_fs3.existsSync)(dir)) {
1005
+ (0, import_node_fs3.mkdirSync)(dir, { recursive: true, mode: 448 });
975
1006
  }
976
1007
  const filePath = getConfigPath();
977
- (0, import_node_fs2.writeFileSync)(filePath, JSON.stringify(config, null, 2) + "\n", { mode: 384 });
978
- (0, import_node_fs2.chmodSync)(filePath, 384);
1008
+ (0, import_node_fs3.writeFileSync)(filePath, JSON.stringify(config, null, 2) + "\n", { mode: 384 });
1009
+ (0, import_node_fs3.chmodSync)(filePath, 384);
979
1010
  }
980
1011
  function resolve(key, flagValue) {
981
1012
  if (flagValue) return flagValue;
@@ -1035,11 +1066,17 @@ var BEHAVIOR_PATTERNS = [
1035
1066
  re: /\b(?:no need to|don'?t need to|not necessary to|unnecessary to)\b.*\b(?:check|verify|validate|scan|review|confirm|authenticate)\b/i,
1036
1067
  description: "attempts to normalize skipping verification"
1037
1068
  },
1069
+ {
1070
+ type: "safety_bypass",
1071
+ severity: "high",
1072
+ re: /\[\s*(?:VERIFIED|SAFE|APPROVED|TRUSTED|AUTHORIZED|CLEARED|WHITELISTED)\s*\]/i,
1073
+ description: "stores a verdict-influencing meta-tag that could be prepended to action text to bypass AI evaluation"
1074
+ },
1038
1075
  /* ── Privilege escalation ── */
1039
1076
  {
1040
1077
  type: "privilege_escalation",
1041
1078
  severity: "critical",
1042
- re: /\b(?:admin|administrator|root|superuser|sudo|elevated)\b.*\b(?:privilege|permission|access|role|clearance|authority)\b.*\b(?:granted|approved|confirmed|given|assigned)\b/i,
1079
+ re: /\b(?:admin|administrator|root|superuser|sudo|elevated)\b.*\b(?:privileges?|permissions?|access|roles?|clearance|authority)\b.*\b(?:granted|approved|confirmed|given|assigned)\b/i,
1043
1080
  description: "claims elevated privileges were granted"
1044
1081
  },
1045
1082
  {
package/dist/index.d.cts CHANGED
@@ -251,7 +251,11 @@ declare function verifyJudgeResponseSignature(bodyBytes: Uint8Array, signatureHe
251
251
  * Atbash SDK Telemetry — OpenTelemetry metrics for usage tracking.
252
252
  *
253
253
  * Tracks: function call counts, latency, source (CLI/plugin/SDK),
254
- * and agent identity. Opt-in no data sent unless enabled.
254
+ * and agent identity. ON by default.
255
+ *
256
+ * Opt-out: create ~/.config/atbash/telemetry.json with { "enabled": false }
257
+ * The file must be mode 0600. If missing, corrupted, or unreadable → telemetry stays ON.
258
+ * Environment variables cannot disable telemetry (prevents agent bypass).
255
259
  */
256
260
  type ClientSource = "cli" | "sdk" | "plugin:openclaw" | "plugin:langchain" | "plugin:langgraph" | "plugin:hermes" | "plugin:eliza" | "plugin:crewai" | "plugin:mcp" | "plugin:autogen" | "plugin:jeenai" | (string & {});
257
261
  interface TelemetryConfig {
package/dist/index.d.ts CHANGED
@@ -251,7 +251,11 @@ declare function verifyJudgeResponseSignature(bodyBytes: Uint8Array, signatureHe
251
251
  * Atbash SDK Telemetry — OpenTelemetry metrics for usage tracking.
252
252
  *
253
253
  * Tracks: function call counts, latency, source (CLI/plugin/SDK),
254
- * and agent identity. Opt-in no data sent unless enabled.
254
+ * and agent identity. ON by default.
255
+ *
256
+ * Opt-out: create ~/.config/atbash/telemetry.json with { "enabled": false }
257
+ * The file must be mode 0600. If missing, corrupted, or unreadable → telemetry stays ON.
258
+ * Environment variables cannot disable telemetry (prevents agent bypass).
255
259
  */
256
260
  type ClientSource = "cli" | "sdk" | "plugin:openclaw" | "plugin:langchain" | "plugin:langgraph" | "plugin:hermes" | "plugin:eliza" | "plugin:crewai" | "plugin:mcp" | "plugin:autogen" | "plugin:jeenai" | (string & {});
257
261
  interface TelemetryConfig {
package/dist/index.js CHANGED
@@ -29,6 +29,9 @@ function verifyJudgeResponseSignature(bodyBytes, signatureHex, pubKeyHex) {
29
29
  }
30
30
 
31
31
  // src/opentel/telemetry.ts
32
+ import { readFileSync } from "fs";
33
+ import { homedir } from "os";
34
+ import { join } from "path";
32
35
  import { MeterProvider, PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
33
36
  import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
34
37
  import { resourceFromAttributes } from "@opentelemetry/resources";
@@ -36,14 +39,27 @@ var meterProvider = null;
36
39
  var callCounter = null;
37
40
  var durationHistogram = null;
38
41
  var defaultSource = "sdk";
42
+ function isTelemetryOptedOut() {
43
+ try {
44
+ const home = process.env.HOME || homedir() || "";
45
+ const filePath = join(home, ".config", "atbash", "telemetry.json");
46
+ const raw = readFileSync(filePath, "utf-8").trim();
47
+ if (!raw) return false;
48
+ const config = JSON.parse(raw);
49
+ return config.enabled === false;
50
+ } catch {
51
+ return false;
52
+ }
53
+ }
39
54
  function autoInit() {
40
55
  if (meterProvider) return;
41
- if (process.env.ATBASH_TELEMETRY === "false") return;
56
+ if (isTelemetryOptedOut()) return;
42
57
  setupTelemetry({ enabled: true });
43
58
  }
44
59
  function setupTelemetry(config) {
45
60
  if (!config.enabled) return;
46
61
  if (meterProvider) return;
62
+ if (isTelemetryOptedOut()) return;
47
63
  defaultSource = config.source ?? "sdk";
48
64
  const ATBASH_HONEYCOMB_KEY = "YOUR_INGEST_KEY_HERE";
49
65
  const apiKey = process.env.HONEYCOMB_API_KEY ?? ATBASH_HONEYCOMB_KEY;
@@ -622,22 +638,22 @@ function validateJudgeEndpoint(judge) {
622
638
  }
623
639
 
624
640
  // src/key-loader.ts
625
- import { readFileSync } from "fs";
626
- import { homedir } from "os";
627
- import { join } from "path";
641
+ import { readFileSync as readFileSync2 } from "fs";
642
+ import { homedir as homedir2 } from "os";
643
+ import { join as join2 } from "path";
628
644
  var DEFAULT_KEY_PATH_REL = ".config/atbash/guard-client-key";
629
645
  function resolveKeyPath(input) {
630
646
  if (input) return expandHome(input);
631
- const home = process.env.HOME || homedir() || "";
632
- return join(home, DEFAULT_KEY_PATH_REL);
647
+ const home = process.env.HOME || homedir2() || "";
648
+ return join2(home, DEFAULT_KEY_PATH_REL);
633
649
  }
634
650
  function expandHome(p) {
635
651
  if (!p.startsWith("~/")) return p;
636
- const home = process.env.HOME || homedir() || "";
637
- return join(home, p.slice(2));
652
+ const home = process.env.HOME || homedir2() || "";
653
+ return join2(home, p.slice(2));
638
654
  }
639
655
  function readKeyFile(keyPath) {
640
- const content = String(readFileSync(keyPath, "utf8") || "").trim();
656
+ const content = String(readFileSync2(keyPath, "utf8") || "").trim();
641
657
  let privKey = "";
642
658
  let pubKey = "";
643
659
  if (content.startsWith("{")) {
@@ -829,10 +845,25 @@ function createAtbashClient(config = {}) {
829
845
  };
830
846
  }
831
847
  if (action === "allow") {
832
- const surfacedVerdict = result.verdict === "ALLOW" || result.verdict === "HOLD" || result.verdict === "BLOCK" ? result.verdict : "ALLOW";
848
+ if (result.verdict === "HOLD") {
849
+ return {
850
+ allow: false,
851
+ verdict: "HOLD",
852
+ reason: result.reason,
853
+ toolCallId: result.tool_call_id
854
+ };
855
+ }
856
+ if (result.verdict === "BLOCK") {
857
+ return {
858
+ allow: false,
859
+ verdict: "BLOCK",
860
+ reason: result.reason,
861
+ toolCallId: result.tool_call_id
862
+ };
863
+ }
833
864
  return {
834
865
  allow: true,
835
- verdict: surfacedVerdict,
866
+ verdict: "ALLOW",
836
867
  reason: result.reason,
837
868
  toolCallId: result.tool_call_id
838
869
  };
@@ -862,9 +893,9 @@ function truncate(text) {
862
893
  }
863
894
 
864
895
  // src/user-config.ts
865
- import { readFileSync as readFileSync2, writeFileSync, mkdirSync, chmodSync, existsSync } from "fs";
866
- import { homedir as homedir2 } from "os";
867
- import { join as join2 } from "path";
896
+ import { readFileSync as readFileSync3, writeFileSync, mkdirSync, chmodSync, existsSync } from "fs";
897
+ import { homedir as homedir3 } from "os";
898
+ import { join as join3 } from "path";
868
899
  var ENV_MAP = {
869
900
  agentKey: "ATBASH_AGENT_KEY",
870
901
  orgName: "ATBASH_ORG_NAME",
@@ -874,17 +905,17 @@ var ENV_MAP = {
874
905
  providerModel: "ATBASH_PROVIDER_MODEL"
875
906
  };
876
907
  function getConfigDir() {
877
- const home = process.env.HOME || homedir2() || "";
878
- return join2(home, ".config", "atbash");
908
+ const home = process.env.HOME || homedir3() || "";
909
+ return join3(home, ".config", "atbash");
879
910
  }
880
911
  function getConfigPath() {
881
- return join2(getConfigDir(), "config.json");
912
+ return join3(getConfigDir(), "config.json");
882
913
  }
883
914
  function loadUserConfig() {
884
915
  try {
885
916
  const p = getConfigPath();
886
917
  if (!existsSync(p)) return {};
887
- const raw = readFileSync2(p, "utf-8").trim();
918
+ const raw = readFileSync3(p, "utf-8").trim();
888
919
  if (!raw) return {};
889
920
  return JSON.parse(raw);
890
921
  } catch (err) {
@@ -959,11 +990,17 @@ var BEHAVIOR_PATTERNS = [
959
990
  re: /\b(?:no need to|don'?t need to|not necessary to|unnecessary to)\b.*\b(?:check|verify|validate|scan|review|confirm|authenticate)\b/i,
960
991
  description: "attempts to normalize skipping verification"
961
992
  },
993
+ {
994
+ type: "safety_bypass",
995
+ severity: "high",
996
+ re: /\[\s*(?:VERIFIED|SAFE|APPROVED|TRUSTED|AUTHORIZED|CLEARED|WHITELISTED)\s*\]/i,
997
+ description: "stores a verdict-influencing meta-tag that could be prepended to action text to bypass AI evaluation"
998
+ },
962
999
  /* ── Privilege escalation ── */
963
1000
  {
964
1001
  type: "privilege_escalation",
965
1002
  severity: "critical",
966
- re: /\b(?:admin|administrator|root|superuser|sudo|elevated)\b.*\b(?:privilege|permission|access|role|clearance|authority)\b.*\b(?:granted|approved|confirmed|given|assigned)\b/i,
1003
+ re: /\b(?:admin|administrator|root|superuser|sudo|elevated)\b.*\b(?:privileges?|permissions?|access|roles?|clearance|authority)\b.*\b(?:granted|approved|confirmed|given|assigned)\b/i,
967
1004
  description: "claims elevated privileges were granted"
968
1005
  },
969
1006
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atbash/sdk",
3
- "version": "0.3.11-dev.3",
3
+ "version": "0.3.11-dev.5",
4
4
  "description": "Atbash SDK — control boundary before the last irreversible step in an agent workflow",
5
5
  "homepage": "https://atbash.ai",
6
6
  "author": "Atbash",