Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/auto-unanalyzable-command-allow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@moonshot-ai/kimi-code": patch
---

Stop blocking dangerous commands and commands that cannot be statically analyzed in auto permission mode.
2 changes: 1 addition & 1 deletion docs/en/configuration/config-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ api_key = "sk-xxx"

`permission` sets permission rules that are automatically loaded when a session starts, controlling whether the Agent needs user confirmation before calling a tool. Rules are written as a `[[permission.rules]]` array of tables, matched in order; the first matching rule takes effect.

You can also set `dangerous_command_guard = false` under `[permission]` to turn off the built-in dangerous-command policy entirely (no dangerous-command ask or auto-mode deny); the default is `true`. An environment variable `KIMI_CODE_DANGEROUS_COMMAND_GUARD=false` overrides the file setting and restores the behavior before the policy was introduced. Use this switch only for environments that already gate commands outside the agent.
You can also set `dangerous_command_guard = false` under `[permission]` to turn off the built-in dangerous-command policy entirely (no dangerous-command confirmation in Always Ask and Ask When Needed mode; the policy is never active in Never Ask mode); the default is `true`. An environment variable `KIMI_CODE_DANGEROUS_COMMAND_GUARD=false` overrides the file setting and restores the behavior before the policy was introduced. Use this switch only for environments that already gate commands outside the agent.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
Expand Down
2 changes: 1 addition & 1 deletion docs/en/guides/interaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Approvals are not triggered for regular tool calls in Ask When Needed mode, nor

**Ask When Needed mode** (formerly YOLO), toggled with `/ask-when-needed`, auto-approves regular tool calls, making it suitable for batch tasks you know are safe. It still asks before sensitive actions — accessing sensitive files such as `.env` or SSH keys, running dangerous commands such as `shutdown` or `rm -rf`, or exiting Plan mode — and the agent can still ask you questions.

**Never Ask mode** (formerly Auto), toggled with `/never-ask`, is the fully unattended mode: every tool approval is handled automatically, including sensitive files and plan exits, and the agent never asks you questions — it decides everything on its own. The only exception is the built-in dangerous-command guard: commands such as `shutdown`, `reboot`, or `rm -rf` are always blocked in Never Ask mode, and always require your confirmation in Always Ask and Ask When Needed mode.
**Never Ask mode** (formerly Auto), toggled with `/never-ask`, is the fully unattended mode: every tool approval is handled automatically, including sensitive files and plan exits, and the agent never asks you questions — it decides everything on its own. The built-in dangerous-command guard asks for your confirmation before commands such as `shutdown`, `reboot`, or `rm -rf` in Always Ask and Ask When Needed mode; in Never Ask mode these commands run without interruption.


## Mode switching
Expand Down
2 changes: 1 addition & 1 deletion docs/zh/configuration/config-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ api_key = "sk-xxx"

`permission` 设置会话启动时自动加载的权限规则,控制 Agent 调用工具时是否需要用户确认。规则用 `[[permission.rules]]` 数组表写出,按顺序匹配,第一条命中即生效。

也可以在 `[permission]` 下设置 `dangerous_command_guard = false` 完全关闭内置危险命令策略(不再触发危险命令审批或 auto 模式拒绝),默认 `true`。环境变量 `KIMI_CODE_DANGEROUS_COMMAND_GUARD=false` 会覆盖文件设置并恢复策略引入前的行为。此开关只适用于已经在 Agent 之外统一命令限权的环境。
也可以在 `[permission]` 下设置 `dangerous_command_guard = false` 完全关闭内置危险命令策略("Always Ask" 和 "Ask When Needed" 模式下不再触发危险命令审批;"Never Ask" 模式本就不启用该策略),默认 `true`。环境变量 `KIMI_CODE_DANGEROUS_COMMAND_GUARD=false` 会覆盖文件设置并恢复策略引入前的行为。此开关只适用于已经在 Agent 之外统一命令限权的环境。

| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
Expand Down
2 changes: 1 addition & 1 deletion docs/zh/guides/interaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Agent 调用会产生副作用的工具(修改文件、执行命令等)时

