@mnemonik/shared 7.97.2 → 7.98.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/ambientPointer.d.ts.map +1 -1
- package/dist/ambientPointer.js +2 -1
- package/dist/ambientPointer.js.map +1 -1
- package/dist/apiOrigin.d.ts +3 -0
- package/dist/apiOrigin.d.ts.map +1 -0
- package/dist/apiOrigin.js +5 -0
- package/dist/apiOrigin.js.map +1 -0
- package/dist/ast/astChunker.d.ts +12 -12
- package/dist/ast/astChunker.js +32 -32
- package/dist/ast/grammars.d.ts +9 -9
- package/dist/ast/grammars.js +15 -15
- package/dist/codeScanner.d.ts +56 -43
- package/dist/codeScanner.d.ts.map +1 -1
- package/dist/codeScanner.js +262 -143
- package/dist/codeScanner.js.map +1 -1
- package/dist/contextBudget.js +2 -2
- package/dist/contextBudget.js.map +1 -1
- package/dist/gitEditDetector.d.ts +6 -6
- package/dist/gitEditDetector.js +7 -7
- package/dist/hookRuntime.d.ts +35 -2
- package/dist/hookRuntime.d.ts.map +1 -1
- package/dist/hookRuntime.js +127 -33
- package/dist/hookRuntime.js.map +1 -1
- package/dist/hookTimeouts.d.ts +6 -6
- package/dist/hookTimeouts.js +6 -6
- package/dist/hostAdapter.d.ts +135 -0
- package/dist/hostAdapter.d.ts.map +1 -0
- package/dist/hostAdapter.js +323 -0
- package/dist/hostAdapter.js.map +1 -0
- package/dist/hostBinary.d.ts +29 -0
- package/dist/hostBinary.d.ts.map +1 -0
- package/dist/hostBinary.js +179 -0
- package/dist/hostBinary.js.map +1 -0
- package/dist/index.d.ts +11 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/instructions.d.ts +26 -26
- package/dist/instructions.js +26 -26
- package/dist/jitDeliveryAck.d.ts.map +1 -1
- package/dist/jitDeliveryAck.js +2 -0
- package/dist/jitDeliveryAck.js.map +1 -1
- package/dist/projectIdentityFile.d.ts +25 -0
- package/dist/projectIdentityFile.d.ts.map +1 -0
- package/dist/projectIdentityFile.js +87 -0
- package/dist/projectIdentityFile.js.map +1 -0
- package/dist/projectSetupHandoff.d.ts +24 -0
- package/dist/projectSetupHandoff.d.ts.map +1 -0
- package/dist/projectSetupHandoff.js +249 -0
- package/dist/projectSetupHandoff.js.map +1 -0
- package/dist/protectedPaths.d.ts +9 -0
- package/dist/protectedPaths.d.ts.map +1 -0
- package/dist/protectedPaths.js +66 -0
- package/dist/protectedPaths.js.map +1 -0
- package/dist/readiness.d.ts +143 -0
- package/dist/readiness.d.ts.map +1 -0
- package/dist/readiness.js +304 -0
- package/dist/readiness.js.map +1 -0
- package/dist/repositoryFingerprint.d.ts +50 -0
- package/dist/repositoryFingerprint.d.ts.map +1 -0
- package/dist/repositoryFingerprint.js +160 -0
- package/dist/repositoryFingerprint.js.map +1 -0
- package/dist/repositoryRoot.d.ts +56 -0
- package/dist/repositoryRoot.d.ts.map +1 -0
- package/dist/repositoryRoot.js +226 -0
- package/dist/repositoryRoot.js.map +1 -0
- package/dist/runtimeReader.d.ts +102 -0
- package/dist/runtimeReader.d.ts.map +1 -0
- package/dist/runtimeReader.js +408 -0
- package/dist/runtimeReader.js.map +1 -0
- package/dist/runtimeSigners.d.ts +37 -0
- package/dist/runtimeSigners.d.ts.map +1 -0
- package/dist/runtimeSigners.js +507 -0
- package/dist/runtimeSigners.js.map +1 -0
- package/dist/scannerSupervisor.d.ts +35 -0
- package/dist/scannerSupervisor.d.ts.map +1 -0
- package/dist/scannerSupervisor.js +2 -0
- package/dist/scannerSupervisor.js.map +1 -0
- package/dist/secretPatterns.d.ts +9 -9
- package/dist/secretPatterns.d.ts.map +1 -1
- package/dist/secretPatterns.js +27 -25
- package/dist/secretPatterns.js.map +1 -1
- package/dist/testing/hostAdapterConformance.d.ts +17 -0
- package/dist/testing/hostAdapterConformance.d.ts.map +1 -0
- package/dist/testing/hostAdapterConformance.js +477 -0
- package/dist/testing/hostAdapterConformance.js.map +1 -0
- package/dist/usageGuide.d.ts +1 -1
- package/dist/usageGuide.d.ts.map +1 -1
- package/dist/usageGuide.js +4 -4
- package/package.json +7 -2
- package/queries/bash.tags.scm +1 -1
- package/queries/groovy.tags.scm +1 -1
- package/scripts/vendor-grammars.ts +13 -13
- package/src/ambientPointer.ts +2 -1
- package/src/apiOrigin.ts +4 -0
- package/src/ast/astChunker.ts +39 -39
- package/src/ast/grammars.ts +16 -16
- package/src/codeScanner.ts +274 -149
- package/src/contextBudget.ts +2 -2
- package/src/gitEditDetector.ts +7 -7
- package/src/hookRuntime.ts +162 -34
- package/src/hookTimeouts.ts +6 -6
- package/src/hostAdapter.ts +468 -0
- package/src/hostBinary.ts +205 -0
- package/src/index.ts +20 -0
- package/src/instructions.ts +26 -26
- package/src/jitDeliveryAck.ts +2 -0
- package/src/projectIdentityFile.ts +100 -0
- package/src/projectSetupHandoff.ts +275 -0
- package/src/protectedPaths.ts +88 -0
- package/src/readiness.ts +516 -0
- package/src/repositoryFingerprint.ts +199 -0
- package/src/repositoryRoot.ts +261 -0
- package/src/runtimeReader.ts +495 -0
- package/src/runtimeSigners.ts +577 -0
- package/src/scannerSupervisor.ts +26 -0
- package/src/secretPatterns.ts +27 -25
- package/src/testing/hostAdapterConformance.ts +538 -0
- package/src/usageGuide.ts +4 -4
- package/test-fixtures/identity/runner.d.mts +12 -0
- package/test-fixtures/identity/runner.mjs +282 -0
- package/tests/fixtures/repository-fingerprint-v1.golden.json +834 -0
- package/tests/projectIdentity.test.ts +56 -0
- package/tests/readiness.test.ts +158 -0
- package/tests/repositoryFingerprint.test.ts +26 -0
- package/tsconfig.test.json +9 -0
- package/wasm/bash.tags.scm +1 -1
- package/wasm/groovy.tags.scm +1 -1
- package/wasm/javascript.tags.scm +2 -2
- package/wasm/solidity.tags.scm +1 -1
package/src/secretPatterns.ts
CHANGED
|
@@ -2,26 +2,26 @@
|
|
|
2
2
|
* Single source of truth for secret-redaction patterns.
|
|
3
3
|
*
|
|
4
4
|
* Used by:
|
|
5
|
-
* - packages/shared CodeScanner
|
|
5
|
+
* - packages/shared CodeScanner - scrubs chunk content before computing
|
|
6
6
|
* contentHash, so daemon ships scrubbed content (correct hash for
|
|
7
7
|
* server-side cache dedup).
|
|
8
|
-
* - server /api/v1/scan/push handler
|
|
9
|
-
* depth (idempotent
|
|
8
|
+
* - server /api/v1/scan/push handler - re-applies scrub as defense in
|
|
9
|
+
* depth (idempotent - already-scrubbed content stays the same), so
|
|
10
10
|
* older daemons or compromised daemons can't leak secrets through us.
|
|
11
|
-
* - server GitMiner
|
|
11
|
+
* - server GitMiner - scrubs commit messages before storing as memories.
|
|
12
12
|
*
|
|
13
13
|
* Patterns target high-confidence credential shapes:
|
|
14
14
|
* 1. key=value style: api_key, secret, token, password, credential, auth
|
|
15
15
|
* 2. Stripe-style sk_live_/pk_test_ keys
|
|
16
16
|
* 3. GitHub personal access tokens (ghp_ prefix, exact 36 chars)
|
|
17
17
|
* 4. GitLab personal access tokens (glpat- prefix, 20+ chars)
|
|
18
|
-
* 5. PEM private keys
|
|
18
|
+
* 5. PEM private keys - whole block, header through footer
|
|
19
19
|
* 6. Provider prefixes: AWS (AKIA/ASIA + labeled secret key), JWT,
|
|
20
20
|
* Slack (xox*), Google (AIza), Anthropic (sk-ant-), npm (npm_/npms_)
|
|
21
21
|
* 7. Credentials inside scheme://user:pass@host connection strings
|
|
22
22
|
* 8. Authorization: Bearer headers
|
|
23
23
|
* 9. Standalone high-entropy tokens matching no known prefix
|
|
24
|
-
* (`redactHighEntropyTokens`
|
|
24
|
+
* (`redactHighEntropyTokens` - heavily guarded, see below)
|
|
25
25
|
*
|
|
26
26
|
* False-positive cost: a few legitimate strings get replaced with the
|
|
27
27
|
* placeholder. False-negative cost: a credential ships to the server and
|
|
@@ -32,10 +32,10 @@
|
|
|
32
32
|
* FIDELITY IS A PEER CONCERN, NOT A ROUNDING ERROR. Over-scrubbing is the
|
|
33
33
|
* same class of failure as under-scrubbing: a pattern that eats prose,
|
|
34
34
|
* identifiers, hashes or paths silently blinds doc-truth's authority
|
|
35
|
-
* extractors
|
|
35
|
+
* extractors - exactly what happened when a `process.env.X` read was
|
|
36
36
|
* redacted as if it were a literal (see ENV_READ_VALUE_RE below). Every
|
|
37
37
|
* pattern here carries positive AND negative tests in
|
|
38
|
-
* tests/SecretPatterns.test.ts, and the entropy detector is
|
|
38
|
+
* tests/SecretPatterns.test.ts, and the entropy detector is also
|
|
39
39
|
* guarded against hashes, UUIDs, paths, slugs and identifiers.
|
|
40
40
|
*/
|
|
41
41
|
|
|
@@ -45,7 +45,7 @@ export const SECRET_REDACTION_PLACEHOLDER = '[REDACTED]';
|
|
|
45
45
|
export const SECRET_PATTERNS: ReadonlyArray<RegExp> = [
|
|
46
46
|
/(?:api[_-]?key|secret|token|password|credential|auth)\s*[:=]\s*\S+/gi,
|
|
47
47
|
// Stripe-shape: (sk|pk)_(live|test)_<24+ alphanumerics>. Catches modern
|
|
48
|
-
// Stripe keys whose body is split by an environment
|
|
48
|
+
// Stripe keys whose body is split by an environment separator that
|
|
49
49
|
// breaks the contiguous-alphanum pattern below. Required `live|test`
|
|
50
50
|
// literal prevents false-positives on snake_case identifiers like
|
|
51
51
|
// pkg_install_helper_function_xyz_abc_def.
|
|
@@ -53,7 +53,7 @@ export const SECRET_PATTERNS: ReadonlyArray<RegExp> = [
|
|
|
53
53
|
/(?:sk|pk)[-_][a-zA-Z0-9]{20,}/g,
|
|
54
54
|
/ghp_[a-zA-Z0-9]{36}/g,
|
|
55
55
|
/glpat-[a-zA-Z0-9-]{20,}/g,
|
|
56
|
-
// PEM private keys. The BLOCK pattern runs first so header
|
|
56
|
+
// PEM private keys. The BLOCK pattern runs first so header->footer (the
|
|
57
57
|
// actual key material) is redacted as one unit; the header-only pattern
|
|
58
58
|
// stays as the fallback for the case a chunk boundary lands between
|
|
59
59
|
// header and footer, where the block never closes inside the chunk.
|
|
@@ -82,7 +82,7 @@ export const SECRET_PATTERNS: ReadonlyArray<RegExp> = [
|
|
|
82
82
|
/\b[a-z][a-z0-9+.-]*:\/\/[^/\s?#]*@/gi,
|
|
83
83
|
// Authorization: Bearer <token>. The token class deliberately excludes
|
|
84
84
|
// `<` and `$`, so documentation placeholders (`Bearer <your-api-key>`,
|
|
85
|
-
// `Bearer $MNEMONIK_PROXY_TOKEN`) are left intact
|
|
85
|
+
// `Bearer $MNEMONIK_PROXY_TOKEN`) are left intact - redacting those would
|
|
86
86
|
// destroy the instruction without hiding a secret.
|
|
87
87
|
/Authorization\s*:\s*Bearer\s+[A-Za-z0-9._~+/-]+=*/gi,
|
|
88
88
|
];
|
|
@@ -97,7 +97,7 @@ export const SECRET_PATTERNS: ReadonlyArray<RegExp> = [
|
|
|
97
97
|
/**
|
|
98
98
|
* A key=value match whose value side is a code REFERENCE to an env read
|
|
99
99
|
* (`process.env.X`, `process.env['X']`, `import.meta.env.X`) contains no
|
|
100
|
-
* literal secret
|
|
100
|
+
* literal secret - redacting it destroys information (it blinded the
|
|
101
101
|
* doc-truth env_vars authority to every secret-named variable) without
|
|
102
102
|
* protecting anything.
|
|
103
103
|
*/
|
|
@@ -106,7 +106,7 @@ const ENV_READ_VALUE_RE = /[:=]\s*(?:await\s+)?(?:process\.env[.[]|import\.meta\
|
|
|
106
106
|
/* ------------------------------------------------------------------ *
|
|
107
107
|
* High-entropy token detector
|
|
108
108
|
*
|
|
109
|
-
* Catches credentials that carry no recognizable provider prefix
|
|
109
|
+
* Catches credentials that carry no recognizable provider prefix - the
|
|
110
110
|
* long random blob in `"webhook": "<40 random chars>"`. A naive entropy
|
|
111
111
|
* threshold cannot do this safely: measured over this repository, a
|
|
112
112
|
* camelCase identifier scores 4.49 bits/char against 4.66 for a real AWS
|
|
@@ -114,10 +114,10 @@ const ENV_READ_VALUE_RE = /[:=]\s*(?:await\s+)?(?:process\.env[.[]|import\.meta\
|
|
|
114
114
|
* below carry the discrimination; entropy is only the final filter.
|
|
115
115
|
*
|
|
116
116
|
* Every candidate must clear ALL of:
|
|
117
|
-
* 1. CONTEXT
|
|
117
|
+
* 1. CONTEXT - sits immediately after `=`/`:` or an opening quote.
|
|
118
118
|
* Bare prose positions are never touched, which is what
|
|
119
119
|
* keeps the detector out of documentation.
|
|
120
|
-
* 2. LENGTH
|
|
120
|
+
* 2. LENGTH - >= 36 characters. The floor started at 32 and was
|
|
121
121
|
* raised by the claim-yield guard: 32-char opaque
|
|
122
122
|
* RESOURCE IDS (Vercel `dpl_`/`prj_`, Stripe object ids)
|
|
123
123
|
* are public identifiers, not credentials, and eating
|
|
@@ -127,19 +127,19 @@ const ENV_READ_VALUE_RE = /[:=]\s*(?:await\s+)?(?:process\.env[.[]|import\.meta\
|
|
|
127
127
|
* base64 32-byte key 44); shorter non-hex randomness is
|
|
128
128
|
* almost always an object id, and anything hex is
|
|
129
129
|
* already exempt by rule 4.
|
|
130
|
-
* 3. CHARSET MIX
|
|
131
|
-
* 4. NOT HEX-ISH
|
|
130
|
+
* 3. CHARSET MIX - contains lowercase AND uppercase AND a digit.
|
|
131
|
+
* 4. NOT HEX-ISH - hex after stripping `-`/`_` is a digest or UUID
|
|
132
132
|
* (commit SHAs, contentHash, snippet_hash, project ids).
|
|
133
|
-
* 5. NOT STRUCTURED
|
|
133
|
+
* 5. NOT STRUCTURED - if every `/`, `-`, `_` separated segment is <= 16
|
|
134
134
|
* chars the token is a path, slug or SCREAMING_SNAKE
|
|
135
135
|
* identifier ("tests/fixtures/docTruth/dogfood-2026-06-06").
|
|
136
|
-
* 6. NOT WORDY
|
|
136
|
+
* 6. NOT WORDY - a lowercase run longer than 5 means natural words
|
|
137
137
|
* ("...FromCache..."), not random output.
|
|
138
|
-
* 7. ENTROPY
|
|
138
|
+
* 7. ENTROPY - Shannon entropy >= 4.0 bits/char.
|
|
139
139
|
*
|
|
140
140
|
* Calibrated by sweeping every file this scanner would chunk across this
|
|
141
141
|
* repository (1426 files): 8 tokens fire, every one of them a credential
|
|
142
|
-
* shape
|
|
142
|
+
* shape - JWT headers, an AWS example secret key, a leaked Stripe
|
|
143
143
|
* `whsec_`, and this suite's own fixtures. Zero prose, zero paths, zero
|
|
144
144
|
* identifiers, zero resource ids.
|
|
145
145
|
*
|
|
@@ -154,14 +154,16 @@ const ENTROPY_MAX_LOWERCASE_RUN = 5;
|
|
|
154
154
|
|
|
155
155
|
/**
|
|
156
156
|
* Maximal runs of base64url/base64 characters. `=` is admitted only as
|
|
157
|
-
* trailing padding
|
|
157
|
+
* trailing padding - allowing it inside the run let a candidate span an
|
|
158
158
|
* assignment (`HARNESS_PROJECT_ID=<uuid>` matched as one token, defeating
|
|
159
159
|
* the UUID exemption).
|
|
160
160
|
*/
|
|
161
|
-
|
|
161
|
+
// Keep the same 36-character floor without an unbounded counted repetition:
|
|
162
|
+
// V8 retains backtracking state for {36,} and overflows on a 10 MiB line.
|
|
163
|
+
const ENTROPY_CANDIDATE_RE = /[A-Za-z0-9+/_-]{35}[A-Za-z0-9+/_-]+={0,2}/g;
|
|
162
164
|
/** Opening quote, or `=`/`:` with optional whitespace and optional quote. */
|
|
163
165
|
const ENTROPY_CONTEXT_RE = /(?:["'`]|[:=]\s*["'`]?)$/;
|
|
164
|
-
/** `==`, `=>`, `!=`, `<=`, `>=`, `+=`
|
|
166
|
+
/** `==`, `=>`, `!=`, `<=`, `>=`, `+=` ... are comparisons, not assignments. */
|
|
165
167
|
const ENTROPY_OPERATOR_TAIL_RE = /[=!<>+\-*/%&|^]$/;
|
|
166
168
|
const ENTROPY_HEXISH_RE = /^[0-9a-fA-F]+$/;
|
|
167
169
|
const ENTROPY_STRUCTURED_RE = /^[A-Za-z0-9]+(?:[/_-][A-Za-z0-9]+)+$/;
|
|
@@ -209,7 +211,7 @@ function isHighEntropySecret(token: string): boolean {
|
|
|
209
211
|
|
|
210
212
|
/**
|
|
211
213
|
* Redact standalone high-entropy tokens that no provider pattern claimed.
|
|
212
|
-
* Only the token is replaced
|
|
214
|
+
* Only the token is replaced - the surrounding key, quote and punctuation
|
|
213
215
|
* survive, so `{"webhook": "<secret>"}` stays valid, readable JSON.
|
|
214
216
|
*
|
|
215
217
|
* Exported for direct testing of the guard behavior; production callers
|