mirror of https://github.com/openclaw/openclaw.git
fix(gateway): surface env override keys in exec approvals
This commit is contained in:
parent
38a6415a70
commit
57204b4fa9
|
|
@ -113,6 +113,7 @@ Docs: https://docs.openclaw.ai
|
|||
- Agents/compaction: rerun transcript repair after `session.compact()` so orphaned `tool_result` blocks cannot survive compaction and break later Anthropic requests. (#16095) thanks @claw-sylphx.
|
||||
- Agents/compaction: trigger overflow recovery from the tool-result guard once post-compaction context still exceeds the safe threshold, so long tool loops compact before the next model call hard-fails. (#29371) thanks @keshav55.
|
||||
- macOS/exec approvals: harden exec-host request HMAC verification to use a timing-safe compare and keep malformed or truncated signatures fail-closed in focused IPC auth coverage.
|
||||
- Gateway/exec approvals: surface requested env override keys in gateway-host approval prompts so operators can review surviving env context without inheriting noisy base host env.
|
||||
|
||||
## 2026.3.13
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ export type ProcessGatewayAllowlistParams = {
|
|||
command: string;
|
||||
workdir: string;
|
||||
env: Record<string, string>;
|
||||
requestedEnv?: Record<string, string>;
|
||||
pty: boolean;
|
||||
timeoutSec?: number;
|
||||
defaultTimeoutSec: number;
|
||||
|
|
@ -152,6 +153,7 @@ export async function processGatewayAllowlist(
|
|||
await registerExecApprovalRequestForHostOrThrow({
|
||||
approvalId,
|
||||
command: params.command,
|
||||
env: params.requestedEnv,
|
||||
workdir: params.workdir,
|
||||
host: "gateway",
|
||||
security: hostSecurity,
|
||||
|
|
|
|||
|
|
@ -429,6 +429,7 @@ export function createExecTool(
|
|||
command: params.command,
|
||||
workdir,
|
||||
env,
|
||||
requestedEnv: params.env,
|
||||
pty: params.pty === true && !sandbox,
|
||||
timeoutSec: params.timeout,
|
||||
defaultTimeoutSec,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,10 @@ import {
|
|||
DEFAULT_EXEC_APPROVAL_TIMEOUT_MS,
|
||||
type ExecApprovalDecision,
|
||||
} from "../../infra/exec-approvals.js";
|
||||
import { buildSystemRunApprovalBinding } from "../../infra/system-run-approval-binding.js";
|
||||
import {
|
||||
buildSystemRunApprovalBinding,
|
||||
buildSystemRunApprovalEnvBinding,
|
||||
} from "../../infra/system-run-approval-binding.js";
|
||||
import { resolveSystemRunApprovalRequestContext } from "../../infra/system-run-approval-context.js";
|
||||
import type { ExecApprovalManager } from "../exec-approval-manager.js";
|
||||
import {
|
||||
|
|
@ -107,6 +110,7 @@ export function createExecApprovalHandlers(
|
|||
);
|
||||
return;
|
||||
}
|
||||
const envBinding = buildSystemRunApprovalEnvBinding(p.env);
|
||||
const systemRunBinding =
|
||||
host === "node"
|
||||
? buildSystemRunApprovalBinding({
|
||||
|
|
@ -132,7 +136,7 @@ export function createExecApprovalHandlers(
|
|||
? undefined
|
||||
: sanitizeExecApprovalDisplayText(approvalContext.commandPreview),
|
||||
commandArgv: host === "node" ? undefined : effectiveCommandArgv,
|
||||
envKeys: systemRunBinding?.envKeys?.length ? systemRunBinding.envKeys : undefined,
|
||||
envKeys: envBinding.envKeys.length > 0 ? envBinding.envKeys : undefined,
|
||||
systemRunBinding: systemRunBinding?.binding ?? null,
|
||||
systemRunPlan: approvalContext.plan,
|
||||
cwd: effectiveCwd ?? null,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,10 @@ import { fileURLToPath } from "node:url";
|
|||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { emitAgentEvent } from "../../infra/agent-events.js";
|
||||
import { formatZonedTimestamp } from "../../infra/format-time/format-datetime.js";
|
||||
import { buildSystemRunApprovalBinding } from "../../infra/system-run-approval-binding.js";
|
||||
import {
|
||||
buildSystemRunApprovalBinding,
|
||||
buildSystemRunApprovalEnvBinding,
|
||||
} from "../../infra/system-run-approval-binding.js";
|
||||
import { resetLogger, setLoggerOverride } from "../../logging.js";
|
||||
import { ExecApprovalManager } from "../exec-approval-manager.js";
|
||||
import { validateExecApprovalRequestParams } from "../protocol/index.js";
|
||||
|
|
@ -583,6 +586,31 @@ describe("exec approval handlers", () => {
|
|||
);
|
||||
});
|
||||
|
||||
it("stores sorted env keys for gateway approvals without node-only binding", async () => {
|
||||
const { handlers, broadcasts, respond, context } = createExecApprovalFixture();
|
||||
await requestExecApproval({
|
||||
handlers,
|
||||
respond,
|
||||
context,
|
||||
params: {
|
||||
host: "gateway",
|
||||
nodeId: undefined,
|
||||
systemRunPlan: undefined,
|
||||
env: {
|
||||
Z_VAR: "z",
|
||||
A_VAR: "a",
|
||||
},
|
||||
},
|
||||
});
|
||||
const requested = broadcasts.find((entry) => entry.event === "exec.approval.requested");
|
||||
expect(requested).toBeTruthy();
|
||||
const request = (requested?.payload as { request?: Record<string, unknown> })?.request ?? {};
|
||||
expect(request["envKeys"]).toEqual(
|
||||
buildSystemRunApprovalEnvBinding({ A_VAR: "a", Z_VAR: "z" }).envKeys,
|
||||
);
|
||||
expect(request["systemRunBinding"]).toBeNull();
|
||||
});
|
||||
|
||||
it("prefers systemRunPlan canonical command/cwd when present", async () => {
|
||||
const { handlers, broadcasts, respond, context } = createExecApprovalFixture();
|
||||
await requestExecApproval({
|
||||
|
|
|
|||
Loading…
Reference in New Issue