@node9/proxy 1.64.0 → 1.65.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/cli.js +1063 -791
- package/dist/cli.mjs +1043 -771
- package/dist/dashboard.mjs +2 -1
- package/dist/index.js +24 -9
- package/dist/index.mjs +24 -9
- package/package.json +1 -1
package/dist/dashboard.mjs
CHANGED
|
@@ -2459,7 +2459,7 @@ var init_trusted_hosts = __esm({
|
|
|
2459
2459
|
});
|
|
2460
2460
|
|
|
2461
2461
|
// src/config/index.ts
|
|
2462
|
-
var DANGEROUS_WORDS, DEFAULT_CONFIG;
|
|
2462
|
+
var DANGEROUS_WORDS, DEFAULT_CONFIG, CACHE_LOG_REARM_MS;
|
|
2463
2463
|
var init_config = __esm({
|
|
2464
2464
|
"src/config/index.ts"() {
|
|
2465
2465
|
"use strict";
|
|
@@ -2684,6 +2684,7 @@ var init_config = __esm({
|
|
|
2684
2684
|
},
|
|
2685
2685
|
environments: {}
|
|
2686
2686
|
};
|
|
2687
|
+
CACHE_LOG_REARM_MS = 5 * 60 * 1e3;
|
|
2687
2688
|
}
|
|
2688
2689
|
});
|
|
2689
2690
|
|
package/dist/index.js
CHANGED
|
@@ -4070,9 +4070,9 @@ function getActiveEnvironment(config) {
|
|
|
4070
4070
|
const env = config.settings.environment || process.env.NODE_ENV || "development";
|
|
4071
4071
|
return config.environments[env] ?? null;
|
|
4072
4072
|
}
|
|
4073
|
-
var cacheReadFailureLogged = false;
|
|
4074
4073
|
function readRulesCacheResilient(cacheFile) {
|
|
4075
4074
|
let existed = false;
|
|
4075
|
+
let sawReadError = false;
|
|
4076
4076
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
4077
4077
|
let content;
|
|
4078
4078
|
try {
|
|
@@ -4080,30 +4080,42 @@ function readRulesCacheResilient(cacheFile) {
|
|
|
4080
4080
|
existed = true;
|
|
4081
4081
|
} catch (err) {
|
|
4082
4082
|
if (err.code === "ENOENT") return {};
|
|
4083
|
+
sawReadError = true;
|
|
4083
4084
|
continue;
|
|
4084
4085
|
}
|
|
4085
4086
|
try {
|
|
4086
|
-
|
|
4087
|
+
const parsed = JSON.parse(content);
|
|
4088
|
+
lastParsedRulesCache = parsed;
|
|
4089
|
+
return parsed;
|
|
4087
4090
|
} catch {
|
|
4088
4091
|
}
|
|
4089
4092
|
}
|
|
4090
|
-
if (existed) {
|
|
4093
|
+
if (existed || sawReadError) {
|
|
4091
4094
|
const backup = import_path4.default.join(import_path4.default.dirname(cacheFile), "rules-cache.last-good.json");
|
|
4092
4095
|
if (backup !== cacheFile) {
|
|
4093
4096
|
try {
|
|
4094
4097
|
const raw = JSON.parse(import_fs4.default.readFileSync(backup, "utf-8"));
|
|
4095
4098
|
logCacheReadIssue(cacheFile, "RULES_CACHE_CORRUPT_USED_BACKUP");
|
|
4099
|
+
lastParsedRulesCache = raw;
|
|
4096
4100
|
return raw;
|
|
4097
4101
|
} catch {
|
|
4098
4102
|
}
|
|
4099
4103
|
}
|
|
4104
|
+
if (lastParsedRulesCache) {
|
|
4105
|
+
logCacheReadIssue(cacheFile, "RULES_CACHE_USED_MEMORY");
|
|
4106
|
+
return lastParsedRulesCache;
|
|
4107
|
+
}
|
|
4100
4108
|
logCacheReadIssue(cacheFile, "RULES_CACHE_UNREADABLE");
|
|
4101
4109
|
}
|
|
4102
4110
|
return {};
|
|
4103
4111
|
}
|
|
4112
|
+
var lastParsedRulesCache = null;
|
|
4113
|
+
var CACHE_LOG_REARM_MS = 5 * 60 * 1e3;
|
|
4114
|
+
var cacheReadLastLoggedAt = 0;
|
|
4104
4115
|
function logCacheReadIssue(cacheFile, kind) {
|
|
4105
|
-
|
|
4106
|
-
|
|
4116
|
+
const now = Date.now();
|
|
4117
|
+
if (now - cacheReadLastLoggedAt < CACHE_LOG_REARM_MS) return;
|
|
4118
|
+
cacheReadLastLoggedAt = now;
|
|
4107
4119
|
try {
|
|
4108
4120
|
import_fs4.default.appendFileSync(
|
|
4109
4121
|
import_path4.default.join(import_os4.default.homedir(), ".node9", "hook-debug.log"),
|
|
@@ -5616,6 +5628,7 @@ async function _authorizeHeadlessCore(toolName, args, metaArg, options) {
|
|
|
5616
5628
|
let riskMetadata;
|
|
5617
5629
|
let statefulRecoveryCommand;
|
|
5618
5630
|
let localSmartRuleMatched = false;
|
|
5631
|
+
let hardBlockDowngraded = false;
|
|
5619
5632
|
let taintWarning = null;
|
|
5620
5633
|
if (isNetworkTool(toolName, args)) {
|
|
5621
5634
|
const filePaths = extractFilePaths(toolName, args);
|
|
@@ -5857,6 +5870,7 @@ async function _authorizeHeadlessCore(toolName, args, metaArg, options) {
|
|
|
5857
5870
|
return { approved: true, checkedBy: "local-policy" };
|
|
5858
5871
|
}
|
|
5859
5872
|
if (policyResult.decision === "block") {
|
|
5873
|
+
hardBlockDowngraded = true;
|
|
5860
5874
|
const daemonUp = isDaemonRunning();
|
|
5861
5875
|
let humanApproverReachable = false;
|
|
5862
5876
|
if (!policyResult.dependsOnStatePredicates?.length && daemonUp && !isTestEnv2) {
|
|
@@ -5930,7 +5944,8 @@ async function _authorizeHeadlessCore(toolName, args, metaArg, options) {
|
|
|
5930
5944
|
explainableLabel = policyResult.blockedByLabel || "Local Config";
|
|
5931
5945
|
policyMatchedField = policyResult.matchedField;
|
|
5932
5946
|
policyMatchedWord = policyResult.matchedWord;
|
|
5933
|
-
if (policyResult.ruleName || policyResult.tier === 7
|
|
5947
|
+
if (policyResult.ruleName || policyResult.tier === 7 || hardBlockDowngraded)
|
|
5948
|
+
localSmartRuleMatched = true;
|
|
5934
5949
|
if (policyResult.ruleDescription) policyRuleDescription = policyResult.ruleDescription;
|
|
5935
5950
|
else if (policyResult.reason) policyRuleDescription = policyResult.reason;
|
|
5936
5951
|
riskMetadata = computeRiskMetadata(
|
|
@@ -5942,7 +5957,7 @@ async function _authorizeHeadlessCore(toolName, args, metaArg, options) {
|
|
|
5942
5957
|
policyResult.ruleName
|
|
5943
5958
|
);
|
|
5944
5959
|
if (policyRuleDescription) riskMetadata.ruleDescription = policyRuleDescription.slice(0, 200);
|
|
5945
|
-
const persistent = policyResult.ruleName || policyResult.tier === 7 ? null : getPersistentDecision(toolName);
|
|
5960
|
+
const persistent = policyResult.ruleName || policyResult.tier === 7 || hardBlockDowngraded ? null : getPersistentDecision(toolName);
|
|
5946
5961
|
if (persistent === "allow" && !appPermReview) {
|
|
5947
5962
|
if (!isManual) appendLocalAudit(toolName, args, "allow", "persistent", meta, hashAuditArgs);
|
|
5948
5963
|
return { approved: true, checkedBy: "persistent" };
|
|
@@ -5975,7 +5990,7 @@ async function _authorizeHeadlessCore(toolName, args, metaArg, options) {
|
|
|
5975
5990
|
return { approved: true };
|
|
5976
5991
|
}
|
|
5977
5992
|
}
|
|
5978
|
-
if (!taintWarning && !appPermReview && getActiveTrustSession(toolName, args)) {
|
|
5993
|
+
if (!taintWarning && !appPermReview && !hardBlockDowngraded && getActiveTrustSession(toolName, args)) {
|
|
5979
5994
|
if (!isManual) appendLocalAudit(toolName, args, "allow", "trust", meta, hashAuditArgs);
|
|
5980
5995
|
return { approved: true, checkedBy: "trust" };
|
|
5981
5996
|
}
|
|
@@ -6039,7 +6054,7 @@ ${appPermReview}`
|
|
|
6039
6054
|
forceReview
|
|
6040
6055
|
);
|
|
6041
6056
|
if (!initResult.pending) {
|
|
6042
|
-
if (initResult.shadowMode && !appPermReview) {
|
|
6057
|
+
if (initResult.shadowMode && !localSmartRuleMatched && !options?.localSmartRuleMatched && !appPermReview) {
|
|
6043
6058
|
return { approved: true, checkedBy: "cloud" };
|
|
6044
6059
|
}
|
|
6045
6060
|
if (!localSmartRuleMatched && !options?.localSmartRuleMatched && !appPermReview) {
|
package/dist/index.mjs
CHANGED
|
@@ -4040,9 +4040,9 @@ function getActiveEnvironment(config) {
|
|
|
4040
4040
|
const env = config.settings.environment || process.env.NODE_ENV || "development";
|
|
4041
4041
|
return config.environments[env] ?? null;
|
|
4042
4042
|
}
|
|
4043
|
-
var cacheReadFailureLogged = false;
|
|
4044
4043
|
function readRulesCacheResilient(cacheFile) {
|
|
4045
4044
|
let existed = false;
|
|
4045
|
+
let sawReadError = false;
|
|
4046
4046
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
4047
4047
|
let content;
|
|
4048
4048
|
try {
|
|
@@ -4050,30 +4050,42 @@ function readRulesCacheResilient(cacheFile) {
|
|
|
4050
4050
|
existed = true;
|
|
4051
4051
|
} catch (err) {
|
|
4052
4052
|
if (err.code === "ENOENT") return {};
|
|
4053
|
+
sawReadError = true;
|
|
4053
4054
|
continue;
|
|
4054
4055
|
}
|
|
4055
4056
|
try {
|
|
4056
|
-
|
|
4057
|
+
const parsed = JSON.parse(content);
|
|
4058
|
+
lastParsedRulesCache = parsed;
|
|
4059
|
+
return parsed;
|
|
4057
4060
|
} catch {
|
|
4058
4061
|
}
|
|
4059
4062
|
}
|
|
4060
|
-
if (existed) {
|
|
4063
|
+
if (existed || sawReadError) {
|
|
4061
4064
|
const backup = path4.join(path4.dirname(cacheFile), "rules-cache.last-good.json");
|
|
4062
4065
|
if (backup !== cacheFile) {
|
|
4063
4066
|
try {
|
|
4064
4067
|
const raw = JSON.parse(fs4.readFileSync(backup, "utf-8"));
|
|
4065
4068
|
logCacheReadIssue(cacheFile, "RULES_CACHE_CORRUPT_USED_BACKUP");
|
|
4069
|
+
lastParsedRulesCache = raw;
|
|
4066
4070
|
return raw;
|
|
4067
4071
|
} catch {
|
|
4068
4072
|
}
|
|
4069
4073
|
}
|
|
4074
|
+
if (lastParsedRulesCache) {
|
|
4075
|
+
logCacheReadIssue(cacheFile, "RULES_CACHE_USED_MEMORY");
|
|
4076
|
+
return lastParsedRulesCache;
|
|
4077
|
+
}
|
|
4070
4078
|
logCacheReadIssue(cacheFile, "RULES_CACHE_UNREADABLE");
|
|
4071
4079
|
}
|
|
4072
4080
|
return {};
|
|
4073
4081
|
}
|
|
4082
|
+
var lastParsedRulesCache = null;
|
|
4083
|
+
var CACHE_LOG_REARM_MS = 5 * 60 * 1e3;
|
|
4084
|
+
var cacheReadLastLoggedAt = 0;
|
|
4074
4085
|
function logCacheReadIssue(cacheFile, kind) {
|
|
4075
|
-
|
|
4076
|
-
|
|
4086
|
+
const now = Date.now();
|
|
4087
|
+
if (now - cacheReadLastLoggedAt < CACHE_LOG_REARM_MS) return;
|
|
4088
|
+
cacheReadLastLoggedAt = now;
|
|
4077
4089
|
try {
|
|
4078
4090
|
fs4.appendFileSync(
|
|
4079
4091
|
path4.join(os4.homedir(), ".node9", "hook-debug.log"),
|
|
@@ -5586,6 +5598,7 @@ async function _authorizeHeadlessCore(toolName, args, metaArg, options) {
|
|
|
5586
5598
|
let riskMetadata;
|
|
5587
5599
|
let statefulRecoveryCommand;
|
|
5588
5600
|
let localSmartRuleMatched = false;
|
|
5601
|
+
let hardBlockDowngraded = false;
|
|
5589
5602
|
let taintWarning = null;
|
|
5590
5603
|
if (isNetworkTool(toolName, args)) {
|
|
5591
5604
|
const filePaths = extractFilePaths(toolName, args);
|
|
@@ -5827,6 +5840,7 @@ async function _authorizeHeadlessCore(toolName, args, metaArg, options) {
|
|
|
5827
5840
|
return { approved: true, checkedBy: "local-policy" };
|
|
5828
5841
|
}
|
|
5829
5842
|
if (policyResult.decision === "block") {
|
|
5843
|
+
hardBlockDowngraded = true;
|
|
5830
5844
|
const daemonUp = isDaemonRunning();
|
|
5831
5845
|
let humanApproverReachable = false;
|
|
5832
5846
|
if (!policyResult.dependsOnStatePredicates?.length && daemonUp && !isTestEnv2) {
|
|
@@ -5900,7 +5914,8 @@ async function _authorizeHeadlessCore(toolName, args, metaArg, options) {
|
|
|
5900
5914
|
explainableLabel = policyResult.blockedByLabel || "Local Config";
|
|
5901
5915
|
policyMatchedField = policyResult.matchedField;
|
|
5902
5916
|
policyMatchedWord = policyResult.matchedWord;
|
|
5903
|
-
if (policyResult.ruleName || policyResult.tier === 7
|
|
5917
|
+
if (policyResult.ruleName || policyResult.tier === 7 || hardBlockDowngraded)
|
|
5918
|
+
localSmartRuleMatched = true;
|
|
5904
5919
|
if (policyResult.ruleDescription) policyRuleDescription = policyResult.ruleDescription;
|
|
5905
5920
|
else if (policyResult.reason) policyRuleDescription = policyResult.reason;
|
|
5906
5921
|
riskMetadata = computeRiskMetadata(
|
|
@@ -5912,7 +5927,7 @@ async function _authorizeHeadlessCore(toolName, args, metaArg, options) {
|
|
|
5912
5927
|
policyResult.ruleName
|
|
5913
5928
|
);
|
|
5914
5929
|
if (policyRuleDescription) riskMetadata.ruleDescription = policyRuleDescription.slice(0, 200);
|
|
5915
|
-
const persistent = policyResult.ruleName || policyResult.tier === 7 ? null : getPersistentDecision(toolName);
|
|
5930
|
+
const persistent = policyResult.ruleName || policyResult.tier === 7 || hardBlockDowngraded ? null : getPersistentDecision(toolName);
|
|
5916
5931
|
if (persistent === "allow" && !appPermReview) {
|
|
5917
5932
|
if (!isManual) appendLocalAudit(toolName, args, "allow", "persistent", meta, hashAuditArgs);
|
|
5918
5933
|
return { approved: true, checkedBy: "persistent" };
|
|
@@ -5945,7 +5960,7 @@ async function _authorizeHeadlessCore(toolName, args, metaArg, options) {
|
|
|
5945
5960
|
return { approved: true };
|
|
5946
5961
|
}
|
|
5947
5962
|
}
|
|
5948
|
-
if (!taintWarning && !appPermReview && getActiveTrustSession(toolName, args)) {
|
|
5963
|
+
if (!taintWarning && !appPermReview && !hardBlockDowngraded && getActiveTrustSession(toolName, args)) {
|
|
5949
5964
|
if (!isManual) appendLocalAudit(toolName, args, "allow", "trust", meta, hashAuditArgs);
|
|
5950
5965
|
return { approved: true, checkedBy: "trust" };
|
|
5951
5966
|
}
|
|
@@ -6009,7 +6024,7 @@ ${appPermReview}`
|
|
|
6009
6024
|
forceReview
|
|
6010
6025
|
);
|
|
6011
6026
|
if (!initResult.pending) {
|
|
6012
|
-
if (initResult.shadowMode && !appPermReview) {
|
|
6027
|
+
if (initResult.shadowMode && !localSmartRuleMatched && !options?.localSmartRuleMatched && !appPermReview) {
|
|
6013
6028
|
return { approved: true, checkedBy: "cloud" };
|
|
6014
6029
|
}
|
|
6015
6030
|
if (!localSmartRuleMatched && !options?.localSmartRuleMatched && !appPermReview) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@node9/proxy",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.65.0",
|
|
4
4
|
"description": "The Sudo Command for AI Agents. Execution Security for Claude Code, Codex, Gemini, Cursor, Opencode, Pi, and any MCP server.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|