@optimuslabs/pii-scrub-staging 0.1.0 → 0.1.1

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/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # @optimuslabs/pii-scrub
2
2
 
3
- Redacts secrets, and optionally personal data (email names, home-directory usernames), from what an
4
- Optimus endpoint sends, before the request leaves the machine. Used by `@optimuslabs/runtime`
3
+ Redacts secrets from what an Optimus endpoint sends, before the request leaves the machine. Personal
4
+ data (emails, home directories) is not redacted: the backend reads it for owners, tenants and path
5
+ matching. Used by `@optimuslabs/runtime`
5
6
  (tool calls), `@optimuslabs/harness-map` (config file inventory) and `@optimuslabs/discovery`
6
7
  (which sends the version). Design: `docs/pii-scrubbing/DESIGN.md`.
7
8
 
@@ -10,7 +11,7 @@ import { SCRUBBER_VERSION, scrub, scrubText, scrubValue } from "@optimuslabs/pii
10
11
 
11
12
  scrubValue({ env: { BRAVE_API_KEY: "BSA..." } }); // { env: { BRAVE_API_KEY: "[OL_REDACTED:CREDENTIAL_ENV_VAR]" } }
12
13
  scrubText("key sk-ant-api03-...", { fingerprintKey }); // "key sk-ant-api03-[OL_REDACTED:ANTHROPIC_KEY:<24 hex>]"
13
- scrubText("ada@gmail.com", { personalData: true }); // "[OL_REDACTED:EMAIL]@gmail.com"
14
+ scrubValue({ command: "npx", env: { LOG_LEVEL: "debug" } }); // unchanged: only secrets are redacted
14
15
  scrub(payload).hits; // { ANTHROPIC_KEY: 1, ... }; placeholders already there are not hits
