agent-inspect 6.29.0 → 6.29.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/CHANGELOG.md +6 -0
- package/README.md +1 -1
- package/docs/CLI.md +19 -1
- package/docs/LIMITATIONS.md +1 -1
- package/docs/SAFE-TRACE-SHARING.md +1 -1
- package/docs/STANDARDS.md +1 -1
- package/package.json +1 -1
- package/packages/cli/dist/{chunk-D7PT6TXM.mjs → chunk-UK4HD5M3.mjs} +126 -26
- package/packages/cli/dist/chunk-UK4HD5M3.mjs.map +1 -0
- package/packages/cli/dist/index.cjs +196 -97
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +63 -72
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/cli/dist/{src-QONEBW2F.mjs → src-CMPIJGUE.mjs} +3 -3
- package/packages/cli/dist/{src-QONEBW2F.mjs.map → src-CMPIJGUE.mjs.map} +1 -1
- package/packages/core/dist/advanced.cjs +100 -24
- package/packages/core/dist/advanced.cjs.map +1 -1
- package/packages/core/dist/advanced.d.cts +11 -0
- package/packages/core/dist/advanced.d.ts +11 -0
- package/packages/core/dist/advanced.mjs +109 -33
- package/packages/core/dist/advanced.mjs.map +1 -1
- package/packages/core/dist/checks.cjs +225 -33
- package/packages/core/dist/checks.cjs.map +1 -1
- package/packages/core/dist/checks.mjs +3 -3
- package/packages/core/dist/{chunk-TNOPL75V.mjs → chunk-5RF7FYGL.mjs} +3 -3
- package/packages/core/dist/{chunk-TNOPL75V.mjs.map → chunk-5RF7FYGL.mjs.map} +1 -1
- package/packages/core/dist/{chunk-3B24355S.mjs → chunk-65LFRW2T.mjs} +3 -3
- package/packages/core/dist/{chunk-3B24355S.mjs.map → chunk-65LFRW2T.mjs.map} +1 -1
- package/packages/core/dist/{chunk-TIGBAVED.mjs → chunk-AQMJFKI6.mjs} +4 -4
- package/packages/core/dist/{chunk-TIGBAVED.mjs.map → chunk-AQMJFKI6.mjs.map} +1 -1
- package/packages/core/dist/{chunk-MVRZ7JBH.mjs → chunk-COZPMOUF.mjs} +3 -3
- package/packages/core/dist/{chunk-MVRZ7JBH.mjs.map → chunk-COZPMOUF.mjs.map} +1 -1
- package/packages/core/dist/{chunk-LGTPSHH2.mjs → chunk-GPGBKN7W.mjs} +228 -36
- package/packages/core/dist/chunk-GPGBKN7W.mjs.map +1 -0
- package/packages/core/dist/exporters.cjs +10 -5
- package/packages/core/dist/exporters.cjs.map +1 -1
- package/packages/core/dist/exporters.d.cts +12 -2
- package/packages/core/dist/exporters.d.ts +12 -2
- package/packages/core/dist/exporters.mjs +13 -8
- package/packages/core/dist/exporters.mjs.map +1 -1
- package/packages/core/dist/index.mjs +4 -4
- package/packages/core/dist/writers.mjs +1 -1
- package/packages/cli/dist/chunk-D7PT6TXM.mjs.map +0 -1
- package/packages/core/dist/chunk-LGTPSHH2.mjs.map +0 -1
|
@@ -165,8 +165,31 @@ var init_redactor = __esm({
|
|
|
165
165
|
});
|
|
166
166
|
|
|
167
167
|
// packages/core/src/safety/credential-value-patterns.ts
|
|
168
|
+
function stringContainsHighConfidenceCredential(value) {
|
|
169
|
+
for (const pattern of HIGH_CONFIDENCE_CREDENTIAL_PATTERNS) {
|
|
170
|
+
pattern.lastIndex = 0;
|
|
171
|
+
if (pattern.test(value)) {
|
|
172
|
+
pattern.lastIndex = 0;
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
var KEY_VALUE_SECRET_PATTERN, HIGH_CONFIDENCE_CREDENTIAL_PATTERNS;
|
|
168
179
|
var init_credential_value_patterns = __esm({
|
|
169
180
|
"packages/core/src/safety/credential-value-patterns.ts"() {
|
|
181
|
+
KEY_VALUE_SECRET_PATTERN = /\b(?:api[_-]?key|internal[_-]?token|access[_-]?token|auth[_-]?token|password|secret|token)=([^\s"'\\]{8,})/i;
|
|
182
|
+
HIGH_CONFIDENCE_CREDENTIAL_PATTERNS = [
|
|
183
|
+
/^(?:basic|bearer|digest|apikey)\s+[a-z0-9._~+/=-]+$/i,
|
|
184
|
+
/\bbearer\s+[a-z0-9._~+/=-]{12,}\b/i,
|
|
185
|
+
/\b[a-z0-9_.-]+=[^;\s]+(?:;\s*[a-z0-9_.-]+=[^;\s]+)+/i,
|
|
186
|
+
/\beyJ[a-zA-Z0-9_-]{8,}\.[a-zA-Z0-9_-]{8,}\.[a-zA-Z0-9_-]{8,}\b/,
|
|
187
|
+
/\b(?:sk-(?:proj-)?[a-zA-Z0-9_-]{16,}|sk-ant-[a-zA-Z0-9_-]{16,}|AIza[0-9A-Za-z_-]{20,})\b/,
|
|
188
|
+
/\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{20,}\b/,
|
|
189
|
+
/\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/,
|
|
190
|
+
/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*-----END [A-Z ]*PRIVATE KEY-----/,
|
|
191
|
+
KEY_VALUE_SECRET_PATTERN
|
|
192
|
+
];
|
|
170
193
|
}
|
|
171
194
|
});
|
|
172
195
|
|
|
@@ -6972,9 +6995,16 @@ var init_control_rules = __esm({
|
|
|
6972
6995
|
}
|
|
6973
6996
|
});
|
|
6974
6997
|
|
|
6998
|
+
// packages/core/src/checks/canonical-equality.ts
|
|
6999
|
+
var init_canonical_equality = __esm({
|
|
7000
|
+
"packages/core/src/checks/canonical-equality.ts"() {
|
|
7001
|
+
}
|
|
7002
|
+
});
|
|
7003
|
+
|
|
6975
7004
|
// packages/core/src/checks/tool-arguments.ts
|
|
6976
7005
|
var init_tool_arguments = __esm({
|
|
6977
7006
|
"packages/core/src/checks/tool-arguments.ts"() {
|
|
7007
|
+
init_canonical_equality();
|
|
6978
7008
|
}
|
|
6979
7009
|
});
|
|
6980
7010
|
|
|
@@ -6989,6 +7019,7 @@ var init_retry_safety = __esm({
|
|
|
6989
7019
|
// packages/core/src/checks/recovery-operations.ts
|
|
6990
7020
|
var init_recovery_operations = __esm({
|
|
6991
7021
|
"packages/core/src/checks/recovery-operations.ts"() {
|
|
7022
|
+
init_canonical_equality();
|
|
6992
7023
|
init_logical_events();
|
|
6993
7024
|
init_tool_arguments();
|
|
6994
7025
|
init_retry_safety();
|
|
@@ -7196,6 +7227,38 @@ var init_contract = __esm({
|
|
|
7196
7227
|
});
|
|
7197
7228
|
|
|
7198
7229
|
// packages/core/src/evidence/contract-binding.ts
|
|
7230
|
+
function contractContainsUnsafeExpectedValues(value) {
|
|
7231
|
+
return scanForExpectedFields(value, 0);
|
|
7232
|
+
}
|
|
7233
|
+
function scanForExpectedFields(value, depth) {
|
|
7234
|
+
if (depth > 32) return false;
|
|
7235
|
+
if (Array.isArray(value)) {
|
|
7236
|
+
return value.some((item) => scanForExpectedFields(item, depth + 1));
|
|
7237
|
+
}
|
|
7238
|
+
if (value === null || typeof value !== "object") return false;
|
|
7239
|
+
const record = value;
|
|
7240
|
+
for (const [key, child] of Object.entries(record)) {
|
|
7241
|
+
if (key === "expected" || key === "oneOf") {
|
|
7242
|
+
if (valueTreeContainsCredential(child, depth + 1)) return true;
|
|
7243
|
+
continue;
|
|
7244
|
+
}
|
|
7245
|
+
if (scanForExpectedFields(child, depth + 1)) return true;
|
|
7246
|
+
}
|
|
7247
|
+
return false;
|
|
7248
|
+
}
|
|
7249
|
+
function valueTreeContainsCredential(value, depth) {
|
|
7250
|
+
if (depth > 32) return false;
|
|
7251
|
+
if (typeof value === "string") {
|
|
7252
|
+
return stringContainsHighConfidenceCredential(value);
|
|
7253
|
+
}
|
|
7254
|
+
if (Array.isArray(value)) {
|
|
7255
|
+
return value.some((item) => valueTreeContainsCredential(item, depth + 1));
|
|
7256
|
+
}
|
|
7257
|
+
if (value === null || typeof value !== "object") return false;
|
|
7258
|
+
return Object.values(value).some(
|
|
7259
|
+
(child) => valueTreeContainsCredential(child, depth + 1)
|
|
7260
|
+
);
|
|
7261
|
+
}
|
|
7199
7262
|
function serializeCanonicalJson(value) {
|
|
7200
7263
|
return `${JSON.stringify(stableValue(value), null, 2)}
|
|
7201
7264
|
`;
|
|
@@ -7329,6 +7392,32 @@ function buildEvidenceContractPackage(input3) {
|
|
|
7329
7392
|
if (unsupported.length > 0) {
|
|
7330
7393
|
ruleIds = sortedUniqueStrings([...ruleIds, ...unsupported]);
|
|
7331
7394
|
}
|
|
7395
|
+
if (contractContainsUnsafeExpectedValues(resolved)) {
|
|
7396
|
+
return {
|
|
7397
|
+
binding: {
|
|
7398
|
+
status: "unavailable",
|
|
7399
|
+
source: input3.source,
|
|
7400
|
+
...input3.contractId !== void 0 ? { contractId: input3.contractId } : {},
|
|
7401
|
+
...input3.contractVersion !== void 0 ? { contractVersion: input3.contractVersion } : {},
|
|
7402
|
+
canonicalizationVersion: EVIDENCE_CONTRACT_CANONICALIZATION_VERSION,
|
|
7403
|
+
engineVersion: input3.engineVersion,
|
|
7404
|
+
ruleIds,
|
|
7405
|
+
...unsupported.length > 0 ? { unsupportedRuleIds: unsupported } : {},
|
|
7406
|
+
note: input3.note ?? EVIDENCE_CONTRACT_UNSAFE_NOTE
|
|
7407
|
+
},
|
|
7408
|
+
checkBinding: {
|
|
7409
|
+
canonicalizationVersion: EVIDENCE_CONTRACT_CANONICALIZATION_VERSION,
|
|
7410
|
+
engineVersion: input3.engineVersion,
|
|
7411
|
+
evaluatedRuleIds: ruleIds,
|
|
7412
|
+
bindingStatus: "unavailable",
|
|
7413
|
+
...unsupported.length > 0 ? { unsupportedRuleIds: unsupported } : {},
|
|
7414
|
+
origin: {
|
|
7415
|
+
source: input3.source,
|
|
7416
|
+
...input3.preset?.name ? { preset: input3.preset.name } : {}
|
|
7417
|
+
}
|
|
7418
|
+
}
|
|
7419
|
+
};
|
|
7420
|
+
}
|
|
7332
7421
|
const document = {
|
|
7333
7422
|
canonicalizationVersion: EVIDENCE_CONTRACT_CANONICALIZATION_VERSION,
|
|
7334
7423
|
kind,
|
|
@@ -7468,16 +7557,18 @@ function verifyEvidenceContractBinding(parts) {
|
|
|
7468
7557
|
}
|
|
7469
7558
|
return issues;
|
|
7470
7559
|
}
|
|
7471
|
-
var EVIDENCE_CONTRACT_CANONICALIZATION_VERSION, EVIDENCE_CONTRACT_PARTIAL_NOTE, EVIDENCE_CONTRACT_UNAVAILABLE_NOTE, EVIDENCE_CONTRACT_ASSURANCE_NOTE;
|
|
7560
|
+
var EVIDENCE_CONTRACT_CANONICALIZATION_VERSION, EVIDENCE_CONTRACT_PARTIAL_NOTE, EVIDENCE_CONTRACT_UNAVAILABLE_NOTE, EVIDENCE_CONTRACT_ASSURANCE_NOTE, EVIDENCE_CONTRACT_UNSAFE_NOTE;
|
|
7472
7561
|
var init_contract_binding = __esm({
|
|
7473
7562
|
"packages/core/src/evidence/contract-binding.ts"() {
|
|
7474
7563
|
init_contract();
|
|
7564
|
+
init_credential_value_patterns();
|
|
7475
7565
|
init_hash();
|
|
7476
7566
|
init_types4();
|
|
7477
7567
|
EVIDENCE_CONTRACT_CANONICALIZATION_VERSION = "1";
|
|
7478
7568
|
EVIDENCE_CONTRACT_PARTIAL_NOTE = "Custom or programmatic rules are not serializable; Evidence records rule IDs only and does not claim complete reviewer replay.";
|
|
7479
7569
|
EVIDENCE_CONTRACT_UNAVAILABLE_NOTE = "No resolved TraceContract or check preset was packaged with this Evidence artifact.";
|
|
7480
7570
|
EVIDENCE_CONTRACT_ASSURANCE_NOTE = "Contract binding verifies packaged digest integrity only; it does not prove producer identity, trusted time, source completeness, semantic truth, or external acceptance.";
|
|
7571
|
+
EVIDENCE_CONTRACT_UNSAFE_NOTE = "Resolved TraceContract contains high-confidence credential-like expected values; Evidence refuses complete packaging rather than silently redacting evaluated expectations.";
|
|
7481
7572
|
}
|
|
7482
7573
|
});
|
|
7483
7574
|
|
|
@@ -7826,7 +7917,15 @@ function buildEmbeddedPayload(input3) {
|
|
|
7826
7917
|
redactionProfile: input3.redactionProfile,
|
|
7827
7918
|
verificationPolicy: input3.verificationPolicy
|
|
7828
7919
|
},
|
|
7829
|
-
checkSummary: input3.checkSummary
|
|
7920
|
+
checkSummary: input3.checkSummary,
|
|
7921
|
+
...input3.contractBinding !== void 0 ? {
|
|
7922
|
+
contract: {
|
|
7923
|
+
status: input3.contractBinding.status,
|
|
7924
|
+
...input3.contractBinding.sha256 !== void 0 ? { sha256: input3.contractBinding.sha256 } : {},
|
|
7925
|
+
...input3.contractBinding.ruleCount !== void 0 ? { ruleCount: input3.contractBinding.ruleCount } : {},
|
|
7926
|
+
...input3.contractBinding.note !== void 0 ? { note: input3.contractBinding.note } : {}
|
|
7927
|
+
}
|
|
7928
|
+
} : {}
|
|
7830
7929
|
};
|
|
7831
7930
|
}
|
|
7832
7931
|
function buildEvidenceHtmlShell(input3) {
|
|
@@ -7924,6 +8023,7 @@ ${nav}
|
|
|
7924
8023
|
<p>Artifact status: <span class="badge ${statusClass(input3.assessmentStatus)}">${escapeHtml(input3.assessmentStatus)}</span>
|
|
7925
8024
|
${input3.sourceStatus !== void 0 ? ` \xB7 Source status: <span class="badge ${statusClass(input3.sourceStatus)}">${escapeHtml(input3.sourceStatus)}</span>` : ""}</p>
|
|
7926
8025
|
<p>Profile: <code>${escapeHtml(input3.redactionProfile)}</code> \xB7 Verification: <code>${escapeHtml(input3.verificationPolicy)}</code></p>
|
|
8026
|
+
${input3.contractBinding !== void 0 ? `<p>Contract binding: <code>${escapeHtml(input3.contractBinding.status)}</code>${input3.contractBinding.ruleCount !== void 0 ? ` \xB7 Rules: <code>${escapeHtml(String(input3.contractBinding.ruleCount))}</code>` : ""}${input3.contractBinding.sha256 !== void 0 ? ` \xB7 Digest: <code>${escapeHtml(input3.contractBinding.sha256.slice(0, 16))}\u2026</code>` : ""}</p>${input3.contractBinding.note !== void 0 && input3.contractBinding.note.trim() !== "" ? `<p class="muted">${escapeHtml(input3.contractBinding.note)}</p>` : ""}` : ""}
|
|
7927
8027
|
<p>Generator: <code>${escapeHtml(input3.generatorName)}@${escapeHtml(input3.generatorVersion)}</code>
|
|
7928
8028
|
${input3.createdAt ? ` \xB7 Created: <code>${escapeHtml(input3.createdAt)}</code>` : ""}</p>
|
|
7929
8029
|
<h3>Runs</h3>
|
|
@@ -9015,29 +9115,6 @@ function buildEvidenceCiPackage(input3) {
|
|
|
9015
9115
|
schemaVersions.add(version2);
|
|
9016
9116
|
}
|
|
9017
9117
|
const createdAt = input3.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
9018
|
-
const evidenceHtml = buildEvidenceHtmlShell({
|
|
9019
|
-
title: "AgentInspect evidence",
|
|
9020
|
-
runIds: input3.runIds,
|
|
9021
|
-
assessmentStatus: input3.assessmentStatus,
|
|
9022
|
-
sourceStatus: input3.sourceStatus,
|
|
9023
|
-
redactionProfile: input3.redactionProfile,
|
|
9024
|
-
verificationPolicy: input3.redactionProfile,
|
|
9025
|
-
generatorName: "agent-inspect",
|
|
9026
|
-
generatorVersion: input3.generatorVersion,
|
|
9027
|
-
createdAt,
|
|
9028
|
-
summaryText: input3.summaryText,
|
|
9029
|
-
checkSummary: {
|
|
9030
|
-
aggregateStatus: input3.assessmentStatus,
|
|
9031
|
-
runs: input3.runIds.map((runId) => ({
|
|
9032
|
-
runId,
|
|
9033
|
-
status: input3.assessmentStatus,
|
|
9034
|
-
sourceStatus: input3.sourceStatus,
|
|
9035
|
-
errors: input3.assessmentStatus === "UNSAFE" || input3.assessmentStatus === "UNKNOWN" ? 1 : 0,
|
|
9036
|
-
warnings: input3.assessmentStatus === "SAFE WITH WARNINGS" ? 1 : 0,
|
|
9037
|
-
findings: 0
|
|
9038
|
-
}))
|
|
9039
|
-
}
|
|
9040
|
-
});
|
|
9041
9118
|
let checkResultsJson = input3.checkResultsJson;
|
|
9042
9119
|
let contractBinding;
|
|
9043
9120
|
let contractFileContent;
|
|
@@ -9060,6 +9137,37 @@ function buildEvidenceCiPackage(input3) {
|
|
|
9060
9137
|
bindCheckResultsToContract(parsed, packaged2.checkBinding)
|
|
9061
9138
|
);
|
|
9062
9139
|
}
|
|
9140
|
+
const evidenceHtml = buildEvidenceHtmlShell({
|
|
9141
|
+
title: "AgentInspect evidence",
|
|
9142
|
+
runIds: input3.runIds,
|
|
9143
|
+
assessmentStatus: input3.assessmentStatus,
|
|
9144
|
+
sourceStatus: input3.sourceStatus,
|
|
9145
|
+
redactionProfile: input3.redactionProfile,
|
|
9146
|
+
verificationPolicy: input3.redactionProfile,
|
|
9147
|
+
generatorName: "agent-inspect",
|
|
9148
|
+
generatorVersion: input3.generatorVersion,
|
|
9149
|
+
createdAt,
|
|
9150
|
+
summaryText: input3.summaryText,
|
|
9151
|
+
checkSummary: {
|
|
9152
|
+
aggregateStatus: input3.assessmentStatus,
|
|
9153
|
+
runs: input3.runIds.map((runId) => ({
|
|
9154
|
+
runId,
|
|
9155
|
+
status: input3.assessmentStatus,
|
|
9156
|
+
sourceStatus: input3.sourceStatus,
|
|
9157
|
+
errors: input3.assessmentStatus === "UNSAFE" || input3.assessmentStatus === "UNKNOWN" ? 1 : 0,
|
|
9158
|
+
warnings: input3.assessmentStatus === "SAFE WITH WARNINGS" ? 1 : 0,
|
|
9159
|
+
findings: 0
|
|
9160
|
+
}))
|
|
9161
|
+
},
|
|
9162
|
+
...contractBinding !== void 0 ? {
|
|
9163
|
+
contractBinding: {
|
|
9164
|
+
status: contractBinding.status,
|
|
9165
|
+
...contractBinding.sha256 !== void 0 ? { sha256: contractBinding.sha256 } : {},
|
|
9166
|
+
...contractBinding.note !== void 0 ? { note: contractBinding.note } : {},
|
|
9167
|
+
ruleCount: contractBinding.ruleIds.length
|
|
9168
|
+
}
|
|
9169
|
+
} : {}
|
|
9170
|
+
});
|
|
9063
9171
|
const packaged = [
|
|
9064
9172
|
{ path: EVIDENCE_HTML_FILENAME, content: evidenceHtml },
|
|
9065
9173
|
{ path: "check-results.json", content: checkResultsJson },
|
|
@@ -13648,7 +13756,7 @@ var init_src = __esm({
|
|
|
13648
13756
|
});
|
|
13649
13757
|
|
|
13650
13758
|
// package.json
|
|
13651
|
-
var version = "6.29.
|
|
13759
|
+
var version = "6.29.1";
|
|
13652
13760
|
|
|
13653
13761
|
// packages/cli/src/list.ts
|
|
13654
13762
|
init_advanced();
|
|
@@ -17641,13 +17749,13 @@ function isCredentialSensitiveKey2(key, sensitiveKeys) {
|
|
|
17641
17749
|
|
|
17642
17750
|
// packages/redact/src/key-value-secret.ts
|
|
17643
17751
|
var KEY_VALUE_SECRET_PATTERN_SOURCE = String.raw`\b(?:api[_-]?key|internal[_-]?token|access[_-]?token|auth[_-]?token|password|secret|token)=([^\s"'\\]{8,})`;
|
|
17644
|
-
var
|
|
17752
|
+
var KEY_VALUE_SECRET_PATTERN2 = new RegExp(
|
|
17645
17753
|
KEY_VALUE_SECRET_PATTERN_SOURCE,
|
|
17646
17754
|
"i"
|
|
17647
17755
|
);
|
|
17648
17756
|
function valueContainsKeyValueSecret(value) {
|
|
17649
|
-
|
|
17650
|
-
return
|
|
17757
|
+
KEY_VALUE_SECRET_PATTERN2.lastIndex = 0;
|
|
17758
|
+
return KEY_VALUE_SECRET_PATTERN2.test(value);
|
|
17651
17759
|
}
|
|
17652
17760
|
|
|
17653
17761
|
// packages/redact/src/index.ts
|
|
@@ -18116,15 +18224,14 @@ var REDACTION_POLICY_LIMITS = {
|
|
|
18116
18224
|
maxPatterns: 32,
|
|
18117
18225
|
maxPatternLength: 128,
|
|
18118
18226
|
maxPatternIdLength: 64,
|
|
18119
|
-
|
|
18227
|
+
/** Maximum policy file size before parse (bytes). */
|
|
18228
|
+
maxPolicyFileBytes: 64 * 1024
|
|
18120
18229
|
};
|
|
18121
|
-
var
|
|
18230
|
+
var ALLOWED_TOP_LEVEL = /* @__PURE__ */ new Set(["version", "extraKeys", "patterns"]);
|
|
18231
|
+
var ALLOWED_PATTERN_FIELDS = /* @__PURE__ */ new Set(["id", "type", "value", "severity"]);
|
|
18122
18232
|
function isRecord17(value) {
|
|
18123
18233
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
18124
18234
|
}
|
|
18125
|
-
function escapeRegExp(value) {
|
|
18126
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
18127
|
-
}
|
|
18128
18235
|
function rejectRemotePolicyPath(policyPath) {
|
|
18129
18236
|
const trimmed = policyPath.trim();
|
|
18130
18237
|
if (/^[a-z][a-z0-9+.-]*:/i.test(trimmed)) {
|
|
@@ -18153,43 +18260,23 @@ function validateExtraKey(key, index) {
|
|
|
18153
18260
|
}
|
|
18154
18261
|
return key;
|
|
18155
18262
|
}
|
|
18156
|
-
function
|
|
18157
|
-
|
|
18158
|
-
|
|
18159
|
-
|
|
18160
|
-
`${label} exceeds max length ${REDACTION_POLICY_LIMITS.maxPatternLength}.`
|
|
18161
|
-
);
|
|
18162
|
-
}
|
|
18163
|
-
if (!SAFE_TYPED_PATTERN.test(pattern)) {
|
|
18164
|
-
throw new Error(
|
|
18165
|
-
`${label} contains unsupported characters for bounded typed patterns.`
|
|
18166
|
-
);
|
|
18167
|
-
}
|
|
18168
|
-
if (/\(\?/.test(pattern) || /\\[1-9]/.test(pattern)) {
|
|
18169
|
-
throw new Error(
|
|
18170
|
-
`${label} rejects lookaround, backreferences, and nested quantifiers.`
|
|
18171
|
-
);
|
|
18172
|
-
}
|
|
18173
|
-
if (/\([^)]*[+*{][^)]*\)[+*{]/.test(pattern) || /\[[^\]]*[+*{][^\]]*\][+*{]/.test(pattern)) {
|
|
18174
|
-
throw new Error(`${label} rejects nested quantifiers.`);
|
|
18175
|
-
}
|
|
18176
|
-
if (/\.[*+]/.test(pattern) || /[*+]\{/.test(pattern)) {
|
|
18177
|
-
throw new Error(`${label} rejects unbounded .* / .+ style quantifiers.`);
|
|
18178
|
-
}
|
|
18179
|
-
for (const match of pattern.matchAll(/\{(\d+)(?:,(\d*))?\}/g)) {
|
|
18180
|
-
const min = Number(match[1]);
|
|
18181
|
-
const maxRaw = match[2];
|
|
18182
|
-
const max = maxRaw === void 0 || maxRaw === "" ? min : Number(maxRaw);
|
|
18183
|
-
if (!Number.isFinite(min) || !Number.isFinite(max) || min > REDACTION_POLICY_LIMITS.maxTypedQuantifier || max > REDACTION_POLICY_LIMITS.maxTypedQuantifier) {
|
|
18184
|
-
throw new Error(
|
|
18185
|
-
`${label} quantifiers must be <= ${REDACTION_POLICY_LIMITS.maxTypedQuantifier}.`
|
|
18186
|
-
);
|
|
18263
|
+
function rejectUnknownFields(record, allowed, label) {
|
|
18264
|
+
for (const key of Object.keys(record)) {
|
|
18265
|
+
if (!allowed.has(key)) {
|
|
18266
|
+
throw new Error(`${label} rejects unknown field "${key}".`);
|
|
18187
18267
|
}
|
|
18188
18268
|
}
|
|
18189
18269
|
}
|
|
18190
18270
|
function compilePatternDetector(input3, index) {
|
|
18191
18271
|
const label = `patterns[${index}]`;
|
|
18192
18272
|
if (!isRecord17(input3)) throw new Error(`${label} must be an object.`);
|
|
18273
|
+
const typeEarly = input3.type;
|
|
18274
|
+
if (typeEarly === "typed") {
|
|
18275
|
+
throw new Error(
|
|
18276
|
+
`${label}.type "typed" is no longer supported (removed in 6.29.1). Use type "literal" or "prefix" with a fixed value; arbitrary regex patterns are not accepted.`
|
|
18277
|
+
);
|
|
18278
|
+
}
|
|
18279
|
+
rejectUnknownFields(input3, ALLOWED_PATTERN_FIELDS, label);
|
|
18193
18280
|
const idRaw = input3.id;
|
|
18194
18281
|
if (typeof idRaw !== "string" || idRaw.trim() === "") {
|
|
18195
18282
|
throw new Error(`${label}.id must be a non-empty string.`);
|
|
@@ -18204,48 +18291,35 @@ function compilePatternDetector(input3, index) {
|
|
|
18204
18291
|
throw new Error(`${label}.id must be an identifier-like detector id.`);
|
|
18205
18292
|
}
|
|
18206
18293
|
const type = input3.type;
|
|
18207
|
-
if (type !== "literal" && type !== "prefix"
|
|
18208
|
-
throw new Error(`${label}.type must be literal
|
|
18294
|
+
if (type !== "literal" && type !== "prefix") {
|
|
18295
|
+
throw new Error(`${label}.type must be literal or prefix.`);
|
|
18296
|
+
}
|
|
18297
|
+
if (input3.pattern !== void 0) {
|
|
18298
|
+
throw new Error(
|
|
18299
|
+
`${label}.pattern is not accepted; use .value with type literal or prefix.`
|
|
18300
|
+
);
|
|
18209
18301
|
}
|
|
18210
18302
|
const severity = parseSeverity(input3.severity, label);
|
|
18211
|
-
|
|
18212
|
-
|
|
18213
|
-
if (typeof input3.pattern !== "string") {
|
|
18214
|
-
throw new Error(`${label}.pattern must be a string for typed patterns.`);
|
|
18215
|
-
}
|
|
18216
|
-
assertBoundedTypedPattern(input3.pattern, `${label}.pattern`);
|
|
18217
|
-
source = input3.pattern;
|
|
18218
|
-
} else {
|
|
18219
|
-
if (typeof input3.value !== "string") {
|
|
18220
|
-
throw new Error(`${label}.value must be a string for ${type} patterns.`);
|
|
18221
|
-
}
|
|
18222
|
-
if (input3.value.length === 0) {
|
|
18223
|
-
throw new Error(`${label}.value must be non-empty.`);
|
|
18224
|
-
}
|
|
18225
|
-
if (input3.value.length > REDACTION_POLICY_LIMITS.maxPatternLength) {
|
|
18226
|
-
throw new Error(
|
|
18227
|
-
`${label}.value exceeds max length ${REDACTION_POLICY_LIMITS.maxPatternLength}.`
|
|
18228
|
-
);
|
|
18229
|
-
}
|
|
18230
|
-
const escaped = escapeRegExp(input3.value);
|
|
18231
|
-
source = type === "prefix" ? `^${escaped}` : escaped;
|
|
18303
|
+
if (typeof input3.value !== "string") {
|
|
18304
|
+
throw new Error(`${label}.value must be a string for ${type} patterns.`);
|
|
18232
18305
|
}
|
|
18233
|
-
|
|
18234
|
-
|
|
18235
|
-
|
|
18236
|
-
|
|
18306
|
+
if (input3.value.length === 0) {
|
|
18307
|
+
throw new Error(`${label}.value must be non-empty.`);
|
|
18308
|
+
}
|
|
18309
|
+
if (input3.value.length > REDACTION_POLICY_LIMITS.maxPatternLength) {
|
|
18237
18310
|
throw new Error(
|
|
18238
|
-
`${label}
|
|
18311
|
+
`${label}.value exceeds max length ${REDACTION_POLICY_LIMITS.maxPatternLength}.`
|
|
18239
18312
|
);
|
|
18240
18313
|
}
|
|
18314
|
+
const needle = input3.value;
|
|
18315
|
+
const match = type === "prefix" ? (haystack) => haystack.startsWith(needle) : (haystack) => haystack.includes(needle);
|
|
18241
18316
|
return {
|
|
18242
18317
|
id: `policy.${id}`,
|
|
18243
18318
|
severity,
|
|
18244
18319
|
matchKind: "custom",
|
|
18245
18320
|
detect({ value }) {
|
|
18246
18321
|
if (typeof value !== "string") return [];
|
|
18247
|
-
|
|
18248
|
-
return regex.test(value) ? [{ action: "replace", severity, matchKind: "custom" }] : [];
|
|
18322
|
+
return match(value) ? [{ action: "replace", severity, matchKind: "custom" }] : [];
|
|
18249
18323
|
}
|
|
18250
18324
|
};
|
|
18251
18325
|
}
|
|
@@ -18253,6 +18327,7 @@ function compileRedactionPolicy(raw, policyPath) {
|
|
|
18253
18327
|
if (!isRecord17(raw)) {
|
|
18254
18328
|
throw new Error(`Redaction policy must be a JSON object (${policyPath}).`);
|
|
18255
18329
|
}
|
|
18330
|
+
rejectUnknownFields(raw, ALLOWED_TOP_LEVEL, "Redaction policy");
|
|
18256
18331
|
const diagnostics = [];
|
|
18257
18332
|
if (raw.version !== void 0 && raw.version !== 1) {
|
|
18258
18333
|
throw new Error(`Unsupported redaction policy version (supported: 1).`);
|
|
@@ -18316,14 +18391,38 @@ function compileRedactionPolicy(raw, policyPath) {
|
|
|
18316
18391
|
async function loadRedactionPolicy(policyPath) {
|
|
18317
18392
|
rejectRemotePolicyPath(policyPath);
|
|
18318
18393
|
const resolved = path33__default.default.resolve(policyPath);
|
|
18319
|
-
let
|
|
18394
|
+
let fileStat;
|
|
18395
|
+
try {
|
|
18396
|
+
fileStat = await promises.stat(resolved);
|
|
18397
|
+
} catch (error) {
|
|
18398
|
+
throw new Error(
|
|
18399
|
+
`Failed to read --policy file "${resolved}": ${error instanceof Error ? error.message : String(error)}`
|
|
18400
|
+
);
|
|
18401
|
+
}
|
|
18402
|
+
if (!fileStat.isFile()) {
|
|
18403
|
+
throw new Error(
|
|
18404
|
+
`--policy must be a regular local JSON file (not a directory or special file): "${resolved}".`
|
|
18405
|
+
);
|
|
18406
|
+
}
|
|
18407
|
+
if (fileStat.size > REDACTION_POLICY_LIMITS.maxPolicyFileBytes) {
|
|
18408
|
+
throw new Error(
|
|
18409
|
+
`--policy file exceeds max size ${REDACTION_POLICY_LIMITS.maxPolicyFileBytes} bytes.`
|
|
18410
|
+
);
|
|
18411
|
+
}
|
|
18412
|
+
let buffer;
|
|
18320
18413
|
try {
|
|
18321
|
-
|
|
18414
|
+
buffer = await promises.readFile(resolved);
|
|
18322
18415
|
} catch (error) {
|
|
18323
18416
|
throw new Error(
|
|
18324
18417
|
`Failed to read --policy file "${resolved}": ${error instanceof Error ? error.message : String(error)}`
|
|
18325
18418
|
);
|
|
18326
18419
|
}
|
|
18420
|
+
if (buffer.byteLength > REDACTION_POLICY_LIMITS.maxPolicyFileBytes) {
|
|
18421
|
+
throw new Error(
|
|
18422
|
+
`--policy file exceeds max size ${REDACTION_POLICY_LIMITS.maxPolicyFileBytes} bytes.`
|
|
18423
|
+
);
|
|
18424
|
+
}
|
|
18425
|
+
const text = buffer.toString("utf-8");
|
|
18327
18426
|
let parsed;
|
|
18328
18427
|
try {
|
|
18329
18428
|
parsed = JSON.parse(text);
|