**"Ask When Needed"**(必要时询问,原 YOLO)用 `/ask-when-needed` 切换,自动批准普通工具调用,适合已知安全的批处理任务。敏感操作仍会询问——例如访问 `.env`、SSH 私钥等敏感文件、执行 `shutdown`、`rm -rf` 这类危险命令,或退出 Plan 模式——Agent 也仍可能向你提问。

**"Never Ask"**(完全自动,原 Auto)用 `/never-ask` 切换,是完全无人值守模式:所有工具审批自动处理,包括敏感文件和计划退出,且 Agent 不会向你提问,完全由它自己做决定。唯一的例外是内置的危险命令拦截:`shutdown`、`reboot`、`rm -rf` 这类命令在 "Never Ask" 模式下会被直接拒绝,在 "Always Ask" 和 "Ask When Needed" 模式下必须经你确认
**"Never Ask"**(完全自动,原 Auto)用 `/never-ask` 切换,是完全无人值守模式:所有工具审批自动处理,包括敏感文件和计划退出,且 Agent 不会向你提问,完全由它自己做决定。内置的危险命令拦截会在 "Always Ask" 和 "Ask When Needed" 模式下要求你确认 `shutdown`、`reboot`、`rm -rf` 这类命令;在 "Never Ask" 模式下这些命令直接执行,不再拦截


## 模式切换
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ export class DangerousCommandAskPermissionPolicyService implements PermissionPol

evaluate(context: ResolvedToolExecutionHookContext): PermissionPolicyResult | undefined {
if (!isDangerousCommandGuardEnabled(this.config)) return undefined;
if (this.modeService.mode === 'auto') return undefined;
if (context.toolCall.name !== 'Bash') return undefined;
const command = bashCommandText(context.args);
const verdict =
Expand All @@ -128,25 +129,9 @@ export class DangerousCommandAskPermissionPolicyService implements PermissionPol
this.bashParser.parse(source, PARSE_OPTIONS),
);
if (verdict === undefined) return undefined;
const auto = this.modeService.mode === 'auto';
if (verdict.kind === 'dangerous') {
if (auto) {
return {
kind: 'deny',
reason: { dangerous_command: verdict.command },
message: `Bash command '${verdict.command}' is blocked in auto permission mode because it is considered dangerous. Ask the user to switch permission mode or run it themselves.`,
};
}
return { kind: 'ask', reason: { dangerous_command: verdict.command } };
}
if (auto) {
return {
kind: 'deny',
reason: { unanalyzable_command: true },
message:
'This Bash command could not be analyzed and is blocked in auto permission mode. Rewrite it with a literal command name and arguments, or ask the user to run it themselves.',
};
}
return { kind: 'ask', reason: { unanalyzable_command: true } };
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,19 +236,19 @@ describe('AgentPermissionPolicyService chain', () => {
);

it.each([
['shutdown -h now', 'shutdown'],
['reboot', 'reboot'],
['rm -rf /tmp/build', 'rm -rf'],
['dd if=/dev/zero of=/dev/sda bs=1M', 'dd'],
] as const)('denies `%s` in auto mode', async (command, matched) => {
'shutdown -h now',
'reboot',
'rm -rf /tmp/build',
'dd if=/dev/zero of=/dev/sda bs=1M',
])('approves `%s` in auto mode', async (command) => {
mode = 'auto';

await expect(evaluate({
toolName: 'Bash',
args: { command, timeout: 60 },
})).resolves.toMatchObject({
policyName: 'dangerous-command-ask',
result: { kind: 'deny', reason: { dangerous_command: matched } },
policyName: 'auto-mode-approve',
result: { kind: 'approve' },
});
});

Expand Down Expand Up @@ -370,16 +370,16 @@ describe('AgentPermissionPolicyService chain', () => {
});

it.each(['$CMD --force', 'bash -c "echo $HOME"', 'env $FLAGS'])(
'denies unanalyzable command `%s` in auto mode',
'approves unanalyzable command `%s` in auto mode',
async (command) => {
mode = 'auto';

await expect(evaluate({
toolName: 'Bash',
args: { command, timeout: 60 },
})).resolves.toMatchObject({
policyName: 'dangerous-command-ask',
result: { kind: 'deny', reason: { unanalyzable_command: true } },
policyName: 'auto-mode-approve',
result: { kind: 'approve' },
});
},
);
Expand Down
Loading