15
16
  ```
16
17
 
@@ -18,5 +19,9 @@ The rules are in `rules.json`, which the backend reads too; every pattern works
18
19
  JavaScript and Python regex engines. Only vendor-format secrets are fingerprinted (HMAC-SHA256
19
20
  under the org key, 96 bits), and only when the caller passes the key.
20
21
 
22
+ An organization can switch scrubbing off (OPT-942). The senders store the backend's `scrub_pii` in
23
+ `~/.optimuslabs/management/org/config.json`, and every function here returns its input unchanged
24
+ while that file says `"scrub_pii": false`. No file, or no field, means scrub.
25
+
21
26
  The staging build publishes as `@optimuslabs/pii-scrub-staging`, the production build as
22
27
  `@optimuslabs/pii-scrub`.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  /**
2
- * Redact secrets, and optionally personal data, from what an endpoint sends to Optimus.
2
+ * Redact secrets from what an endpoint sends to Optimus. Personal data (emails, home directories)
3
+ * is not redacted: the backend reads it for identity, owners and path matching.
3
4
  *
4
5
  * Runs on the endpoint, just before a request is built, so the value never leaves the machine.
5
6
  * A value is replaced with a typed placeholder rather than dropped, so the backend still knows a
@@ -7,9 +8,7 @@
7
8
  *
8
9
  * sk-ant-api03-[OL_REDACTED:ANTHROPIC_KEY:<fp>] a vendor key keeps its published prefix
9
10
  * [OL_REDACTED:CREDENTIAL_ENV_VAR] a value under a credential-named key
10
- * [OL_REDACTED:ENV_VALUE] any other value in an MCP server's env block
11
- * [OL_REDACTED:EMAIL]@gmail.com an email inside content keeps its domain
12
- * /Users/[OL_REDACTED:USERNAME]/src a home directory keeps its path
11
+ * [OL_REDACTED:POTENTIAL_TOKEN] a 40+ character token in an MCP server's env
13
12
  *
14
13
  * `<fp>` is a 96-bit fingerprint (24 hex characters, HMAC-SHA256 under the org's key), on
15
14
  * vendor-format secrets only, so the same key is recognisable across configs and machines
@@ -21,16 +20,11 @@
21
20
  * is and is not a hit, so scrubbing twice changes nothing and counts nothing.
22
21
  */
23
22
  export { SECRET_FORMATS } from "./rules.js";
23
+ export { scrubbingSwitchedOff } from "./org-setting.js";
24
24
  /** This scrubber's version (the package's), which every sender includes with what it scrubbed. */
25
25
  export declare const SCRUBBER_VERSION: string;
26
26
  export declare const PLACEHOLDER_PREFIX = "[OL_REDACTED:";
27
27
  export interface ScrubOptions {
28
- /**
29
- * Also redact personal data: the name part of emails and the username in home directories. On
30
- * for tool-call content; off for config files, where account emails are identity (agent owners,
31
- * tenant approval, the personal-email finding) and stay readable.
32
- */
33
- personalData?: boolean;
34
28
  /** The org's fingerprint key, hex. Absent until the endpoint has received it: no fingerprints. */
35
29
  fingerprintKey?: string;
36
30
  }
@@ -44,11 +38,15 @@ export declare function placeholder(type: string, fingerprint?: string): string;
44
38
  /**
45
39
  * A deep copy of `value` with every string scrubbed and every value under a credential-named key
46
40
  * redacted, and how many of each type were redacted. Non-string leaves are returned as they are.
41
+ * When the organization has switched scrubbing off, `value` itself, with no hits.
47
42
  */
48
43
  export declare function scrub<T>(value: T, options?: ScrubOptions): ScrubResult<T>;
49
44
  /** `scrub(value).value`. */
50
45
  export declare function scrubValue<T>(value: T, options?: ScrubOptions): T;
51
- /** A copy of `text` with every secret, and with `personalData` emails and usernames, redacted. */
46
+ /**
47
+ * A copy of `text` with every secret redacted;
48
+ * `text` itself when the organization has switched scrubbing off.
49
+ */
52
50
  export declare function scrubText(text: string, options?: ScrubOptions): string;
53
51
  /**
54
52
  * A copy of `record` with each of `fields` that is a string scrubbed as text, the rest untouched:
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAmBH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,kGAAkG;AAClG,eAAO,MAAM,gBAAgB,EAAE,MAA2F,CAAC;AAE3H,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAElD,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,kGAAkG;IAClG,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,8FAA8F;AAC9F,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE/C,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,KAAK,EAAE,CAAC,CAAC;IACT,IAAI,EAAE,SAAS,CAAC;CACjB;AAWD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAEtE;AAgID;;;GAGG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,GAAE,YAAiB,GAAG,WAAW,CAAC,CAAC,CAAC,CAG7E;AAED,4BAA4B;AAC5B,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,GAAE,YAAiB,GAAG,CAAC,CAErE;AAED,kGAAkG;AAClG,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,MAAM,CAE1E;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3D,MAAM,EAAE,CAAC,EACT,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,OAAO,GAAE,YAAiB,GACzB,CAAC,CAMH;AAED,mGAAmG;AACnG,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAO3D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAyBH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,kGAAkG;AAClG,eAAO,MAAM,gBAAgB,EAAE,MAA2F,CAAC;AAE3H,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAElD,MAAM,WAAW,YAAY;IAC3B,kGAAkG;IAClG,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,8FAA8F;AAC9F,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE/C,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,KAAK,EAAE,CAAC,CAAC;IACT,IAAI,EAAE,SAAS,CAAC;CACjB;AAcD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAEtE;AA4MD;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,GAAE,YAAiB,GAAG,WAAW,CAAC,CAAC,CAAC,CAI7E;AAED,4BAA4B;AAC5B,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,GAAE,YAAiB,GAAG,CAAC,CAErE;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,MAAM,CAG1E;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3D,MAAM,EAAE,CAAC,EACT,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,OAAO,GAAE,YAAiB,GACzB,CAAC,CAOH;AAED,mGAAmG;AACnG,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAO3D"}
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  /**
2
- * Redact secrets, and optionally personal data, from what an endpoint sends to Optimus.
2
+ * Redact secrets from what an endpoint sends to Optimus. Personal data (emails, home directories)
3
+ * is not redacted: the backend reads it for identity, owners and path matching.
3
4
  *
4
5
  * Runs on the endpoint, just before a request is built, so the value never leaves the machine.
5
6
  * A value is replaced with a typed placeholder rather than dropped, so the backend still knows a
@@ -7,9 +8,7 @@
7
8
  *
8
9
  * sk-ant-api03-[OL_REDACTED:ANTHROPIC_KEY:<fp>] a vendor key keeps its published prefix
9
10
  * [OL_REDACTED:CREDENTIAL_ENV_VAR] a value under a credential-named key
10
- * [OL_REDACTED:ENV_VALUE] any other value in an MCP server's env block
11
- * [OL_REDACTED:EMAIL]@gmail.com an email inside content keeps its domain
12
- * /Users/[OL_REDACTED:USERNAME]/src a home directory keeps its path
11
+ * [OL_REDACTED:POTENTIAL_TOKEN] a 40+ character token in an MCP server's env
13
12
  *
14
13
  * `<fp>` is a 96-bit fingerprint (24 hex characters, HMAC-SHA256 under the org's key), on
15
14
  * vendor-format secrets only, so the same key is recognisable across configs and machines
@@ -22,13 +21,18 @@
22
21
  */
23
22
  import { createHmac } from "node:crypto";
24
23
  import { createRequire } from "node:module";
25
- import { CONTAINS_REFERENCE, CREDENTIAL_ASSIGNMENT, CREDENTIAL_FLAG, CREDENTIAL_KEY, EMAIL, ENV_REFERENCE, HOME_DIRECTORY, MCP_SERVER_KEYS, MCP_VALUE_BLOCKS, MIN_CREDENTIAL_LENGTH, RESERVED_EMAIL_DOMAIN, SECRET_FORMATS, } from "./rules.js";
24
+ import { CODE_VALUE, CONTAINER_KEEP, CONTAINS_REFERENCE, CREDENTIAL_ASSIGNMENT, CREDENTIAL_CONTAINER, CREDENTIAL_FLAG, CREDENTIAL_KEY, ENV_REFERENCE, GENERIC_TOKEN, JSON_SCHEMA_TYPES, MCP_SERVER_KEYS, MCP_VALUE_BLOCKS, MIN_CREDENTIAL_LENGTH, NOT_A_SECRET_UNDER_WEAK_KEY, PLACEHOLDER_VALUE, SECRET_FORMATS, WEAK_CREDENTIAL_KEY, } from "./rules.js";
25
+ import { scrubbingSwitchedOff } from "./org-setting.js";
26
26
  export { SECRET_FORMATS } from "./rules.js";
27
+ export { scrubbingSwitchedOff } from "./org-setting.js";
27
28
  /** This scrubber's version (the package's), which every sender includes with what it scrubbed. */
28
29
  export const SCRUBBER_VERSION = createRequire(import.meta.url)("../package.json").version;
29
30
  export const PLACEHOLDER_PREFIX = "[OL_REDACTED:";
30
- /** How deep a payload may nest before the scrubber stops descending (and redacts the rest). */
31
- const MAX_DEPTH = 32;
31
+ /**
32
+ * How deep a payload may nest before the scrubber stops descending (and redacts the rest). MCP tool
33
+ * input schemas in agent configs nest past 32 (measured on prod data), so the limit sits well above.
34
+ */
35
+ const MAX_DEPTH = 128;
32
36
  const FINGERPRINT_HEX_LENGTH = 24;
33
37
  export function placeholder(type, fingerprint) {
34
38
  return fingerprint ? `${PLACEHOLDER_PREFIX}${type}:${fingerprint}]` : `${PLACEHOLDER_PREFIX}${type}]`;
@@ -49,37 +53,60 @@ function isCredentialValue(value) {
49
53
  return (trimmed.length >= MIN_CREDENTIAL_LENGTH &&
50
54
  !/\s/.test(trimmed) &&
51
55
  !ENV_REFERENCE.test(trimmed) &&
56
+ !PLACEHOLDER_VALUE.test(trimmed) &&
52
57
  // A placeholder, or the front of one that a text rule cut at its closing `]`.
53
58
  !trimmed.includes(PLACEHOLDER_PREFIX));
54
59
  }
60
+ /**
61
+ * Whether `name` names a credential, for its `value`. A bare `_key` name (`DEPLOY_SSH_KEY`, but
62
+ * also `issue_key`, `session_key`) counts only when the value is not an identifier of something else.
63
+ */
64
+ function isCredentialName(name, value) {
65
+ if (CREDENTIAL_KEY.test(name))
66
+ return true;
67
+ return WEAK_CREDENTIAL_KEY.test(name) && !NOT_A_SECRET_UNDER_WEAK_KEY.test(value.trim());
68
+ }
69
+ /** A reference to a secret stored elsewhere, or a documentation placeholder where one goes. */
70
+ function isReferenceOrPlaceholder(secret) {
71
+ return CONTAINS_REFERENCE.test(secret) || ENV_REFERENCE.test(secret) || PLACEHOLDER_VALUE.test(secret);
72
+ }
55
73
  function redactFormats(text, pass) {
56
74
  let out = text;
57
75
  for (const format of SECRET_FORMATS) {
58
76
  out = out.replace(format.pattern, (match, prefix) => {
77
+ // Over a placeholder already written (`https://[OL_REDACTED:URL_CREDENTIALS]@host`): left as
78
+ // it is, so scrubbing twice changes nothing and counts nothing.
79
+ if (match.includes(PLACEHOLDER_PREFIX))
80
+ return match;
81
+ const kept = typeof prefix === "string" ? prefix : "";
82
+ if (format.skipPlaceholders && isReferenceOrPlaceholder(match.slice(kept.length)))
83
+ return match;
59
84
  const fingerprint = format.fingerprint ? fingerprintOf(pass, match) : undefined;
