Skip to content

exec-approvals.json security=full not respected — commands still gated #26962

@Youyou972

Description

@Youyou972

Bug

exec-approvals.json with security: "full" and ask: "off" for all agents (both in defaults and per-agent agents entries) does not bypass the exec approval gate. Commands are still denied with approval-timeout.

Steps to Reproduce

  1. Set ~/.openclaw/exec-approvals.json:
{
  "version": 1,
  "socket": { "path": "~/.openclaw/exec-approvals.sock", "token": "..." },
  "defaults": { "security": "full", "ask": "off" },
  "agents": {
    "main": { "security": "full", "ask": "off" },
    "work-krab": { "security": "full", "ask": "off" }
  }
}
  1. Run openclaw approvals set --file ~/.openclaw/exec-approvals.json — confirms: Defaults: security=full, ask=off, Agents: 4
  2. Run openclaw approvals get — shows correct config
  3. Restart gateway
  4. Agent tries to run any exec command (even echo test)
  5. Result: Exec denied (approval-timeout) instead of immediate execution

Expected Behavior

With security: "full", the gateway exec bridge should return { allowed: true } immediately at line ~89 of src/gateway/server-methods/exec-approval-bridge.ts:

if (policy.security === "full") {
    return { allowed: true, reason: "security=full" };
}

Actual Behavior

The code reaches requestUserApproval() which waits for a companion app socket. Since no companion app is connected, it falls through to askFallback (default: "deny") and returns approval-timeout.

Analysis

Looking at the source (src/infra/exec-approvals.ts and src/gateway/server-methods/exec-approval-bridge.ts), the logic is correct. Possible causes:

  1. loadExecApprovals() returns empty {} — Maybe OPENCLAW_STATE_DIR is set differently than expected, or the file path resolves wrong, or the JSON parse fails silently (the catch returns {})
  2. agentId mismatch — The req.agentId passed to resolveExecApproval() might not match the keys in the config (e.g., "main" vs "agent:main" vs undefined)
  3. Gateway caching — The file might be read once at startup and cached, not re-read after openclaw approvals set
  4. The approval flow might bypass the bridge entirely — Some other code path handles exec before exec-approval-bridge.ts is called

Environment

  • OpenClaw v2026.2.24
  • macOS (arm64)
  • Multiple agents configured (main, personal-krab, work-krab, lobstah)
  • No companion app connected
  • Discord channel as primary interface

Workaround

Sub-agents spawned via sessions_spawn can execute commands (they seem to use a different exec path). Main session exec remains blocked.

Suggested Debug

Adding logWarn in loadExecApprovals() to log the resolved file path and whether the file was found would immediately identify if the issue is path resolution.

Metadata

Metadata

Assignees

No one assigned

    Labels

    securitySecurity documentationstaleMarked as stale due to inactivity

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions