@node9/proxy 1.14.0 → 1.14.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/dist/cli.js +64 -5
- package/dist/cli.mjs +64 -4
- package/dist/index.js +63 -4
- package/dist/index.mjs +63 -4
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3674,14 +3674,46 @@ var init_native = __esm({
|
|
|
3674
3674
|
});
|
|
3675
3675
|
|
|
3676
3676
|
// src/auth/cloud.ts
|
|
3677
|
-
function
|
|
3678
|
-
|
|
3677
|
+
function validateApiUrl(raw) {
|
|
3678
|
+
let u;
|
|
3679
|
+
try {
|
|
3680
|
+
u = new URL(raw);
|
|
3681
|
+
} catch {
|
|
3682
|
+
return null;
|
|
3683
|
+
}
|
|
3684
|
+
if (u.username || u.password) return null;
|
|
3685
|
+
if (u.protocol === "https:") return u;
|
|
3686
|
+
if (u.protocol === "http:") {
|
|
3687
|
+
const h = u.hostname;
|
|
3688
|
+
if (h === "127.0.0.1" || h === "localhost" || h === "::1" || h === "[::1]") return u;
|
|
3689
|
+
}
|
|
3690
|
+
return null;
|
|
3691
|
+
}
|
|
3692
|
+
function auditLocalAllow(toolName, args, checkedBy, creds, meta, dlpInfo, containsSensitiveArgs = false) {
|
|
3693
|
+
const validated = validateApiUrl(creds.apiUrl);
|
|
3694
|
+
if (!validated) {
|
|
3695
|
+
try {
|
|
3696
|
+
import_fs10.default.appendFileSync(
|
|
3697
|
+
HOOK_DEBUG_LOG,
|
|
3698
|
+
`[audit] refused to send: invalid apiUrl scheme/host (got "${String(creds.apiUrl).slice(0, 200)}")
|
|
3699
|
+
`
|
|
3700
|
+
);
|
|
3701
|
+
} catch {
|
|
3702
|
+
}
|
|
3703
|
+
return Promise.resolve();
|
|
3704
|
+
}
|
|
3705
|
+
const safeArgs = containsSensitiveArgs ? { tool: toolName, redacted: true } : args;
|
|
3706
|
+
const dlpSample = dlpInfo && typeof dlpInfo.redactedSample === "string" ? dlpInfo.redactedSample.slice(0, DLP_SAMPLE_MAX_LEN) : void 0;
|
|
3707
|
+
const dlpPattern = dlpInfo && typeof dlpInfo.pattern === "string" ? dlpInfo.pattern.slice(0, DLP_PATTERN_MAX_LEN) : void 0;
|
|
3708
|
+
const safeCheckedBy = KNOWN_CHECKED_BY.has(checkedBy) ? checkedBy : "unknown";
|
|
3709
|
+
return fetch(`${validated.toString().replace(/\/$/, "")}/audit`, {
|
|
3679
3710
|
method: "POST",
|
|
3680
3711
|
headers: { "Content-Type": "application/json", Authorization: `Bearer ${creds.apiKey}` },
|
|
3681
3712
|
body: JSON.stringify({
|
|
3682
3713
|
toolName,
|
|
3683
|
-
args,
|
|
3684
|
-
checkedBy,
|
|
3714
|
+
args: safeArgs,
|
|
3715
|
+
checkedBy: safeCheckedBy,
|
|
3716
|
+
...dlpInfo && { dlpPattern, dlpSample },
|
|
3685
3717
|
context: {
|
|
3686
3718
|
agent: meta?.agent,
|
|
3687
3719
|
mcpServer: meta?.mcpServer,
|
|
@@ -3815,7 +3847,7 @@ async function resolveNode9SaaS(requestId, creds, approved, decidedBy) {
|
|
|
3815
3847
|
);
|
|
3816
3848
|
}
|
|
3817
3849
|
}
|
|
3818
|
-
var import_fs10, import_os9, import_path13;
|
|
3850
|
+
var import_fs10, import_os9, import_path13, DLP_SAMPLE_MAX_LEN, DLP_PATTERN_MAX_LEN, KNOWN_CHECKED_BY;
|
|
3819
3851
|
var init_cloud = __esm({
|
|
3820
3852
|
"src/auth/cloud.ts"() {
|
|
3821
3853
|
"use strict";
|
|
@@ -3823,6 +3855,21 @@ var init_cloud = __esm({
|
|
|
3823
3855
|
import_os9 = __toESM(require("os"));
|
|
3824
3856
|
import_path13 = __toESM(require("path"));
|
|
3825
3857
|
init_audit();
|
|
3858
|
+
DLP_SAMPLE_MAX_LEN = 200;
|
|
3859
|
+
DLP_PATTERN_MAX_LEN = 100;
|
|
3860
|
+
KNOWN_CHECKED_BY = /* @__PURE__ */ new Set([
|
|
3861
|
+
"dlp-block",
|
|
3862
|
+
"observe-mode-dlp-would-block",
|
|
3863
|
+
"dlp-review-flagged",
|
|
3864
|
+
"loop-detected",
|
|
3865
|
+
"audit-mode",
|
|
3866
|
+
"local-policy",
|
|
3867
|
+
"smart-rule-block",
|
|
3868
|
+
"persistent",
|
|
3869
|
+
"trust",
|
|
3870
|
+
"observe-mode",
|
|
3871
|
+
"observe-mode-would-block"
|
|
3872
|
+
]);
|
|
3826
3873
|
}
|
|
3827
3874
|
});
|
|
3828
3875
|
|
|
@@ -4010,6 +4057,16 @@ async function _authorizeHeadlessCore(toolName, args, meta, options) {
|
|
|
4010
4057
|
meta,
|
|
4011
4058
|
true
|
|
4012
4059
|
);
|
|
4060
|
+
if (approvers.cloud && creds?.apiKey)
|
|
4061
|
+
auditLocalAllow(
|
|
4062
|
+
toolName,
|
|
4063
|
+
args,
|
|
4064
|
+
isObserveMode ? "observe-mode-dlp-would-block" : "dlp-block",
|
|
4065
|
+
creds,
|
|
4066
|
+
meta,
|
|
4067
|
+
{ pattern: dlpMatch.patternName, redactedSample: dlpMatch.redactedSample },
|
|
4068
|
+
true
|
|
4069
|
+
);
|
|
4013
4070
|
if (isWriteTool(toolName) && filePath) {
|
|
4014
4071
|
await notifyTaint(filePath, `DLP:${dlpMatch.patternName}`);
|
|
4015
4072
|
}
|
|
@@ -4078,6 +4135,8 @@ async function _authorizeHeadlessCore(toolName, args, meta, options) {
|
|
|
4078
4135
|
const reason = `It looks like you've called "${toolName}" ${loopResult.count} times with identical arguments in the last ${ld.windowSeconds}s. Are you stuck? Step back and reconsider your approach \u2014 what are you actually trying to accomplish, and is there a different way to get there?`;
|
|
4079
4136
|
if (!isManual)
|
|
4080
4137
|
appendLocalAudit(toolName, args, "deny", "loop-detected", meta, hashAuditArgs);
|
|
4138
|
+
if (approvers.cloud && creds?.apiKey)
|
|
4139
|
+
auditLocalAllow(toolName, args, "loop-detected", creds, meta, void 0, true);
|
|
4081
4140
|
return {
|
|
4082
4141
|
approved: false,
|
|
4083
4142
|
reason,
|
package/dist/cli.mjs
CHANGED
|
@@ -3655,14 +3655,46 @@ var init_native = __esm({
|
|
|
3655
3655
|
import fs10 from "fs";
|
|
3656
3656
|
import os9 from "os";
|
|
3657
3657
|
import path13 from "path";
|
|
3658
|
-
function
|
|
3659
|
-
|
|
3658
|
+
function validateApiUrl(raw) {
|
|
3659
|
+
let u;
|
|
3660
|
+
try {
|
|
3661
|
+
u = new URL(raw);
|
|
3662
|
+
} catch {
|
|
3663
|
+
return null;
|
|
3664
|
+
}
|
|
3665
|
+
if (u.username || u.password) return null;
|
|
3666
|
+
if (u.protocol === "https:") return u;
|
|
3667
|
+
if (u.protocol === "http:") {
|
|
3668
|
+
const h = u.hostname;
|
|
3669
|
+
if (h === "127.0.0.1" || h === "localhost" || h === "::1" || h === "[::1]") return u;
|
|
3670
|
+
}
|
|
3671
|
+
return null;
|
|
3672
|
+
}
|
|
3673
|
+
function auditLocalAllow(toolName, args, checkedBy, creds, meta, dlpInfo, containsSensitiveArgs = false) {
|
|
3674
|
+
const validated = validateApiUrl(creds.apiUrl);
|
|
3675
|
+
if (!validated) {
|
|
3676
|
+
try {
|
|
3677
|
+
fs10.appendFileSync(
|
|
3678
|
+
HOOK_DEBUG_LOG,
|
|
3679
|
+
`[audit] refused to send: invalid apiUrl scheme/host (got "${String(creds.apiUrl).slice(0, 200)}")
|
|
3680
|
+
`
|
|
3681
|
+
);
|
|
3682
|
+
} catch {
|
|
3683
|
+
}
|
|
3684
|
+
return Promise.resolve();
|
|
3685
|
+
}
|
|
3686
|
+
const safeArgs = containsSensitiveArgs ? { tool: toolName, redacted: true } : args;
|
|
3687
|
+
const dlpSample = dlpInfo && typeof dlpInfo.redactedSample === "string" ? dlpInfo.redactedSample.slice(0, DLP_SAMPLE_MAX_LEN) : void 0;
|
|
3688
|
+
const dlpPattern = dlpInfo && typeof dlpInfo.pattern === "string" ? dlpInfo.pattern.slice(0, DLP_PATTERN_MAX_LEN) : void 0;
|
|
3689
|
+
const safeCheckedBy = KNOWN_CHECKED_BY.has(checkedBy) ? checkedBy : "unknown";
|
|
3690
|
+
return fetch(`${validated.toString().replace(/\/$/, "")}/audit`, {
|
|
3660
3691
|
method: "POST",
|
|
3661
3692
|
headers: { "Content-Type": "application/json", Authorization: `Bearer ${creds.apiKey}` },
|
|
3662
3693
|
body: JSON.stringify({
|
|
3663
3694
|
toolName,
|
|
3664
|
-
args,
|
|
3665
|
-
checkedBy,
|
|
3695
|
+
args: safeArgs,
|
|
3696
|
+
checkedBy: safeCheckedBy,
|
|
3697
|
+
...dlpInfo && { dlpPattern, dlpSample },
|
|
3666
3698
|
context: {
|
|
3667
3699
|
agent: meta?.agent,
|
|
3668
3700
|
mcpServer: meta?.mcpServer,
|
|
@@ -3796,10 +3828,26 @@ async function resolveNode9SaaS(requestId, creds, approved, decidedBy) {
|
|
|
3796
3828
|
);
|
|
3797
3829
|
}
|
|
3798
3830
|
}
|
|
3831
|
+
var DLP_SAMPLE_MAX_LEN, DLP_PATTERN_MAX_LEN, KNOWN_CHECKED_BY;
|
|
3799
3832
|
var init_cloud = __esm({
|
|
3800
3833
|
"src/auth/cloud.ts"() {
|
|
3801
3834
|
"use strict";
|
|
3802
3835
|
init_audit();
|
|
3836
|
+
DLP_SAMPLE_MAX_LEN = 200;
|
|
3837
|
+
DLP_PATTERN_MAX_LEN = 100;
|
|
3838
|
+
KNOWN_CHECKED_BY = /* @__PURE__ */ new Set([
|
|
3839
|
+
"dlp-block",
|
|
3840
|
+
"observe-mode-dlp-would-block",
|
|
3841
|
+
"dlp-review-flagged",
|
|
3842
|
+
"loop-detected",
|
|
3843
|
+
"audit-mode",
|
|
3844
|
+
"local-policy",
|
|
3845
|
+
"smart-rule-block",
|
|
3846
|
+
"persistent",
|
|
3847
|
+
"trust",
|
|
3848
|
+
"observe-mode",
|
|
3849
|
+
"observe-mode-would-block"
|
|
3850
|
+
]);
|
|
3803
3851
|
}
|
|
3804
3852
|
});
|
|
3805
3853
|
|
|
@@ -3988,6 +4036,16 @@ async function _authorizeHeadlessCore(toolName, args, meta, options) {
|
|
|
3988
4036
|
meta,
|
|
3989
4037
|
true
|
|
3990
4038
|
);
|
|
4039
|
+
if (approvers.cloud && creds?.apiKey)
|
|
4040
|
+
auditLocalAllow(
|
|
4041
|
+
toolName,
|
|
4042
|
+
args,
|
|
4043
|
+
isObserveMode ? "observe-mode-dlp-would-block" : "dlp-block",
|
|
4044
|
+
creds,
|
|
4045
|
+
meta,
|
|
4046
|
+
{ pattern: dlpMatch.patternName, redactedSample: dlpMatch.redactedSample },
|
|
4047
|
+
true
|
|
4048
|
+
);
|
|
3991
4049
|
if (isWriteTool(toolName) && filePath) {
|
|
3992
4050
|
await notifyTaint(filePath, `DLP:${dlpMatch.patternName}`);
|
|
3993
4051
|
}
|
|
@@ -4056,6 +4114,8 @@ async function _authorizeHeadlessCore(toolName, args, meta, options) {
|
|
|
4056
4114
|
const reason = `It looks like you've called "${toolName}" ${loopResult.count} times with identical arguments in the last ${ld.windowSeconds}s. Are you stuck? Step back and reconsider your approach \u2014 what are you actually trying to accomplish, and is there a different way to get there?`;
|
|
4057
4115
|
if (!isManual)
|
|
4058
4116
|
appendLocalAudit(toolName, args, "deny", "loop-detected", meta, hashAuditArgs);
|
|
4117
|
+
if (approvers.cloud && creds?.apiKey)
|
|
4118
|
+
auditLocalAllow(toolName, args, "loop-detected", creds, meta, void 0, true);
|
|
4059
4119
|
return {
|
|
4060
4120
|
approved: false,
|
|
4061
4121
|
reason,
|
package/dist/index.js
CHANGED
|
@@ -3102,14 +3102,61 @@ var import_fs9 = __toESM(require("fs"));
|
|
|
3102
3102
|
var import_os8 = __toESM(require("os"));
|
|
3103
3103
|
var import_path13 = __toESM(require("path"));
|
|
3104
3104
|
init_audit();
|
|
3105
|
-
|
|
3106
|
-
|
|
3105
|
+
var DLP_SAMPLE_MAX_LEN = 200;
|
|
3106
|
+
var DLP_PATTERN_MAX_LEN = 100;
|
|
3107
|
+
var KNOWN_CHECKED_BY = /* @__PURE__ */ new Set([
|
|
3108
|
+
"dlp-block",
|
|
3109
|
+
"observe-mode-dlp-would-block",
|
|
3110
|
+
"dlp-review-flagged",
|
|
3111
|
+
"loop-detected",
|
|
3112
|
+
"audit-mode",
|
|
3113
|
+
"local-policy",
|
|
3114
|
+
"smart-rule-block",
|
|
3115
|
+
"persistent",
|
|
3116
|
+
"trust",
|
|
3117
|
+
"observe-mode",
|
|
3118
|
+
"observe-mode-would-block"
|
|
3119
|
+
]);
|
|
3120
|
+
function validateApiUrl(raw) {
|
|
3121
|
+
let u;
|
|
3122
|
+
try {
|
|
3123
|
+
u = new URL(raw);
|
|
3124
|
+
} catch {
|
|
3125
|
+
return null;
|
|
3126
|
+
}
|
|
3127
|
+
if (u.username || u.password) return null;
|
|
3128
|
+
if (u.protocol === "https:") return u;
|
|
3129
|
+
if (u.protocol === "http:") {
|
|
3130
|
+
const h = u.hostname;
|
|
3131
|
+
if (h === "127.0.0.1" || h === "localhost" || h === "::1" || h === "[::1]") return u;
|
|
3132
|
+
}
|
|
3133
|
+
return null;
|
|
3134
|
+
}
|
|
3135
|
+
function auditLocalAllow(toolName, args, checkedBy, creds, meta, dlpInfo, containsSensitiveArgs = false) {
|
|
3136
|
+
const validated = validateApiUrl(creds.apiUrl);
|
|
3137
|
+
if (!validated) {
|
|
3138
|
+
try {
|
|
3139
|
+
import_fs9.default.appendFileSync(
|
|
3140
|
+
HOOK_DEBUG_LOG,
|
|
3141
|
+
`[audit] refused to send: invalid apiUrl scheme/host (got "${String(creds.apiUrl).slice(0, 200)}")
|
|
3142
|
+
`
|
|
3143
|
+
);
|
|
3144
|
+
} catch {
|
|
3145
|
+
}
|
|
3146
|
+
return Promise.resolve();
|
|
3147
|
+
}
|
|
3148
|
+
const safeArgs = containsSensitiveArgs ? { tool: toolName, redacted: true } : args;
|
|
3149
|
+
const dlpSample = dlpInfo && typeof dlpInfo.redactedSample === "string" ? dlpInfo.redactedSample.slice(0, DLP_SAMPLE_MAX_LEN) : void 0;
|
|
3150
|
+
const dlpPattern = dlpInfo && typeof dlpInfo.pattern === "string" ? dlpInfo.pattern.slice(0, DLP_PATTERN_MAX_LEN) : void 0;
|
|
3151
|
+
const safeCheckedBy = KNOWN_CHECKED_BY.has(checkedBy) ? checkedBy : "unknown";
|
|
3152
|
+
return fetch(`${validated.toString().replace(/\/$/, "")}/audit`, {
|
|
3107
3153
|
method: "POST",
|
|
3108
3154
|
headers: { "Content-Type": "application/json", Authorization: `Bearer ${creds.apiKey}` },
|
|
3109
3155
|
body: JSON.stringify({
|
|
3110
3156
|
toolName,
|
|
3111
|
-
args,
|
|
3112
|
-
checkedBy,
|
|
3157
|
+
args: safeArgs,
|
|
3158
|
+
checkedBy: safeCheckedBy,
|
|
3159
|
+
...dlpInfo && { dlpPattern, dlpSample },
|
|
3113
3160
|
context: {
|
|
3114
3161
|
agent: meta?.agent,
|
|
3115
3162
|
mcpServer: meta?.mcpServer,
|
|
@@ -3433,6 +3480,16 @@ async function _authorizeHeadlessCore(toolName, args, meta, options) {
|
|
|
3433
3480
|
meta,
|
|
3434
3481
|
true
|
|
3435
3482
|
);
|
|
3483
|
+
if (approvers.cloud && creds?.apiKey)
|
|
3484
|
+
auditLocalAllow(
|
|
3485
|
+
toolName,
|
|
3486
|
+
args,
|
|
3487
|
+
isObserveMode ? "observe-mode-dlp-would-block" : "dlp-block",
|
|
3488
|
+
creds,
|
|
3489
|
+
meta,
|
|
3490
|
+
{ pattern: dlpMatch.patternName, redactedSample: dlpMatch.redactedSample },
|
|
3491
|
+
true
|
|
3492
|
+
);
|
|
3436
3493
|
if (isWriteTool(toolName) && filePath) {
|
|
3437
3494
|
await notifyTaint(filePath, `DLP:${dlpMatch.patternName}`);
|
|
3438
3495
|
}
|
|
@@ -3501,6 +3558,8 @@ async function _authorizeHeadlessCore(toolName, args, meta, options) {
|
|
|
3501
3558
|
const reason = `It looks like you've called "${toolName}" ${loopResult.count} times with identical arguments in the last ${ld.windowSeconds}s. Are you stuck? Step back and reconsider your approach \u2014 what are you actually trying to accomplish, and is there a different way to get there?`;
|
|
3502
3559
|
if (!isManual)
|
|
3503
3560
|
appendLocalAudit(toolName, args, "deny", "loop-detected", meta, hashAuditArgs);
|
|
3561
|
+
if (approvers.cloud && creds?.apiKey)
|
|
3562
|
+
auditLocalAllow(toolName, args, "loop-detected", creds, meta, void 0, true);
|
|
3504
3563
|
return {
|
|
3505
3564
|
approved: false,
|
|
3506
3565
|
reason,
|
package/dist/index.mjs
CHANGED
|
@@ -3072,14 +3072,61 @@ init_audit();
|
|
|
3072
3072
|
import fs9 from "fs";
|
|
3073
3073
|
import os8 from "os";
|
|
3074
3074
|
import path13 from "path";
|
|
3075
|
-
|
|
3076
|
-
|
|
3075
|
+
var DLP_SAMPLE_MAX_LEN = 200;
|
|
3076
|
+
var DLP_PATTERN_MAX_LEN = 100;
|
|
3077
|
+
var KNOWN_CHECKED_BY = /* @__PURE__ */ new Set([
|
|
3078
|
+
"dlp-block",
|
|
3079
|
+
"observe-mode-dlp-would-block",
|
|
3080
|
+
"dlp-review-flagged",
|
|
3081
|
+
"loop-detected",
|
|
3082
|
+
"audit-mode",
|
|
3083
|
+
"local-policy",
|
|
3084
|
+
"smart-rule-block",
|
|
3085
|
+
"persistent",
|
|
3086
|
+
"trust",
|
|
3087
|
+
"observe-mode",
|
|
3088
|
+
"observe-mode-would-block"
|
|
3089
|
+
]);
|
|
3090
|
+
function validateApiUrl(raw) {
|
|
3091
|
+
let u;
|
|
3092
|
+
try {
|
|
3093
|
+
u = new URL(raw);
|
|
3094
|
+
} catch {
|
|
3095
|
+
return null;
|
|
3096
|
+
}
|
|
3097
|
+
if (u.username || u.password) return null;
|
|
3098
|
+
if (u.protocol === "https:") return u;
|
|
3099
|
+
if (u.protocol === "http:") {
|
|
3100
|
+
const h = u.hostname;
|
|
3101
|
+
if (h === "127.0.0.1" || h === "localhost" || h === "::1" || h === "[::1]") return u;
|
|
3102
|
+
}
|
|
3103
|
+
return null;
|
|
3104
|
+
}
|
|
3105
|
+
function auditLocalAllow(toolName, args, checkedBy, creds, meta, dlpInfo, containsSensitiveArgs = false) {
|
|
3106
|
+
const validated = validateApiUrl(creds.apiUrl);
|
|
3107
|
+
if (!validated) {
|
|
3108
|
+
try {
|
|
3109
|
+
fs9.appendFileSync(
|
|
3110
|
+
HOOK_DEBUG_LOG,
|
|
3111
|
+
`[audit] refused to send: invalid apiUrl scheme/host (got "${String(creds.apiUrl).slice(0, 200)}")
|
|
3112
|
+
`
|
|
3113
|
+
);
|
|
3114
|
+
} catch {
|
|
3115
|
+
}
|
|
3116
|
+
return Promise.resolve();
|
|
3117
|
+
}
|
|
3118
|
+
const safeArgs = containsSensitiveArgs ? { tool: toolName, redacted: true } : args;
|
|
3119
|
+
const dlpSample = dlpInfo && typeof dlpInfo.redactedSample === "string" ? dlpInfo.redactedSample.slice(0, DLP_SAMPLE_MAX_LEN) : void 0;
|
|
3120
|
+
const dlpPattern = dlpInfo && typeof dlpInfo.pattern === "string" ? dlpInfo.pattern.slice(0, DLP_PATTERN_MAX_LEN) : void 0;
|
|
3121
|
+
const safeCheckedBy = KNOWN_CHECKED_BY.has(checkedBy) ? checkedBy : "unknown";
|
|
3122
|
+
return fetch(`${validated.toString().replace(/\/$/, "")}/audit`, {
|
|
3077
3123
|
method: "POST",
|
|
3078
3124
|
headers: { "Content-Type": "application/json", Authorization: `Bearer ${creds.apiKey}` },
|
|
3079
3125
|
body: JSON.stringify({
|
|
3080
3126
|
toolName,
|
|
3081
|
-
args,
|
|
3082
|
-
checkedBy,
|
|
3127
|
+
args: safeArgs,
|
|
3128
|
+
checkedBy: safeCheckedBy,
|
|
3129
|
+
...dlpInfo && { dlpPattern, dlpSample },
|
|
3083
3130
|
context: {
|
|
3084
3131
|
agent: meta?.agent,
|
|
3085
3132
|
mcpServer: meta?.mcpServer,
|
|
@@ -3403,6 +3450,16 @@ async function _authorizeHeadlessCore(toolName, args, meta, options) {
|
|
|
3403
3450
|
meta,
|
|
3404
3451
|
true
|
|
3405
3452
|
);
|
|
3453
|
+
if (approvers.cloud && creds?.apiKey)
|
|
3454
|
+
auditLocalAllow(
|
|
3455
|
+
toolName,
|
|
3456
|
+
args,
|
|
3457
|
+
isObserveMode ? "observe-mode-dlp-would-block" : "dlp-block",
|
|
3458
|
+
creds,
|
|
3459
|
+
meta,
|
|
3460
|
+
{ pattern: dlpMatch.patternName, redactedSample: dlpMatch.redactedSample },
|
|
3461
|
+
true
|
|
3462
|
+
);
|
|
3406
3463
|
if (isWriteTool(toolName) && filePath) {
|
|
3407
3464
|
await notifyTaint(filePath, `DLP:${dlpMatch.patternName}`);
|
|
3408
3465
|
}
|
|
@@ -3471,6 +3528,8 @@ async function _authorizeHeadlessCore(toolName, args, meta, options) {
|
|
|
3471
3528
|
const reason = `It looks like you've called "${toolName}" ${loopResult.count} times with identical arguments in the last ${ld.windowSeconds}s. Are you stuck? Step back and reconsider your approach \u2014 what are you actually trying to accomplish, and is there a different way to get there?`;
|
|
3472
3529
|
if (!isManual)
|
|
3473
3530
|
appendLocalAudit(toolName, args, "deny", "loop-detected", meta, hashAuditArgs);
|
|
3531
|
+
if (approvers.cloud && creds?.apiKey)
|
|
3532
|
+
auditLocalAllow(toolName, args, "loop-detected", creds, meta, void 0, true);
|
|
3474
3533
|
return {
|
|
3475
3534
|
approved: false,
|
|
3476
3535
|
reason,
|