@claudexor/util 1.0.1 → 2.1.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.
- package/dist/index.d.ts +31 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +136 -41
- package/dist/index.js.map +1 -1
- package/dist/secret-names.d.ts +25 -0
- package/dist/secret-names.d.ts.map +1 -0
- package/dist/secret-names.js +51 -0
- package/dist/secret-names.js.map +1 -0
- package/dist/sensitive-resource.d.ts +55 -0
- package/dist/sensitive-resource.d.ts.map +1 -0
- package/dist/sensitive-resource.js +221 -0
- package/dist/sensitive-resource.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { CLAUDEXOR_VERSION } from "./version.js";
|
|
2
|
+
export * from "./secret-names.js";
|
|
3
|
+
export * from "./sensitive-resource.js";
|
|
2
4
|
/** Generate a short unique id, optionally prefixed (e.g. "run-3f2a...."). */
|
|
3
5
|
export declare function newId(prefix?: string): string;
|
|
4
6
|
/** Current time as an ISO-8601 string. */
|
|
@@ -10,6 +12,13 @@ export declare function hashJson(value: unknown): string;
|
|
|
10
12
|
/** JSON.stringify with sorted object keys for stable hashing. */
|
|
11
13
|
export declare function stableStringify(value: unknown): string;
|
|
12
14
|
export declare function ensureDir(path: string): void;
|
|
15
|
+
/**
|
|
16
|
+
* Establish a private daemon-owned directory without following any symlink in
|
|
17
|
+
* the supplied spelling. The direct parent must already exist canonically;
|
|
18
|
+
* callers create nested owned roots one level at a time. No chmod occurs until
|
|
19
|
+
* pathname identity has been proven.
|
|
20
|
+
*/
|
|
21
|
+
export declare function ensureCanonicalPrivateDirectory(path: string): string;
|
|
13
22
|
export declare function writeText(path: string, text: string): void;
|
|
14
23
|
export declare function writeJson(path: string, value: unknown): void;
|
|
15
24
|
export declare function appendLine(path: string, line: string): void;
|
|
@@ -28,6 +37,27 @@ export declare function listDir(path: string): string[];
|
|
|
28
37
|
*/
|
|
29
38
|
export declare function userHomeDir(): string;
|
|
30
39
|
export declare function userConfigDir(): string;
|
|
40
|
+
/**
|
|
41
|
+
* The ONE Claudexor-owned confinement root (round-22 DRY): under an explicit
|
|
42
|
+
* CLAUDEXOR_CONFIG_DIR override, that override IS the complete relocatable
|
|
43
|
+
* root; without it the owned tree is ~/.claudexor. Credential-profile
|
|
44
|
+
* locators and the isolation-locator confinement both derive from here —
|
|
45
|
+
* never re-derive this ternary inline.
|
|
46
|
+
*/
|
|
47
|
+
export declare function claudexorOwnedRoot(): string;
|
|
48
|
+
/**
|
|
49
|
+
* Stable external runtime namespace for a project.
|
|
50
|
+
*
|
|
51
|
+
* A repository's `.claudexor/` directory is user-owned, versionable project
|
|
52
|
+
* configuration. Runtime state (runs, worktrees, scoped homes, review packets)
|
|
53
|
+
* therefore must never be placed below the repository or require Claudexor to
|
|
54
|
+
* edit either of the user's `.gitignore` files. Existing roots are resolved
|
|
55
|
+
* through symlinks before hashing so two spellings of the same project share a
|
|
56
|
+
* single namespace; a not-yet-existing root still gets a deterministic absolute
|
|
57
|
+
* identity and is re-keyed only after it exists and is registered.
|
|
58
|
+
*/
|
|
59
|
+
export declare function canonicalProjectRoot(repoRoot: string): string;
|
|
60
|
+
export declare function projectRuntimeDir(repoRoot: string): string;
|
|
31
61
|
export declare function noProjectRepoRoot(): string;
|
|
32
62
|
/**
|
|
33
63
|
* Best-effort redaction of obvious secret tokens from text destined for logs or
|
|
@@ -36,7 +66,7 @@ export declare function noProjectRepoRoot(): string;
|
|
|
36
66
|
*/
|
|
37
67
|
export declare function redactSecrets(text: string): string;
|
|
38
68
|
export declare function containsSecretLikeToken(text: string): boolean;
|
|
39
|
-
export declare function assertNoInlineSecretValues(value: unknown, path?: string, context?: string): void;
|
|
69
|
+
export declare function assertNoInlineSecretValues(value: unknown, path?: string, context?: string, valuesOnly?: boolean): void;
|
|
40
70
|
/** The machine-readable `code` a typed error carries (e.g. inline_secret_rejected), if any. */
|
|
41
71
|
export declare function errorCode(err: unknown): string | undefined;
|
|
42
72
|
/**
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AAqBxC,6EAA6E;AAC7E,wBAAgB,KAAK,CAAC,MAAM,SAAK,GAAG,MAAM,CAGzC;AAED,0CAA0C;AAC1C,wBAAgB,MAAM,IAAI,MAAM,CAE/B;AAED,sDAAsD;AACtD,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,6EAA6E;AAC7E,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAE/C;AAED,iEAAiE;AACjE,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEtD;AAcD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAO5C;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA+CpE;AAWD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAG1D;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAE5D;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAG3D;AAED;;iDAEiD;AACjD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMxD;AAED,oFAAoF;AACpF,wBAAgB,YAAY,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAQhE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAM9C;AAQD;;;;GAIG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAWpC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAatC;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAI3C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAO7D;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG1D;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE7D;AAQD,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,EACd,IAAI,SAAM,EACV,OAAO,SAAe,EACtB,UAAU,UAAQ,GACjB,IAAI,CA8DN;AAED,+FAA+F;AAC/F,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAU1D;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI,CAO9E"}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
export { CLAUDEXOR_VERSION } from "./version.js";
|
|
2
|
+
export * from "./secret-names.js";
|
|
3
|
+
export * from "./sensitive-resource.js";
|
|
4
|
+
import { sensitiveResourcePolicy } from "./sensitive-resource.js";
|
|
2
5
|
import { createHash, randomUUID } from "node:crypto";
|
|
3
|
-
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, } from "node:fs";
|
|
6
|
+
import { closeSync, constants, existsSync, fchmodSync, fstatSync, fsyncSync, lstatSync, mkdirSync, openSync, readdirSync, readFileSync, realpathSync, writeFileSync, } from "node:fs";
|
|
4
7
|
import { homedir } from "node:os";
|
|
5
|
-
import { dirname, isAbsolute, join } from "node:path";
|
|
8
|
+
import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
6
9
|
/** Generate a short unique id, optionally prefixed (e.g. "run-3f2a...."). */
|
|
7
10
|
export function newId(prefix = "") {
|
|
8
11
|
const id = randomUUID().replace(/-/g, "").slice(0, 12);
|
|
@@ -44,6 +47,67 @@ export function ensureDir(path) {
|
|
|
44
47
|
// (secrets, daemon token) assert their own permissions at their writers.
|
|
45
48
|
mkdirSync(path, { recursive: true, mode: 0o700 });
|
|
46
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Establish a private daemon-owned directory without following any symlink in
|
|
52
|
+
* the supplied spelling. The direct parent must already exist canonically;
|
|
53
|
+
* callers create nested owned roots one level at a time. No chmod occurs until
|
|
54
|
+
* pathname identity has been proven.
|
|
55
|
+
*/
|
|
56
|
+
export function ensureCanonicalPrivateDirectory(path) {
|
|
57
|
+
const absolute = resolve(path);
|
|
58
|
+
if (!existsSync(absolute)) {
|
|
59
|
+
const parent = dirname(absolute);
|
|
60
|
+
const parentStat = lstatSync(parent);
|
|
61
|
+
if (parentStat.isSymbolicLink() ||
|
|
62
|
+
!parentStat.isDirectory() ||
|
|
63
|
+
realpathSync.native(parent) !== parent) {
|
|
64
|
+
throw new Error(`owned directory parent is not canonical: ${parent}`);
|
|
65
|
+
}
|
|
66
|
+
mkdirSync(absolute, { recursive: false, mode: 0o700 });
|
|
67
|
+
fsyncCanonicalDirectory(parent);
|
|
68
|
+
}
|
|
69
|
+
const preliminary = lstatSync(absolute);
|
|
70
|
+
if (preliminary.isSymbolicLink() || !preliminary.isDirectory()) {
|
|
71
|
+
throw new Error(`owned directory path is not canonical: ${absolute}`);
|
|
72
|
+
}
|
|
73
|
+
let fd;
|
|
74
|
+
try {
|
|
75
|
+
fd = openSync(absolute, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
throw new Error(`owned directory path is not canonical: ${absolute}`);
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
const opened = fstatSync(fd);
|
|
82
|
+
const named = lstatSync(absolute);
|
|
83
|
+
if (!opened.isDirectory() ||
|
|
84
|
+
named.isSymbolicLink() ||
|
|
85
|
+
!named.isDirectory() ||
|
|
86
|
+
opened.dev !== named.dev ||
|
|
87
|
+
opened.ino !== named.ino ||
|
|
88
|
+
realpathSync.native(absolute) !== absolute ||
|
|
89
|
+
(typeof process.getuid === "function" && opened.uid !== process.getuid())) {
|
|
90
|
+
throw new Error(`owned directory path is not canonical: ${absolute}`);
|
|
91
|
+
}
|
|
92
|
+
// Mutate permissions only through the descriptor whose inode and pathname
|
|
93
|
+
// identity were proven above; never follow a replacement path with chmod.
|
|
94
|
+
fchmodSync(fd, 0o700);
|
|
95
|
+
fsyncSync(fd);
|
|
96
|
+
}
|
|
97
|
+
finally {
|
|
98
|
+
closeSync(fd);
|
|
99
|
+
}
|
|
100
|
+
return absolute;
|
|
101
|
+
}
|
|
102
|
+
function fsyncCanonicalDirectory(path) {
|
|
103
|
+
const fd = openSync(path, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
|
|
104
|
+
try {
|
|
105
|
+
fsyncSync(fd);
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
closeSync(fd);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
47
111
|
export function writeText(path, text) {
|
|
48
112
|
ensureDir(dirname(path));
|
|
49
113
|
writeFileSync(path, text, { encoding: "utf8", mode: 0o600 });
|
|
@@ -117,54 +181,69 @@ export function userConfigDir() {
|
|
|
117
181
|
throw new Error("CLAUDEXOR_CONFIG_DIR must be a safe absolute path");
|
|
118
182
|
return safe;
|
|
119
183
|
}
|
|
120
|
-
|
|
184
|
+
// v2 is an intentionally empty, non-migrating namespace. Keeping the
|
|
185
|
+
// version boundary in the default root prevents the daemon from even
|
|
186
|
+
// probing v1 config, trust, secret, token, or journal bytes. An explicit
|
|
187
|
+
// CLAUDEXOR_CONFIG_DIR remains the hermetic test/operator override and is
|
|
188
|
+
// already treated as the complete v2 root.
|
|
189
|
+
return join(userHomeDir(), ".claudexor", "v2");
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* The ONE Claudexor-owned confinement root (round-22 DRY): under an explicit
|
|
193
|
+
* CLAUDEXOR_CONFIG_DIR override, that override IS the complete relocatable
|
|
194
|
+
* root; without it the owned tree is ~/.claudexor. Credential-profile
|
|
195
|
+
* locators and the isolation-locator confinement both derive from here —
|
|
196
|
+
* never re-derive this ternary inline.
|
|
197
|
+
*/
|
|
198
|
+
export function claudexorOwnedRoot() {
|
|
199
|
+
return process.env.CLAUDEXOR_CONFIG_DIR?.trim()
|
|
200
|
+
? userConfigDir()
|
|
201
|
+
: join(userHomeDir(), ".claudexor");
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Stable external runtime namespace for a project.
|
|
205
|
+
*
|
|
206
|
+
* A repository's `.claudexor/` directory is user-owned, versionable project
|
|
207
|
+
* configuration. Runtime state (runs, worktrees, scoped homes, review packets)
|
|
208
|
+
* therefore must never be placed below the repository or require Claudexor to
|
|
209
|
+
* edit either of the user's `.gitignore` files. Existing roots are resolved
|
|
210
|
+
* through symlinks before hashing so two spellings of the same project share a
|
|
211
|
+
* single namespace; a not-yet-existing root still gets a deterministic absolute
|
|
212
|
+
* identity and is re-keyed only after it exists and is registered.
|
|
213
|
+
*/
|
|
214
|
+
export function canonicalProjectRoot(repoRoot) {
|
|
215
|
+
const absolute = resolve(repoRoot);
|
|
216
|
+
try {
|
|
217
|
+
return realpathSync.native(absolute);
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
return absolute;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
export function projectRuntimeDir(repoRoot) {
|
|
224
|
+
const digest = sha256(canonicalProjectRoot(repoRoot)).slice("sha256:".length);
|
|
225
|
+
return join(userConfigDir(), "projects", digest);
|
|
121
226
|
}
|
|
122
227
|
export function noProjectRepoRoot() {
|
|
123
228
|
return join(userHomeDir(), ".cache", "claudexor", "no-project");
|
|
124
229
|
}
|
|
125
|
-
const SECRET_PATTERNS = [
|
|
126
|
-
/\bgithub_pat_[A-Za-z0-9_]{20,}\b/g,
|
|
127
|
-
/\bghp_[A-Za-z0-9]{20,}\b/g,
|
|
128
|
-
/\bgho_[A-Za-z0-9]{20,}\b/g,
|
|
129
|
-
/\bghs_[A-Za-z0-9]{20,}\b/g,
|
|
130
|
-
/\bghu_[A-Za-z0-9]{20,}\b/g,
|
|
131
|
-
/\bglpat-[A-Za-z0-9_-]{16,}\b/g,
|
|
132
|
-
/\bsk-ant-[A-Za-z0-9_-]{20,}\b/g,
|
|
133
|
-
/\bsk-or-v1-[A-Za-z0-9]{20,}\b/g,
|
|
134
|
-
/\bsk-[A-Za-z0-9_-]{20,}\b/g,
|
|
135
|
-
/\bAIza[A-Za-z0-9_-]{30,}\b/g,
|
|
136
|
-
/\bxai-[A-Za-z0-9_-]{20,}\b/g,
|
|
137
|
-
/\bAKIA[0-9A-Z]{16}\b/g,
|
|
138
|
-
// Slack tokens incl. xoxe (refresh) and xoxc (session) classes.
|
|
139
|
-
/\bxox[abceprs]-[A-Za-z0-9-]{10,}\b/g,
|
|
140
|
-
// Cursor API keys (key_<hex>); OpenRouter keys (sk-or-v1-... handled above).
|
|
141
|
-
/\bkey_[A-Za-z0-9]{20,}\b/g,
|
|
142
|
-
// Google OAuth access tokens.
|
|
143
|
-
/\bya29\.[A-Za-z0-9._-]{20,}\b/g,
|
|
144
|
-
// npm granular access tokens.
|
|
145
|
-
/\bnpm_[A-Za-z0-9]{20,}\b/g,
|
|
146
|
-
// PEM private key blocks (RSA/EC/OPENSSH/PKCS8 headers all match).
|
|
147
|
-
/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g,
|
|
148
|
-
// Bearer tokens (length-gated to avoid redacting prose like "Bearer of news").
|
|
149
|
-
/\bBearer\s+[A-Za-z0-9._~+/-]{20,}=*/gi,
|
|
150
|
-
// JWTs (header.payload.signature) — anthropic/cursor/openai OAuth tokens.
|
|
151
|
-
/\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{6,}\b/g,
|
|
152
|
-
];
|
|
153
230
|
/**
|
|
154
231
|
* Best-effort redaction of obvious secret tokens from text destined for logs or
|
|
155
232
|
* artifacts. This is defense-in-depth, never the primary control: secrets must
|
|
156
233
|
* not reach this layer in the first place.
|
|
157
234
|
*/
|
|
158
235
|
export function redactSecrets(text) {
|
|
159
|
-
|
|
160
|
-
for (const pattern of SECRET_PATTERNS)
|
|
161
|
-
out = out.replace(pattern, "[redacted]");
|
|
162
|
-
return out;
|
|
236
|
+
return sensitiveResourcePolicy.redact(text);
|
|
163
237
|
}
|
|
164
238
|
export function containsSecretLikeToken(text) {
|
|
165
|
-
return
|
|
239
|
+
return sensitiveResourcePolicy.containsSensitiveContent(text);
|
|
166
240
|
}
|
|
167
|
-
|
|
241
|
+
/** Keys whose subtree is a caller-authored JSON SCHEMA: its object keys are
|
|
242
|
+
* field NAMES (a `token` or `password` property is legitimate), so the
|
|
243
|
+
* key-based secret check must not fire there — but string VALUES inside it
|
|
244
|
+
* (const/default/enum literals) are still scanned for real secrets. */
|
|
245
|
+
const SCHEMA_VALUE_SUBTREE_KEYS = new Set(["outputSchema", "output_schema"]);
|
|
246
|
+
export function assertNoInlineSecretValues(value, path = "$", context = "run params", valuesOnly = false) {
|
|
168
247
|
if (typeof value === "string") {
|
|
169
248
|
if (containsSecretLikeToken(value)) {
|
|
170
249
|
// Prompts get a tailored remediation: they are DURABLE run artifacts
|
|
@@ -185,19 +264,35 @@ export function assertNoInlineSecretValues(value, path = "$", context = "run par
|
|
|
185
264
|
if (!value || typeof value !== "object")
|
|
186
265
|
return;
|
|
187
266
|
if (Array.isArray(value)) {
|
|
188
|
-
value.forEach((v, i) => assertNoInlineSecretValues(v, `${path}[${i}]`, context));
|
|
267
|
+
value.forEach((v, i) => assertNoInlineSecretValues(v, `${path}[${i}]`, context, valuesOnly));
|
|
189
268
|
return;
|
|
190
269
|
}
|
|
191
270
|
for (const [key, child] of Object.entries(value)) {
|
|
192
|
-
|
|
271
|
+
// A real secret embedded in a KEY (e.g. a schema property literally named
|
|
272
|
+
// with a live token) is rejected in EVERY mode — valuesOnly only relaxes
|
|
273
|
+
// the NAME heuristic (a legitimate `token`/`password` field name), never
|
|
274
|
+
// the actual-secret detector. Never echo the raw key in the message.
|
|
275
|
+
if (containsSecretLikeToken(key)) {
|
|
276
|
+
throw Object.assign(new Error(`secret-like value is not accepted in ${context} (${path}: object key); store values via secrets and pass refs/profiles`), { status: 400, code: "inline_secret_rejected" });
|
|
277
|
+
}
|
|
278
|
+
// Inside a JSON Schema subtree, keys are field names — skip the name-word
|
|
279
|
+
// heuristic (a `token`/`password`/`env` FIELD is legitimate), but string
|
|
280
|
+
// VALUES are still scanned below.
|
|
281
|
+
if (!valuesOnly &&
|
|
282
|
+
(key === "env" ||
|
|
283
|
+
key === "secrets" ||
|
|
284
|
+
/(^|[_-])(secret|token|password|api[_-]?key)($|[_-])/i.test(key))) {
|
|
193
285
|
throw Object.assign(new Error(`inline secrets/env are not accepted in ${context} (${path}.${key}); store values via secrets and pass refs/profiles`), { status: 400, code: "inline_secret_rejected" });
|
|
194
286
|
}
|
|
195
|
-
assertNoInlineSecretValues(child, `${path}.${key}`, context);
|
|
287
|
+
assertNoInlineSecretValues(child, `${path}.${key}`, context, valuesOnly || SCHEMA_VALUE_SUBTREE_KEYS.has(key));
|
|
196
288
|
}
|
|
197
289
|
}
|
|
198
290
|
/** The machine-readable `code` a typed error carries (e.g. inline_secret_rejected), if any. */
|
|
199
291
|
export function errorCode(err) {
|
|
200
|
-
if (err &&
|
|
292
|
+
if (err &&
|
|
293
|
+
typeof err === "object" &&
|
|
294
|
+
"code" in err &&
|
|
295
|
+
typeof err.code === "string") {
|
|
201
296
|
return err.code;
|
|
202
297
|
}
|
|
203
298
|
return undefined;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EACL,UAAU,EACV,SAAS,EACT,WAAW,EACX,YAAY,EACZ,aAAa,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single owner of the managed secret NAME grammar (names are secret REFS,
|
|
3
|
+
* never values). It lives in the dependency-free util package so the schema
|
|
4
|
+
* (CredentialProfile.secret_ref), the secret store, the CLI/HTTP surfaces,
|
|
5
|
+
* and every harness adapter validate against exactly one grammar; the secrets
|
|
6
|
+
* package re-exports it for its historical importers.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* The single allowlist of managed secret names (previously duplicated in
|
|
10
|
+
* the CLI and the control API, and BOTH were missing `claude_oauth` — the
|
|
11
|
+
* claude adapter reads it, so it must be settable). Adding a name here makes
|
|
12
|
+
* it settable via CLI and HTTP alike.
|
|
13
|
+
*/
|
|
14
|
+
export declare const MANAGED_SECRET_NAMES: readonly ["openai", "anthropic", "claude_oauth", "openrouter", "cursor", "opencode", "raw"];
|
|
15
|
+
export declare function isManagedSecretName(name: string): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* The managed base of a NAMESPACED profile secret_ref, or null when the ref
|
|
18
|
+
* is malformed OR bare (release wave round-15 #5): a profile's ref must carry
|
|
19
|
+
* its own `<base>:<profile>` namespace — a bare engine-default slot (e.g.
|
|
20
|
+
* "anthropic") would silently alias the default credential, and profiles are
|
|
21
|
+
* ADDITIVE identities. Adapters compare the returned base against their own
|
|
22
|
+
* provider slot so a key stored for one provider is never sent to another.
|
|
23
|
+
*/
|
|
24
|
+
export declare function namespacedSecretRefBase(ref: string | null | undefined): string | null;
|
|
25
|
+
//# sourceMappingURL=secret-names.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret-names.d.ts","sourceRoot":"","sources":["../src/secret-names.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,6FAQvB,CAAC;AAUX,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAKzD;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAIrF"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single owner of the managed secret NAME grammar (names are secret REFS,
|
|
3
|
+
* never values). It lives in the dependency-free util package so the schema
|
|
4
|
+
* (CredentialProfile.secret_ref), the secret store, the CLI/HTTP surfaces,
|
|
5
|
+
* and every harness adapter validate against exactly one grammar; the secrets
|
|
6
|
+
* package re-exports it for its historical importers.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* The single allowlist of managed secret names (previously duplicated in
|
|
10
|
+
* the CLI and the control API, and BOTH were missing `claude_oauth` — the
|
|
11
|
+
* claude adapter reads it, so it must be settable). Adding a name here makes
|
|
12
|
+
* it settable via CLI and HTTP alike.
|
|
13
|
+
*/
|
|
14
|
+
export const MANAGED_SECRET_NAMES = [
|
|
15
|
+
"openai",
|
|
16
|
+
"anthropic",
|
|
17
|
+
"claude_oauth",
|
|
18
|
+
"openrouter",
|
|
19
|
+
"cursor",
|
|
20
|
+
"opencode",
|
|
21
|
+
"raw",
|
|
22
|
+
];
|
|
23
|
+
/**
|
|
24
|
+
* Managed names accept an optional per-profile namespace suffix (INV-135):
|
|
25
|
+
* `<base>` (the engine-default slot) or `<base>:<profile>` where base stays in
|
|
26
|
+
* the allowlist and profile is a bounded slug. One grammar for CLI, HTTP, and
|
|
27
|
+
* adapters — a profile's secret_ref is exactly such a name.
|
|
28
|
+
*/
|
|
29
|
+
const PROFILE_SUFFIX = /^[a-z0-9][a-z0-9_-]{0,63}$/;
|
|
30
|
+
export function isManagedSecretName(name) {
|
|
31
|
+
const sep = name.indexOf(":");
|
|
32
|
+
const base = sep === -1 ? name : name.slice(0, sep);
|
|
33
|
+
if (!MANAGED_SECRET_NAMES.includes(base))
|
|
34
|
+
return false;
|
|
35
|
+
return sep === -1 || PROFILE_SUFFIX.test(name.slice(sep + 1));
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The managed base of a NAMESPACED profile secret_ref, or null when the ref
|
|
39
|
+
* is malformed OR bare (release wave round-15 #5): a profile's ref must carry
|
|
40
|
+
* its own `<base>:<profile>` namespace — a bare engine-default slot (e.g.
|
|
41
|
+
* "anthropic") would silently alias the default credential, and profiles are
|
|
42
|
+
* ADDITIVE identities. Adapters compare the returned base against their own
|
|
43
|
+
* provider slot so a key stored for one provider is never sent to another.
|
|
44
|
+
*/
|
|
45
|
+
export function namespacedSecretRefBase(ref) {
|
|
46
|
+
if (!ref || !isManagedSecretName(ref))
|
|
47
|
+
return null;
|
|
48
|
+
const sep = ref.indexOf(":");
|
|
49
|
+
return sep === -1 ? null : ref.slice(0, sep);
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=secret-names.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret-names.js","sourceRoot":"","sources":["../src/secret-names.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,QAAQ;IACR,WAAW;IACX,cAAc;IACd,YAAY;IACZ,QAAQ;IACR,UAAU;IACV,KAAK;CACG,CAAC;AAEX;;;;;GAKG;AACH,MAAM,cAAc,GAAG,4BAA4B,CAAC;AAEpD,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACpD,IAAI,CAAE,oBAA0C,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9E,OAAO,GAAG,KAAK,CAAC,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CAAC,GAA8B;IACpE,IAAI,CAAC,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACnD,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC7B,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export type SensitiveResourcePathClass = "credential_file" | "credential_store" | "environment_file" | "private_key" | "secret_container";
|
|
2
|
+
export interface SensitiveResourcePathDecision {
|
|
3
|
+
readonly sensitive: boolean;
|
|
4
|
+
readonly class: SensitiveResourcePathClass | null;
|
|
5
|
+
readonly matchedPart: string | null;
|
|
6
|
+
readonly reason: string | null;
|
|
7
|
+
}
|
|
8
|
+
export type SensitiveContentHandling = "redact" | "reject";
|
|
9
|
+
export type SensitiveContentSignature = "anthropic_api_key" | "aws_access_key" | "bearer_token" | "cursor_api_key" | "github_token" | "gitlab_token" | "google_api_key" | "google_oauth_token" | "jwt" | "npm_token" | "openai_compatible_api_key" | "private_key_block" | "slack_token" | "xai_api_key";
|
|
10
|
+
export interface SensitiveContentDecision {
|
|
11
|
+
readonly action: "allow" | "redact" | "reject";
|
|
12
|
+
readonly containsSensitiveContent: boolean;
|
|
13
|
+
readonly signatures: readonly SensitiveContentSignature[];
|
|
14
|
+
readonly text: string;
|
|
15
|
+
}
|
|
16
|
+
export type SymlinkTargetKind = "directory" | "file" | "other" | "unknown";
|
|
17
|
+
export type SensitiveSymlinkDenyReason = "absolute_target" | "excluded_target" | "invalid_source" | "relocation_escape" | "sensitive_source" | "sensitive_target" | "target_kind" | "target_outside_root" | "unresolved_target";
|
|
18
|
+
export interface SensitiveSymlinkInput {
|
|
19
|
+
/** Logical root containing the symlink. */
|
|
20
|
+
sourceRoot: string;
|
|
21
|
+
/** Canonical identity of sourceRoot (normally realpath(sourceRoot)). */
|
|
22
|
+
canonicalSourceRoot: string;
|
|
23
|
+
sourcePath: string;
|
|
24
|
+
linkTarget: string;
|
|
25
|
+
resolvedTargetPath: string | null;
|
|
26
|
+
targetKind: SymlinkTargetKind;
|
|
27
|
+
allowedTargetKinds: readonly SymlinkTargetKind[];
|
|
28
|
+
/** Roots that must not be reachable from the copied/mapped tree. */
|
|
29
|
+
excludedRoots?: readonly string[];
|
|
30
|
+
/** Destination root used to prove that a relative link remains contained after relocation. */
|
|
31
|
+
relocationRoot?: string;
|
|
32
|
+
}
|
|
33
|
+
export interface SensitiveSymlinkDecision {
|
|
34
|
+
readonly allowed: boolean;
|
|
35
|
+
readonly reason: SensitiveSymlinkDenyReason | null;
|
|
36
|
+
readonly detail: string | null;
|
|
37
|
+
readonly pathDecision: SensitiveResourcePathDecision | null;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Single owner for sensitive path, symlink-target, and content decisions.
|
|
41
|
+
*
|
|
42
|
+
* The API is deliberately surface-neutral: context/review consume it now;
|
|
43
|
+
* upload and release scanners can consume the same typed decisions later
|
|
44
|
+
* without growing another classifier or weakening this policy.
|
|
45
|
+
*/
|
|
46
|
+
export declare class SensitiveResourcePolicy {
|
|
47
|
+
readonly redactionMarker = "[redacted]";
|
|
48
|
+
classifyPath(path: string): SensitiveResourcePathDecision;
|
|
49
|
+
inspectContent(text: string, handling?: SensitiveContentHandling): SensitiveContentDecision;
|
|
50
|
+
redact(text: string): string;
|
|
51
|
+
containsSensitiveContent(text: string): boolean;
|
|
52
|
+
assessSymlink(input: SensitiveSymlinkInput): SensitiveSymlinkDecision;
|
|
53
|
+
}
|
|
54
|
+
export declare const sensitiveResourcePolicy: Readonly<SensitiveResourcePolicy>;
|
|
55
|
+
//# sourceMappingURL=sensitive-resource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sensitive-resource.d.ts","sourceRoot":"","sources":["../src/sensitive-resource.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,0BAA0B,GACpC,iBAAiB,GAAG,kBAAkB,GAAG,kBAAkB,GAAG,aAAa,GAAG,kBAAkB,CAAC;AAEnG,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,0BAA0B,GAAG,IAAI,CAAC;IAClD,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,MAAM,wBAAwB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE3D,MAAM,MAAM,yBAAyB,GACjC,mBAAmB,GACnB,gBAAgB,GAChB,cAAc,GACd,gBAAgB,GAChB,cAAc,GACd,cAAc,GACd,gBAAgB,GAChB,oBAAoB,GACpB,KAAK,GACL,WAAW,GACX,2BAA2B,GAC3B,mBAAmB,GACnB,aAAa,GACb,aAAa,CAAC;AAElB,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC/C,QAAQ,CAAC,wBAAwB,EAAE,OAAO,CAAC;IAC3C,QAAQ,CAAC,UAAU,EAAE,SAAS,yBAAyB,EAAE,CAAC;IAC1D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;AAE3E,MAAM,MAAM,0BAA0B,GAClC,iBAAiB,GACjB,iBAAiB,GACjB,gBAAgB,GAChB,mBAAmB,GACnB,kBAAkB,GAClB,kBAAkB,GAClB,aAAa,GACb,qBAAqB,GACrB,mBAAmB,CAAC;AAExB,MAAM,WAAW,qBAAqB;IACpC,2CAA2C;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,mBAAmB,EAAE,MAAM,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,UAAU,EAAE,iBAAiB,CAAC;IAC9B,kBAAkB,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACjD,oEAAoE;IACpE,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,8FAA8F;IAC9F,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,0BAA0B,GAAG,IAAI,CAAC;IACnD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,6BAA6B,GAAG,IAAI,CAAC;CAC7D;AAoED;;;;;;GAMG;AACH,qBAAa,uBAAuB;IAClC,QAAQ,CAAC,eAAe,gBAAgB;IAExC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,6BAA6B;IA2DzD,cAAc,CACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,wBAAmC,GAC5C,wBAAwB;IAqB3B,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAI5B,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI/C,aAAa,CAAC,KAAK,EAAE,qBAAqB,GAAG,wBAAwB;CA2CtE;AAED,eAAO,MAAM,uBAAuB,mCAA+C,CAAC"}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { dirname, extname, isAbsolute, join, normalize, relative, resolve } from "node:path";
|
|
2
|
+
const SAFE_ENV_TEMPLATE_BASENAMES = new Set([".env.example", ".env.sample", ".env.template"]);
|
|
3
|
+
const CREDENTIAL_STORE_PARTS = new Set([
|
|
4
|
+
".anthropic",
|
|
5
|
+
".aws",
|
|
6
|
+
".azure",
|
|
7
|
+
".claude",
|
|
8
|
+
".codex",
|
|
9
|
+
".cursor",
|
|
10
|
+
".docker",
|
|
11
|
+
".gcloud",
|
|
12
|
+
".gnupg",
|
|
13
|
+
".kube",
|
|
14
|
+
".openai",
|
|
15
|
+
".ssh",
|
|
16
|
+
]);
|
|
17
|
+
const CREDENTIAL_FILE_BASENAMES = new Set([
|
|
18
|
+
".git-credentials",
|
|
19
|
+
".netrc",
|
|
20
|
+
".npmrc",
|
|
21
|
+
".pypirc",
|
|
22
|
+
"application_default_credentials.json",
|
|
23
|
+
]);
|
|
24
|
+
const PRIVATE_KEY_EXTENSIONS = new Set([".jks", ".key", ".keystore", ".p12", ".pem", ".pfx"]);
|
|
25
|
+
const PRIVATE_KEY_BASENAME = /^id_(?:dsa|ecdsa|ed25519|rsa)(?:[._-].+)?$/;
|
|
26
|
+
const CREDENTIAL_FILE_BASENAME = /^(?:credentials(?:[._-].*)?|service-account(?:[._-].*)?\.json)$/;
|
|
27
|
+
const CONTENT_RULES = [
|
|
28
|
+
{ id: "github_token", pattern: /\bgithub_pat_[A-Za-z0-9_]{20,}\b/g },
|
|
29
|
+
{ id: "github_token", pattern: /\bghp_[A-Za-z0-9]{20,}\b/g },
|
|
30
|
+
{ id: "github_token", pattern: /\bgho_[A-Za-z0-9]{20,}\b/g },
|
|
31
|
+
{ id: "github_token", pattern: /\bghs_[A-Za-z0-9]{20,}\b/g },
|
|
32
|
+
{ id: "github_token", pattern: /\bghu_[A-Za-z0-9]{20,}\b/g },
|
|
33
|
+
{ id: "gitlab_token", pattern: /\bglpat-[A-Za-z0-9_-]{16,}\b/g },
|
|
34
|
+
{ id: "anthropic_api_key", pattern: /\bsk-ant-[A-Za-z0-9_-]{20,}\b/g },
|
|
35
|
+
{ id: "openai_compatible_api_key", pattern: /\bsk-or-v1-[A-Za-z0-9]{20,}\b/g },
|
|
36
|
+
{ id: "openai_compatible_api_key", pattern: /\bsk-[A-Za-z0-9_-]{20,}\b/g },
|
|
37
|
+
{ id: "google_api_key", pattern: /\bAIza[A-Za-z0-9_-]{30,}\b/g },
|
|
38
|
+
{ id: "xai_api_key", pattern: /\bxai-[A-Za-z0-9_-]{20,}\b/g },
|
|
39
|
+
{ id: "aws_access_key", pattern: /\bAKIA[0-9A-Z]{16}\b/g },
|
|
40
|
+
{ id: "slack_token", pattern: /\bxox[abceprs]-[A-Za-z0-9-]{10,}\b/g },
|
|
41
|
+
{ id: "cursor_api_key", pattern: /\bkey_[A-Za-z0-9]{20,}\b/g },
|
|
42
|
+
{ id: "google_oauth_token", pattern: /\bya29\.[A-Za-z0-9._-]{20,}\b/g },
|
|
43
|
+
{ id: "npm_token", pattern: /\bnpm_[A-Za-z0-9]{20,}\b/g },
|
|
44
|
+
{
|
|
45
|
+
id: "private_key_block",
|
|
46
|
+
pattern: /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g,
|
|
47
|
+
},
|
|
48
|
+
{ id: "bearer_token", pattern: /\bBearer\s+[A-Za-z0-9._~+/-]{20,}=*/gi },
|
|
49
|
+
{ id: "jwt", pattern: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{6,}\b/g },
|
|
50
|
+
];
|
|
51
|
+
const ALLOW_PATH = Object.freeze({
|
|
52
|
+
sensitive: false,
|
|
53
|
+
class: null,
|
|
54
|
+
matchedPart: null,
|
|
55
|
+
reason: null,
|
|
56
|
+
});
|
|
57
|
+
/**
|
|
58
|
+
* Single owner for sensitive path, symlink-target, and content decisions.
|
|
59
|
+
*
|
|
60
|
+
* The API is deliberately surface-neutral: context/review consume it now;
|
|
61
|
+
* upload and release scanners can consume the same typed decisions later
|
|
62
|
+
* without growing another classifier or weakening this policy.
|
|
63
|
+
*/
|
|
64
|
+
export class SensitiveResourcePolicy {
|
|
65
|
+
redactionMarker = "[redacted]";
|
|
66
|
+
classifyPath(path) {
|
|
67
|
+
const parts = normalizedPathParts(path);
|
|
68
|
+
for (let index = 0; index < parts.length; index += 1) {
|
|
69
|
+
const part = parts[index] ?? "";
|
|
70
|
+
const lower = part.toLowerCase();
|
|
71
|
+
if (CREDENTIAL_STORE_PARTS.has(lower)) {
|
|
72
|
+
return sensitivePath("credential_store", part, `credential-store path component: ${part}`);
|
|
73
|
+
}
|
|
74
|
+
if (lower === ".config" && parts[index + 1]?.toLowerCase() === "gcloud") {
|
|
75
|
+
return sensitivePath("credential_store", `${part}/${parts[index + 1]}`, `credential-store path component: ${part}/${parts[index + 1]}`);
|
|
76
|
+
}
|
|
77
|
+
// A monorepo package may legitimately own secret-management source code
|
|
78
|
+
// (`packages/secrets/**`). Its files still pass the shared content scan;
|
|
79
|
+
// every other `secrets` container remains path-sensitive.
|
|
80
|
+
const sourcePackage = index > 0 && parts[index - 1]?.toLowerCase() === "packages";
|
|
81
|
+
if (lower === "secrets" && !sourcePackage) {
|
|
82
|
+
return sensitivePath("secret_container", part, `secret-container path component: ${part}`);
|
|
83
|
+
}
|
|
84
|
+
if (lower === ".env" ||
|
|
85
|
+
lower === ".envrc" ||
|
|
86
|
+
lower.startsWith(".envrc.") ||
|
|
87
|
+
(lower.startsWith(".env.") && !SAFE_ENV_TEMPLATE_BASENAMES.has(lower))) {
|
|
88
|
+
return sensitivePath("environment_file", part, `environment secret file: ${part}`);
|
|
89
|
+
}
|
|
90
|
+
if (CREDENTIAL_FILE_BASENAMES.has(lower) || CREDENTIAL_FILE_BASENAME.test(lower)) {
|
|
91
|
+
return sensitivePath("credential_file", part, `credential file: ${part}`);
|
|
92
|
+
}
|
|
93
|
+
if (!lower.endsWith(".pub") && PRIVATE_KEY_BASENAME.test(lower)) {
|
|
94
|
+
return sensitivePath("private_key", part, `private-key basename: ${part}`);
|
|
95
|
+
}
|
|
96
|
+
if (PRIVATE_KEY_EXTENSIONS.has(extname(lower))) {
|
|
97
|
+
return sensitivePath("private_key", part, `private-key/container extension: ${extname(lower)}`);
|
|
98
|
+
}
|
|
99
|
+
if (lower === ".claudexor") {
|
|
100
|
+
const runtimePart = parts[index + 1]?.toLowerCase();
|
|
101
|
+
if (runtimePart && ["auth", "home", "homes", "secrets"].includes(runtimePart)) {
|
|
102
|
+
return sensitivePath("credential_store", `${part}/${parts[index + 1]}`, `Claudexor credential/runtime path: ${part}/${parts[index + 1]}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return ALLOW_PATH;
|
|
107
|
+
}
|
|
108
|
+
inspectContent(text, handling = "redact") {
|
|
109
|
+
let redacted = text;
|
|
110
|
+
const signatures = new Set();
|
|
111
|
+
for (const rule of CONTENT_RULES) {
|
|
112
|
+
const before = redacted;
|
|
113
|
+
redacted = redacted.replace(rule.pattern, this.redactionMarker);
|
|
114
|
+
if (redacted !== before)
|
|
115
|
+
signatures.add(rule.id);
|
|
116
|
+
}
|
|
117
|
+
if (signatures.size === 0) {
|
|
118
|
+
return { action: "allow", containsSensitiveContent: false, signatures: [], text };
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
action: handling,
|
|
122
|
+
containsSensitiveContent: true,
|
|
123
|
+
signatures: [...signatures],
|
|
124
|
+
// Never echo a matched secret from a policy decision, including a reject
|
|
125
|
+
// decision that a caller might later persist as diagnostic evidence.
|
|
126
|
+
text: redacted,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
redact(text) {
|
|
130
|
+
return this.inspectContent(text, "redact").text;
|
|
131
|
+
}
|
|
132
|
+
containsSensitiveContent(text) {
|
|
133
|
+
return this.inspectContent(text, "reject").containsSensitiveContent;
|
|
134
|
+
}
|
|
135
|
+
assessSymlink(input) {
|
|
136
|
+
const sourceRoot = resolve(input.sourceRoot);
|
|
137
|
+
const canonicalRoot = resolve(input.canonicalSourceRoot);
|
|
138
|
+
const sourcePath = resolve(input.sourcePath);
|
|
139
|
+
const excludedRoots = (input.excludedRoots ?? []).map((path) => resolve(path));
|
|
140
|
+
if (!isSameOrInside(sourceRoot, sourcePath)) {
|
|
141
|
+
return denySymlink("invalid_source", "symlink source is outside the allowed root");
|
|
142
|
+
}
|
|
143
|
+
const sourceDecision = this.classifyPath(relative(sourceRoot, sourcePath));
|
|
144
|
+
if (sourceDecision.sensitive) {
|
|
145
|
+
return denySymlink("sensitive_source", sourceDecision.reason ?? "symlink source is sensitive", sourceDecision);
|
|
146
|
+
}
|
|
147
|
+
if (!input.resolvedTargetPath) {
|
|
148
|
+
return denySymlink("unresolved_target", "symlink target cannot be resolved");
|
|
149
|
+
}
|
|
150
|
+
if (!input.allowedTargetKinds.includes(input.targetKind)) {
|
|
151
|
+
return denySymlink("target_kind", `symlink target kind is not allowed: ${input.targetKind}`);
|
|
152
|
+
}
|
|
153
|
+
const resolvedTarget = resolve(input.resolvedTargetPath);
|
|
154
|
+
if (!isSameOrInside(canonicalRoot, resolvedTarget)) {
|
|
155
|
+
return denySymlink("target_outside_root", "symlink resolves outside the allowed root");
|
|
156
|
+
}
|
|
157
|
+
if (excludedRoots.some((root) => isSameOrInside(root, resolvedTarget))) {
|
|
158
|
+
return denySymlink("excluded_target", "symlink resolves into an excluded root");
|
|
159
|
+
}
|
|
160
|
+
const targetDecision = this.classifyPath(relative(canonicalRoot, resolvedTarget));
|
|
161
|
+
if (targetDecision.sensitive) {
|
|
162
|
+
return denySymlink("sensitive_target", targetDecision.reason ?? "symlink target is sensitive", targetDecision);
|
|
163
|
+
}
|
|
164
|
+
return assessRelocation(input, sourceRoot, sourcePath, excludedRoots);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
export const sensitiveResourcePolicy = Object.freeze(new SensitiveResourcePolicy());
|
|
168
|
+
function normalizedPathParts(path) {
|
|
169
|
+
return path
|
|
170
|
+
.replace(/\\/g, "/")
|
|
171
|
+
.split("/")
|
|
172
|
+
.filter((part) => part.length > 0 && part !== ".");
|
|
173
|
+
}
|
|
174
|
+
function sensitivePath(pathClass, matchedPart, reason) {
|
|
175
|
+
return { sensitive: true, class: pathClass, matchedPart, reason };
|
|
176
|
+
}
|
|
177
|
+
function denySymlink(reason, detail, pathDecision = null) {
|
|
178
|
+
return { allowed: false, reason, detail, pathDecision };
|
|
179
|
+
}
|
|
180
|
+
function allowSymlink() {
|
|
181
|
+
return { allowed: true, reason: null, detail: null, pathDecision: null };
|
|
182
|
+
}
|
|
183
|
+
function assessRelocation(input, sourceRoot, sourcePath, excludedRoots) {
|
|
184
|
+
if (isAbsolute(input.linkTarget)) {
|
|
185
|
+
return input.relocationRoot
|
|
186
|
+
? denySymlink("absolute_target", "absolute symlink targets are not relocatable")
|
|
187
|
+
: allowSymlink();
|
|
188
|
+
}
|
|
189
|
+
if (!input.relocationRoot)
|
|
190
|
+
return allowSymlink();
|
|
191
|
+
const relocationRoot = resolve(input.relocationRoot);
|
|
192
|
+
const sourceParentRelative = relative(sourceRoot, dirname(sourcePath));
|
|
193
|
+
if (escapesRelativeRoot(sourceParentRelative)) {
|
|
194
|
+
return denySymlink("invalid_source", "symlink source parent is outside the allowed root");
|
|
195
|
+
}
|
|
196
|
+
const relocatedTargetRelative = normalize(join(sourceParentRelative, input.linkTarget));
|
|
197
|
+
if (escapesRelativeRoot(relocatedTargetRelative)) {
|
|
198
|
+
return denySymlink("relocation_escape", "symlink escapes when relocated");
|
|
199
|
+
}
|
|
200
|
+
const relocatedTarget = resolve(relocationRoot, relocatedTargetRelative);
|
|
201
|
+
if (!isSameOrInside(relocationRoot, relocatedTarget)) {
|
|
202
|
+
return denySymlink("relocation_escape", "symlink escapes the relocation root");
|
|
203
|
+
}
|
|
204
|
+
if (excludedRoots.some((root) => isSameOrInside(root, relocatedTarget))) {
|
|
205
|
+
return denySymlink("excluded_target", "relocated symlink resolves into an excluded root");
|
|
206
|
+
}
|
|
207
|
+
return allowSymlink();
|
|
208
|
+
}
|
|
209
|
+
function escapesRelativeRoot(path) {
|
|
210
|
+
if (isAbsolute(path))
|
|
211
|
+
return true;
|
|
212
|
+
const normalized = normalize(path);
|
|
213
|
+
const first = normalized.split(/[\\/]+/)[0];
|
|
214
|
+
return normalized === ".." || first === "..";
|
|
215
|
+
}
|
|
216
|
+
function isSameOrInside(parent, target) {
|
|
217
|
+
const rel = relative(resolve(parent), resolve(target));
|
|
218
|
+
const firstPart = rel.split(/[\\/]+/)[0];
|
|
219
|
+
return rel === "" || (!!rel && firstPart !== ".." && !isAbsolute(rel));
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=sensitive-resource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sensitive-resource.js","sourceRoot":"","sources":["../src/sensitive-resource.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const CLAUDEXOR_VERSION = "1.0
|
|
1
|
+
export declare const CLAUDEXOR_VERSION = "2.1.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// GENERATED by scripts/gen-version.mjs from the root package.json — do not edit by hand.
|
|
2
2
|
// Run `pnpm gen:version` after bumping the root version (changesets keeps the
|
|
3
3
|
// workspace manifests in lockstep). The docs-truth gate enforces parity.
|
|
4
|
-
export const CLAUDEXOR_VERSION = "1.0
|
|
4
|
+
export const CLAUDEXOR_VERSION = "2.1.0";
|
|
5
5
|
//# sourceMappingURL=version.js.map
|