60
- return `${typeof prefix === "string" ? prefix : ""}${redacted(pass, format.type, fingerprint)}`;
85
+ return `${kept}${redacted(pass, format.type, fingerprint)}`;
61
86
  });
62
87
  }
63
88
  return out;
64
89
  }
65
- function redactAssignments(text, pass) {
66
- return text.replace(CREDENTIAL_ASSIGNMENT, (match, name, value) => isCredentialValue(value) ? `${name}${redacted(pass, "CREDENTIAL_ENV_VAR")}` : match);
90
+ /** Whether `offset` falls inside a placeholder already written, such as `[OL_REDACTED:GITHUB_TOKEN:<fp>]`. */
91
+ function insidePlaceholder(text, offset) {
92
+ const open = text.lastIndexOf(PLACEHOLDER_PREFIX, offset);
93
+ return open !== -1 && text.indexOf("]", open) >= offset;
67
94
  }
68
- function redactPersonalData(text, pass) {
69
- // `git@github.com:` is an SSH remote, and a reserved domain is documentation: neither is a person.
70
- const emailsDone = text.replace(EMAIL, (match, domain) => match.startsWith("git@") || RESERVED_EMAIL_DOMAIN.test(domain)
71
- ? match
72
- : `${redacted(pass, "EMAIL")}@${domain}`);
73
- return emailsDone.replace(HOME_DIRECTORY, (_match, root) => `${root}${redacted(pass, "USERNAME")}`);
95
+ function redactAssignments(text, pass) {
96
+ return text.replace(CREDENTIAL_ASSIGNMENT, (match, name, value, offset) =>
97
+ // `credential = client.beta(` and `credential: data.credential` are code, not a secret; the
98
+ // `TOKEN:<fp>` of a fingerprinted placeholder is the placeholder, not an assignment.
99
+ isCredentialValue(value) && !CODE_VALUE.test(value) && !insidePlaceholder(text, offset)
100
+ ? `${name}${redacted(pass, "CREDENTIAL_ENV_VAR")}`
101
+ : match);
74
102
  }
75
103
  function scrubString(text, pass) {
76
104
  if (!text)
77
105
  return text;
78
- const out = redactAssignments(redactFormats(text, pass), pass);
79
- return pass.options.personalData ? redactPersonalData(out, pass) : out;
106
+ return redactAssignments(redactFormats(text, pass), pass);
80
107
  }
81
108
  function scrubLeaf(value, pass, key) {
82
- if (key !== undefined && CREDENTIAL_KEY.test(key) && isCredentialValue(value)) {
109
+ if (key !== undefined && isCredentialName(key, value) && isCredentialValue(value)) {
83
110
  // A recognised format keeps its prefix, type and fingerprint; anything else is just a credential.
84
111
  const formatted = redactFormats(value, pass);
85
112
  return formatted !== value ? formatted : redacted(pass, "CREDENTIAL_ENV_VAR");
@@ -89,60 +116,115 @@ function scrubLeaf(value, pass, key) {
89
116
  function isPlainObject(value) {
90
117
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
91
118
  }
119
+ /** A JSON Schema node (an MCP tool's input schema): `{"type": "array", ...}` describes data, holds none. */
120
+ function isSchemaNode(value) {
121
+ if (!isPlainObject(value))
122
+ return false;
123
+ return typeof value.type === "string" && JSON_SCHEMA_TYPES.has(value.type);
124
+ }
92
125
  /**
93
- * A value in an MCP server's env or headers block. Every one is redacted, because a server's
94
- * secrets sit there under whatever name its author chose: a known format keeps its prefix, type
95
- * and fingerprint; a credential-named one is a credential; anything else is typed by the block
96
- * (`ENV_VALUE`, `HEADER_VALUE`), which the backend does not read as a secret. A reference to a
97
- * secret stored elsewhere (`${TOKEN}`, `Bearer ${TOKEN}`) stays readable.
126
+ * An MCP server definition: a server key holding a string or list (`command`, `url`, `args`). A
127
+ * schema's `properties` map with a `type` or `url` property holds objects there, and is not one.
98
128
  */
99
- function redactBlockValue(value, name, ordinaryType, pass) {
100
- if (!value.trim() || CONTAINS_REFERENCE.test(value) || ENV_REFERENCE.test(value.trim()))
101
- return value;
102
- if (value.includes(PLACEHOLDER_PREFIX))
129
+ function isServerDefinition(obj) {
130
+ if (isSchemaNode(obj))
131
+ return false;
132
+ return Object.entries(obj).some(([k, v]) => MCP_SERVER_KEYS.has(k) && (typeof v === "string" || Array.isArray(v)));
133
+ }
134
+ /** Whether a value can be redacted whole: not empty, not a reference, not already a placeholder. */
135
+ function isRedactable(value) {
136
+ return Boolean(value.trim()) && !CONTAINS_REFERENCE.test(value) && !ENV_REFERENCE.test(value.trim()) && !value.includes(PLACEHOLDER_PREFIX);
137
+ }
138
+ /**
139
+ * The backend's generic token (`HardcodedSecretRule`'s "Potential token/secret"): 40 or more
140
+ * letters, digits, `_` and `-`. In a URL only the query is searched, as the backend does: a host
141
+ * or path is not a token.
142
+ */
143
+ function redactGenericTokens(value, pass) {
144
+ const replace = (text) => text.replace(GENERIC_TOKEN, (token) => (token.length >= 40 ? redacted(pass, "POTENTIAL_TOKEN") : token));
145
+ if (!value.includes("://"))
146
+ return replace(value);
147
+ const query = value.indexOf("?");
148
+ return query === -1 ? value : value.slice(0, query + 1) + replace(value.slice(query + 1));
149
+ }
150
+ /**
151
+ * A value in an MCP server's env or headers block, redacted only when it is a secret: a known
152
+ * format keeps its prefix, type and fingerprint; a credential-named one is a credential; a 40+
153
+ * character token is a potential token, as the backend reads one. Anything else (`LOG_LEVEL=debug`)
154
+ * stays readable, as before scrubbing. A reference to a secret stored elsewhere (`${TOKEN}`,
155
+ * `Bearer ${TOKEN}`) stays readable.
156
+ */
157
+ function redactBlockValue(value, name, pass) {
158
+ if (!isRedactable(value))
103
159
  return value;
104
160
  const formatted = redactFormats(value, pass);
105
161
  if (formatted !== value)
106
162
  return formatted;
107
- return redacted(pass, CREDENTIAL_KEY.test(name) ? "CREDENTIAL_ENV_VAR" : ordinaryType);
163
+ if (isCredentialName(name, value) && isCredentialValue(value))
164
+ return redacted(pass, "CREDENTIAL_ENV_VAR");
165
+ return redactGenericTokens(redactAssignments(value, pass), pass);
108
166
  }
109
- function walkValueBlock(block, ordinaryType, pass, depth) {
167
+ function walkValueBlock(block, pass, depth) {
110
168
  const out = {};
111
169
  for (const [name, v] of Object.entries(block)) {
112
- out[name] = typeof v === "string" ? redactBlockValue(v, name, ordinaryType, pass) : walk(v, pass, name, depth + 1);
170
+ out[name] = typeof v === "string" ? redactBlockValue(v, name, pass) : walk(v, pass, name, depth + 1);
113
171
  }
114
172
  return out;
115
173
  }
174
+ /** A value in a credential container: a credential whatever its shape (a known format keeps its type). */
175
+ function redactContainerValue(value, pass) {
176
+ if (!isRedactable(value))
177
+ return value;
178
+ const formatted = redactFormats(value, pass);
179
+ return formatted !== value ? formatted : redacted(pass, "CREDENTIAL_ENV_VAR");
180
+ }
116
181
  /** `["--api-key", "BSA..."]`: the argument after a credential flag is the credential. */
117
182
  function walkArgs(args, pass, depth) {
118
183
  return args.map((arg, i) => {
119
184
  const flag = typeof args[i - 1] === "string" ? CREDENTIAL_FLAG.exec(args[i - 1]) : null;
120
- if (flag && CREDENTIAL_KEY.test(flag[1]) && typeof arg === "string" && isCredentialValue(arg)) {
185
+ if (flag && typeof arg === "string" && isCredentialName(flag[1], arg) && isCredentialValue(arg)) {
121
186
  const formatted = redactFormats(arg, pass);
122
187
  return formatted !== arg ? formatted : redacted(pass, "CREDENTIAL_ENV_VAR");
123
188
  }
124
189
  return walk(arg, pass, "args", depth + 1);
125
190
  });
126
191
  }
127
- /** One child of an object: an MCP value block and `args` get their structural rule. */
192
+ /**
193
+ * A credential container (`copilotTokens: {"https://github.com:ada": "gho_..."}`): every string
194
+ * value is a credential whatever its key, so a token with no known format is still redacted.
195
+ * Fields ending in `id` stay readable.
196
+ */
197
+ function walkCredentialContainer(container, pass, depth) {
198
+ const out = {};
199
+ for (const [name, v] of Object.entries(container)) {
200
+ const isCredential = typeof v === "string" && !CONTAINER_KEEP.test(name);
201
+ out[name] = isCredential ? redactContainerValue(v, pass) : walk(v, pass, name, depth + 1);
202
+ }
203
+ return out;
204
+ }
205
+ /** One child of an object: MCP value blocks, credential containers and `args` get their structural rule. */
128
206
  function walkChild(key, value, inServer, pass, depth) {
129
- const blockType = inServer ? MCP_VALUE_BLOCKS[key] : undefined;
130
- if (blockType && isPlainObject(value))
131
- return walkValueBlock(value, blockType, pass, depth);
207
+ const isBlock = inServer && MCP_VALUE_BLOCKS.has(key);
208
+ const isData = isPlainObject(value) && !isSchemaNode(value);
209
+ if (isBlock && isData)
210
+ return walkValueBlock(value, pass, depth);
211
+ if (CREDENTIAL_CONTAINER.test(key) && isData)
212
+ return walkCredentialContainer(value, pass, depth);
132
213
  if (key === "args" && Array.isArray(value))
133
214
  return walkArgs(value, pass, depth);
134
215
  return walk(value, pass, key, depth + 1);
135
216
  }
136
217
  function walkObject(obj, pass, depth) {
137
- const inServer = Object.keys(obj).some((k) => MCP_SERVER_KEYS.has(k));
218
+ const inServer = isServerDefinition(obj);
138
219
  const out = {};
139
220
  for (const [k, v] of Object.entries(obj))
140
221
  out[k] = walkChild(k, v, inServer, pass, depth);
141
222
  return out;
142
223
  }
143
224
  function walk(value, pass, key, depth) {
225
+ // The TOO_DEEP placeholder a first pass left at this depth stays as it is.
144
226
  if (depth > MAX_DEPTH)
145
- return redacted(pass, "TOO_DEEP");
227
+ return value === placeholder("TOO_DEEP") ? value : redacted(pass, "TOO_DEEP");
146
228
  if (Array.isArray(value))
147
229
  return value.map((item) => walk(item, pass, key, depth + 1));
148
230
  if (isPlainObject(value))
@@ -152,8 +234,11 @@ function walk(value, pass, key, depth) {
152
234
  /**
153
235
  * A deep copy of `value` with every string scrubbed and every value under a credential-named key
154
236
  * redacted, and how many of each type were redacted. Non-string leaves are returned as they are.
237
+ * When the organization has switched scrubbing off, `value` itself, with no hits.
155
238
  */
156
239
  export function scrub(value, options = {}) {
240
+ if (scrubbingSwitchedOff())
241
+ return { value, hits: {} };
157
242
  const pass = { options, hits: {} };
158
243
  return { value: walk(value, pass, undefined, 0), hits: pass.hits };
159
244
  }
@@ -161,8 +246,13 @@ export function scrub(value, options = {}) {
161
246
  export function scrubValue(value, options = {}) {
162
247
  return scrub(value, options).value;
163
248
  }
164
- /** A copy of `text` with every secret, and with `personalData` emails and usernames, redacted. */
249
+ /**
250
+ * A copy of `text` with every secret redacted;
251
+ * `text` itself when the organization has switched scrubbing off.
252
+ */
165
253
  export function scrubText(text, options = {}) {
254
+ if (scrubbingSwitchedOff())
255
+ return text;
166
256
  return scrubString(text, { options, hits: {} });
167
257
  }
168
258
  /**
@@ -171,6 +261,8 @@ export function scrubText(text, options = {}) {
171
261
  */
172
262
  export function scrubFields(record, fields, options = {}) {
173
263
  const out = { ...record };
264
+ if (scrubbingSwitchedOff())
265
+ return out;
174
266
  for (const field of fields) {
175
267
  if (typeof out[field] === "string")
176
268
  out[field] = scrubText(out[field], options);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Whether the organization has switched scrubbing off (OPT-942).
3
+ *
4
+ * The backend sends `scrub_pii` with the prompt policy on startup and inventory responses, and
5
+ * the senders store it in the org config file beside `collect_prompts`. Only an explicit `false`
6
+ * turns scrubbing off: no file yet, an unreadable one or no field means scrub, so an endpoint
7
+ * that has not heard from its organization yet scrubs.
8
+ *
9
+ * Read on every call rather than once per process, so a change reaches a sender as soon as the
10
+ * file is rewritten. The file is a few hundred bytes.
11
+ */
12
+ export declare function orgConfigPath(): string;
13
+ export declare function scrubbingSwitchedOff(): boolean;
14
+ //# sourceMappingURL=org-setting.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"org-setting.d.ts","sourceRoot":"","sources":["../src/org-setting.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,oBAAoB,IAAI,OAAO,CAQ9C"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Whether the organization has switched scrubbing off (OPT-942).
3
+ *
4
+ * The backend sends `scrub_pii` with the prompt policy on startup and inventory responses, and
5
+ * the senders store it in the org config file beside `collect_prompts`. Only an explicit `false`
6
+ * turns scrubbing off: no file yet, an unreadable one or no field means scrub, so an endpoint
7
+ * that has not heard from its organization yet scrubs.
8
+ *
9
+ * Read on every call rather than once per process, so a change reaches a sender as soon as the
10
+ * file is rewritten. The file is a few hundred bytes.
11
+ */
12
+ import { readFileSync } from "node:fs";
13
+ import { homedir } from "node:os";
14
+ import { join } from "node:path";
15
+ export function orgConfigPath() {
16
+ return join(homedir(), ".optimuslabs", "management", "org", "config.json");
17
+ }
18
+ export function scrubbingSwitchedOff() {
19
+ try {
20
+ const config = JSON.parse(readFileSync(orgConfigPath(), "utf8"));
21
+ return Boolean(config) && typeof config === "object" && config.scrub_pii === false;
22
+ }
23
+ catch {
24
+ // No file yet, or not JSON: scrub.
25
+ return false;
26
+ }
27
+ }
28
+ //# sourceMappingURL=org-setting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"org-setting.js","sourceRoot":"","sources":["../src/org-setting.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC;AAC7E,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,aAAa,EAAE,EAAE,MAAM,CAAC,CAAY,CAAC;QAC5E,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAK,MAAkC,CAAC,SAAS,KAAK,KAAK,CAAC;IAClH,CAAC;IAAC,MAAM,CAAC;QACP,mCAAmC;QACnC,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
package/dist/rules.d.ts CHANGED
@@ -13,20 +13,27 @@
13
13
  export interface SecretFormat {
14
14
  type: string;
15
15
  fingerprint: boolean;
16
+ skipPlaceholders: boolean;
16
17
  /** Global, for `replace`. */
17
18
  pattern: RegExp;
18
19
  }
19
20
  export declare const SECRET_FORMATS: readonly SecretFormat[];
20
21
  export declare const CREDENTIAL_KEY: RegExp;
22
+ export declare const WEAK_CREDENTIAL_KEY: RegExp;
23
+ export declare const NOT_A_SECRET_UNDER_WEAK_KEY: RegExp;
24
+ export declare const CREDENTIAL_CONTAINER: RegExp;
25
+ export declare const CONTAINER_KEEP: RegExp;
21
26
  export declare const CREDENTIAL_ASSIGNMENT: RegExp;
27
+ export declare const CODE_VALUE: RegExp;
22
28
  export declare const ENV_REFERENCE: RegExp;
23
29
  export declare const CONTAINS_REFERENCE: RegExp;
30
+ export declare const PLACEHOLDER_VALUE: RegExp;
24
31
  export declare const CREDENTIAL_FLAG: RegExp;
25
- /** Block key (`env`, `headers`) to the placeholder type for an ordinary value in it. */
26
- export declare const MCP_VALUE_BLOCKS: Readonly<Record<string, string>>;
32
+ /** The blocks of an MCP server definition whose values are checked for secrets (`env`, `headers`). */
33
+ export declare const MCP_VALUE_BLOCKS: ReadonlySet<string>;
34
+ /** The backend's generic token shape; a match of 40 or more characters is a potential token. */
35
+ export declare const GENERIC_TOKEN: RegExp;
27
36
  export declare const MCP_SERVER_KEYS: ReadonlySet<string>;
28
- export declare const EMAIL: RegExp;
29
- export declare const RESERVED_EMAIL_DOMAIN: RegExp;
30
- export declare const HOME_DIRECTORY: RegExp;
37
+ export declare const JSON_SCHEMA_TYPES: ReadonlySet<string>;
31
38
  export declare const MIN_CREDENTIAL_LENGTH: number;
32
39
  //# sourceMappingURL=rules.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AA6BH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;IACrB,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;CACjB;AAWD,eAAO,MAAM,cAAc,EAAE,SAAS,YAAY,EAI/C,CAAC;AACJ,eAAO,MAAM,cAAc,QAAuC,CAAC;AACnE,eAAO,MAAM,qBAAqB,QAA6C,CAAC;AAChF,eAAO,MAAM,aAAa,QAAsC,CAAC;AACjE,eAAO,MAAM,kBAAkB,QAA2C,CAAC;AAC3E,eAAO,MAAM,eAAe,QAAwC,CAAC;AACrE,wFAAwF;AACxF,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAiC,CAAC;AAChG,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,MAAM,CAA+C,CAAC;AAChG,eAAO,MAAM,KAAK,QAA6B,CAAC;AAChD,eAAO,MAAM,qBAAqB,QAA8C,CAAC;AACjF,eAAO,MAAM,cAAc,QAAsC,CAAC;AAClE,eAAO,MAAM,qBAAqB,QAA8B,CAAC"}
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAkCH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;IACrB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;CACjB;AAWD,eAAO,MAAM,cAAc,EAAE,SAAS,YAAY,EAK/C,CAAC;AACJ,eAAO,MAAM,cAAc,QAAuC,CAAC;AACnE,eAAO,MAAM,mBAAmB,QAA4C,CAAC;AAC7E,eAAO,MAAM,2BAA2B,QAA6D,CAAC;AACtG,eAAO,MAAM,oBAAoB,QAA6C,CAAC;AAC/E,eAAO,MAAM,cAAc,QAAsD,CAAC;AAClF,eAAO,MAAM,qBAAqB,QAA6C,CAAC;AAChF,eAAO,MAAM,UAAU,QAAmC,CAAC;AAC3D,eAAO,MAAM,aAAa,QAAsC,CAAC;AACjE,eAAO,MAAM,kBAAkB,QAA2C,CAAC;AAC3E,eAAO,MAAM,iBAAiB,QAA0C,CAAC;AACzE,eAAO,MAAM,eAAe,QAAwC,CAAC;AACrE,sGAAsG;AACtG,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAA0C,CAAC;AAC5F,gGAAgG;AAChG,eAAO,MAAM,aAAa,QAAqC,CAAC;AAChE,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,MAAM,CAA+C,CAAC;AAChG,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAA0C,CAAC;AAC7F,eAAO,MAAM,qBAAqB,QAA8B,CAAC"}
package/dist/rules.js CHANGED
@@ -21,18 +21,25 @@ function compile(spec, global) {
21
21
  export const SECRET_FORMATS = RULES.formats.map((f) => ({
22
22
  type: f.type,
23
23
  fingerprint: f.fingerprint,
24
+ skipPlaceholders: Boolean(f.skip_placeholders),
24
25
  pattern: compile(f, true),
25
26
  }));
26
27
  export const CREDENTIAL_KEY = compile(RULES.credential_key, false);
28
+ export const WEAK_CREDENTIAL_KEY = compile(RULES.weak_credential_key, false);
29
+ export const NOT_A_SECRET_UNDER_WEAK_KEY = new RegExp(RULES.weak_credential_key.not_a_secret_pattern);
30
+ export const CREDENTIAL_CONTAINER = compile(RULES.credential_container, false);
31
+ export const CONTAINER_KEEP = new RegExp(RULES.credential_container.keep_pattern);
27
32
  export const CREDENTIAL_ASSIGNMENT = compile(RULES.credential_assignment, true);
33
+ export const CODE_VALUE = compile(RULES.code_value, false);
28
34
  export const ENV_REFERENCE = compile(RULES.env_reference, false);
29
35
  export const CONTAINS_REFERENCE = compile(RULES.contains_reference, false);
36
+ export const PLACEHOLDER_VALUE = compile(RULES.placeholder_value, false);
30
37
  export const CREDENTIAL_FLAG = compile(RULES.credential_flag, false);
31
- /** Block key (`env`, `headers`) to the placeholder type for an ordinary value in it. */
32
- export const MCP_VALUE_BLOCKS = RULES.mcp_value_blocks.blocks;
38
+ /** The blocks of an MCP server definition whose values are checked for secrets (`env`, `headers`). */
39
+ export const MCP_VALUE_BLOCKS = new Set(RULES.mcp_value_blocks.blocks);
40
+ /** The backend's generic token shape; a match of 40 or more characters is a potential token. */
41
+ export const GENERIC_TOKEN = compile(RULES.generic_token, true);
33
42
  export const MCP_SERVER_KEYS = new Set(RULES.mcp_value_blocks.server_keys);
34
- export const EMAIL = compile(RULES.email, true);
35
- export const RESERVED_EMAIL_DOMAIN = compile(RULES.reserved_email_domain, false);
36
- export const HOME_DIRECTORY = compile(RULES.home_directory, true);
43
+ export const JSON_SCHEMA_TYPES = new Set(RULES.json_schema_types.types);
37
44
  export const MIN_CREDENTIAL_LENGTH = RULES.min_credential_length;
38
45
  //# sourceMappingURL=rules.js.map
package/dist/rules.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"rules.js","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAkC5C,gGAAgG;AAChG,0EAA0E;AAC1E,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,eAAe,CAAc,CAAC;AAE3E,kGAAkG;AAClG,SAAS,OAAO,CAAC,IAAiB,EAAE,MAAe;IACjD,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACxF,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAA4B,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC/E,IAAI,EAAE,CAAC,CAAC,IAAI;IACZ,WAAW,EAAE,CAAC,CAAC,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC;CAC1B,CAAC,CAAC,CAAC;AACJ,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;AACnE,MAAM,CAAC,MAAM,qBAAqB,GAAG,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,IAAI,CAAC,CAAC;AAChF,MAAM,CAAC,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;AACjE,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;AAC3E,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;AACrE,wFAAwF;AACxF,MAAM,CAAC,MAAM,gBAAgB,GAAqC,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC;AAChG,MAAM,CAAC,MAAM,eAAe,GAAwB,IAAI,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;AAChG,MAAM,CAAC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AAChD,MAAM,CAAC,MAAM,qBAAqB,GAAG,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;AACjF,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;AAClE,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC,qBAAqB,CAAC"}
1
+ {"version":3,"file":"rules.js","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAwC5C,gGAAgG;AAChG,0EAA0E;AAC1E,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,eAAe,CAAc,CAAC;AAE3E,kGAAkG;AAClG,SAAS,OAAO,CAAC,IAAiB,EAAE,MAAe;IACjD,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACxF,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAA4B,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC/E,IAAI,EAAE,CAAC,CAAC,IAAI;IACZ,WAAW,EAAE,CAAC,CAAC,WAAW;IAC1B,gBAAgB,EAAE,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC;IAC9C,OAAO,EAAE,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC;CAC1B,CAAC,CAAC,CAAC;AACJ,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;AACnE,MAAM,CAAC,MAAM,mBAAmB,GAAG,OAAO,CAAC,KAAK,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;AAC7E,MAAM,CAAC,MAAM,2BAA2B,GAAG,IAAI,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,oBAAoB,CAAC,CAAC;AACtG,MAAM,CAAC,MAAM,oBAAoB,GAAG,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;AAC/E,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,YAAY,CAAC,CAAC;AAClF,MAAM,CAAC,MAAM,qBAAqB,GAAG,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,IAAI,CAAC,CAAC;AAChF,MAAM,CAAC,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;AAC3D,MAAM,CAAC,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;AACjE,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;AAC3E,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC,KAAK,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC;AACzE,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;AACrE,sGAAsG;AACtG,MAAM,CAAC,MAAM,gBAAgB,GAAwB,IAAI,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAC5F,gGAAgG;AAChG,MAAM,CAAC,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;AAChE,MAAM,CAAC,MAAM,eAAe,GAAwB,IAAI,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;AAChG,MAAM,CAAC,MAAM,iBAAiB,GAAwB,IAAI,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;AAC7F,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC,qBAAqB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optimuslabs/pii-scrub-staging",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Redacts secrets and personal data from what an Optimus endpoint sends, before it leaves the machine.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/rules.json CHANGED
@@ -14,7 +14,15 @@
14
14
  "type": "URL_CREDENTIALS",
15
15
  "pattern": "\\b([a-z][a-z0-9+.-]{0,31}:\\/\\/[^\\s:@/\"'`]{1,256}:)[^\\s@/\"'`]{1,256}(?=@)",
16
16
  "ignore_case": true,
17
- "fingerprint": false
17
+ "fingerprint": false,
18
+ "skip_placeholders": true
19
+ },
20
+ {
21
+ "type": "URL_CREDENTIALS",
22
+ "pattern": "\\b([a-z][a-z0-9+.-]{0,31}:\\/\\/)[^\\s:@/\"'`]{16,255}(?=@)",
23
+ "ignore_case": true,
24
+ "fingerprint": false,
25
+ "skip_placeholders": true
18
26
  },
19
27
  {
20
28
  "type": "ANTHROPIC_KEY",
@@ -86,6 +94,11 @@
86
94
  "pattern": "\\b(pplx-)[A-Za-z0-9]{32,}",
87
95
  "fingerprint": true
88
96
  },
97
+ {
98
+ "type": "BRAVE_KEY",
99
+ "pattern": "\\b(BSA)[A-Za-z0-9_-]{20,}",
100
+ "fingerprint": true
101
+ },
89
102
  {
90
103
  "type": "JWT",
91
104
  "pattern": "\\beyJ[A-Za-z0-9_-]{8,}\\.eyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}",
@@ -95,22 +108,39 @@
95
108
  "type": "BEARER_TOKEN",
96
109
  "pattern": "\\b(Bearer\\s+)[A-Za-z0-9._~+/=-]{16,}",
97
110
  "ignore_case": true,
98
- "fingerprint": false
111
+ "fingerprint": false,
112
+ "skip_placeholders": true
99
113
  },
100
114
  {
101
115
  "type": "BASIC_AUTH",
102
- "pattern": "\\b(Basic\\s+)[A-Za-z0-9+/=]{12,}",
116
+ "pattern": "\\b(Basic\\s+)(?=[A-Za-z0-9+/=]{0,512}(?:[0-9+/=]|[a-z][A-Z]))(?:[A-Za-z0-9+/]{4}){2,128}(?:[A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)(?![A-Za-z0-9+/=])",
103
117
  "fingerprint": false
104
118
  }
105
119
  ],
106
120
  "credential_key": {
107
- "pattern": "(?:[_.-]key|api[_-]?key|apikey|secret|token|password|passwd|credential|private[_-]?key|access[_-]?key|authorization|token[_-]?cache(?:v\\d+)?)$",
121
+ "pattern": "(?:api[_-]?key|apikey|secret|token|password|passwd|credential|private[_-]?key|(?:secret|signing|encryption)[_-]?key|access[_-]?key|authorization|token[_-]?cache(?:v\\d+)?)$",
108
122
  "ignore_case": true
109
123
  },
124
+ "weak_credential_key": {
125
+ "description": "A name ending in `_key` (DEPLOY_SSH_KEY, LICENSE_KEY) is a credential only when its value is not an identifier of something else: an issue key (INCIDENT-31138) or a session key of three or more colon-separated lowercase parts (agent:main:slack). Secret, signing and encryption keys are always credentials (credential_key).",
126
+ "pattern": "[_.-]key$",
127
+ "ignore_case": true,
128
+ "not_a_secret_pattern": "^[a-z0-9_-]+(?::[a-z0-9_+.-]+){2,}$|^[A-Z][A-Z0-9]{1,15}-[0-9]{1,9}$"
129
+ },
130
+ "credential_container": {
131
+ "description": "An object whose every string value is a credential, whatever its own key (Copilot's copilotTokens maps host:user to a token). Fields ending in id stay (Codex tokens.account_id).",
132
+ "pattern": "(?:tokens|secrets|credentials|api[_-]?keys)$",
133
+ "ignore_case": true,
134
+ "keep_pattern": "(?:^|[_-])id$|[a-z]Id$"
135
+ },
110
136
  "credential_assignment": {
111
137
  "pattern": "((?:api[_-]?key|apikey|secret|token|password|passwd|credential|private[_-]?key|access[_-]?key)[\"']?\\s*[:=]\\s*[\"']?)([^\\s\"'`,;&)}\\]]{8,})",
112
138
  "ignore_case": true
113
139
  },
140
+ "code_value": {
141
+ "description": "A value after a credential name in text that is code, not a secret: a call or block opener (`os.environ.get(`, `T.type_alias{`), a template (`{client_private_key}`, `<paste_key_here>`), or a variable named for a credential (`data.credential`, `walletKey`, `this.env.VAPID_PRIVATE_KEY`). A secret that merely contains `(` or `{` is still one.",
142
+ "pattern": "^[A-Za-z_$][\\w$.]*[({]$|^\\{[\\w.]{1,128}$|^<[^<>]{1,64}>$|^(?=[\\w$.]{0,256}(?:\\.|[a-z][A-Z]))(?=[\\w$.]{0,256}(?:[Kk]ey|KEY|[Ss]ecret|SECRET|[Tt]oken|TOKEN|[Pp]assw|PASSW|[Cc]redential|CREDENTIAL|\\.env\\.|\\.environ\\b))[A-Za-z_$][\\w$]*(?:\\.[A-Za-z_$][\\w$]*)*$"
143
+ },
114
144
  "env_reference": {
115
145
  "pattern": "^(?:\\$|\\{\\{|process\\.env\\.)|^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)+$"
116
146
  },
@@ -118,18 +148,22 @@
118
148
  "description": "A reference to a secret stored elsewhere anywhere in a value (`Bearer ${TOKEN}`): the value stays readable.",
119
149
  "pattern": "\\$\\{[^}]{1,128}\\}|\\$env:|process\\.env\\."
120
150
  },
151
+ "placeholder_value": {
152
+ "description": "A documentation placeholder where a secret goes (`<your_key>`, `YOUR_API_TOKEN`, `my_secret`): not a secret, so not redacted and never a finding.",
153
+ "pattern": "^<[^<>]{1,64}>$|(?:^|[_.-])(?:YOUR|your|MY|my)[_-]|_(?:TOKEN|KEY|SECRET|PASSWORD)$"
154
+ },
121
155
  "credential_flag": {
122
156
  "description": "A command-line flag whose next argument is a credential (`--api-key`, `--token`); group 1 is the name, tested against credential_key.",
123
157
  "pattern": "^-{1,2}([A-Za-z0-9_.-]{1,64})$"
124
158
  },
125
159
  "mcp_value_blocks": {
126
- "description": "Blocks inside an MCP server definition whose every value is redacted: block key to the placeholder type for a value that is neither a known format nor under a credential-named key. A server definition is an object with one of server_keys.",
127
- "blocks": {
128
- "env": "ENV_VALUE",
129
- "environment": "ENV_VALUE",
130
- "headers": "HEADER_VALUE",
131
- "http_headers": "HEADER_VALUE"
132
- },
160
+ "description": "Blocks inside an MCP server definition whose values are checked for secrets: a known format, a value under a credential-named key, or a generic token (generic_token) is redacted; any other value stays. A server definition is an object with one of server_keys. A server key counts only when its value is a string or a list, so a JSON Schema `properties` map with a `type` or `url` property is not a server.",
161
+ "blocks": [
162
+ "env",
163
+ "environment",
164
+ "headers",
165
+ "http_headers"
166
+ ],
133
167
  "server_keys": [
134
168
  "command",
135
169
  "args",
@@ -140,15 +174,88 @@
140
174
  "type"
141
175
  ]
142
176
  },
143
- "email": {
144
- "pattern": "\\b[A-Za-z0-9._%+-]{1,64}@([A-Za-z0-9-]{1,63}(?:\\.[A-Za-z0-9-]{1,63})*\\.[A-Za-z]{2,24})\\b"
177
+ "generic_token": {
178
+ "description": "The backend's generic token (HardcodedSecretRule.GENERIC_TOKEN_PATTERN): in an MCP env or headers value, a match of 40 or more characters is redacted as POTENTIAL_TOKEN, which the backend reads as a potential token/secret. In a URL only the query is searched.",
179
+ "pattern": "\\b[a-zA-Z0-9][a-zA-Z0-9_-]{31,}\\b"
145
180
  },
146
- "reserved_email_domain": {
147
- "pattern": "(?:^|\\.)(?:example\\.(?:com|org|net)|example|test|invalid|localhost)$",
148
- "ignore_case": true
149
- },
150
- "home_directory": {
151
- "pattern": "(\\/(?:Users|home)\\/)([A-Za-z0-9._-]{1,64})"
181
+ "json_schema_types": {
182
+ "description": "An object whose `type` is one of these is a JSON Schema node (an MCP tool's input schema), not data: never a credential container or an MCP value block.",
183
+ "types": [
184
+ "object",
185
+ "array",
186
+ "string",
187
+ "number",
188
+ "integer",
189
+ "boolean",
190
+ "null"
191
+ ]
152
192
  },
153
- "min_credential_length": 8
193
+ "min_credential_length": 8,
194
+ "admin_summary": {
195
+ "description": "What admins are told is redacted (org settings, Data redaction; OPT-953): one item per kind, naming the rule groups it describes; \"list\": \"formats\" adds the format types as a list. \"items\" are the names or kinds the other items remove. The backend sends these items; a backend test fails when a rule group that redacts has no item here.",
196
+ "lines": [
197
+ {
198
+ "title": "API keys and tokens",
199
+ "rules": [
200
+ "formats"
201
+ ],
202
+ "list": "formats",
203
+ "text": "Known vendor formats, replaced by [OL_REDACTED:<format>]. The vendor's prefix stays."
204
+ },
205
+ {
206
+ "title": "Credentials by name",
207
+ "rules": [
208
+ "credential_key",
209
+ "weak_credential_key",
210
+ "credential_assignment",
211
+ "credential_flag"
212
+ ],
213
+ "text": "Values named like a credential (api_key, token, secret, password), in any format.",
214
+ "items": [
215
+ "api_key",
216
+ "apikey",
217
+ "secret",
218
+ "token",
219
+ "password",
220
+ "passwd",
221
+ "credential",
222
+ "private_key",
223
+ "secret_key",
224
+ "signing_key",
225
+ "encryption_key",
226
+ "access_key",
227
+ "authorization",
228
+ "token_cache",
229
+ "*_key"
230
+ ]
231
+ },
232
+ {
233
+ "title": "Token maps",
234
+ "rules": [
235
+ "credential_container"
236
+ ],
237
+ "text": "Every value in a map of tokens, such as Copilot's copilotTokens.",
238
+ "items": [
239
+ "*tokens",
240
+ "*secrets",
241
+ "*credentials",
242
+ "*api_keys"
243
+ ]
244
+ },
245
+ {
246
+ "title": "MCP server env and headers",
247
+ "rules": [
248
+ "mcp_value_blocks",
249
+ "generic_token"
250
+ ],
251
+ "text": "Secrets in an MCP server's env and headers: known formats, credential names and long tokens. Other values stay.",
252
+ "items": [
253
+ "env",
254
+ "environment",
255
+ "headers",
256
+ "http_headers"
257
+ ]
258
+ }
259
+ ]
260
+ }
154
261
  }