openclaw - 💡(How to fix) Fix Allow opt-in symlink cwd for approval-bound system.run when user explicitly trusts the path [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#77096Fetched 2026-05-05 05:52:15
View on GitHub
Comments
1
Participants
2
Timeline
3
Reactions
2
Author
Timeline (top)
commented ×1mentioned ×1subscribed ×1

Error Message

The user-facing error (SYSTEM_RUN_DENIED: approval requires canonical cwd (no symlink cwd)) is also opaque and gives no hint of remediation.

  • Include the resolved realpath and remediation hints (set OPENCLAW_HOME, run from canonical path) in the error message.

Fix Action

Fix / Workaround

Current workarounds either lose approval guarantees or change the user's working context:

  • Include the resolved realpath and remediation hints (set OPENCLAW_HOME, run from canonical path) in the error message.
  • Document the rationale and workarounds in docs/tools/exec-approvals.md.

Code Example

{
  "execApprovals": {
    "allowSymlinkCwd": true,
    "allowSymlinkCwdInPath": true
  }
}
RAW_BUFFERClick to expand / collapse

Background

resolveCanonicalApprovalCwdSync in src/node-host/invoke-system-run-plan.ts:1102-1159 unconditionally rejects approval-bound system.run execution when:

  • the cwd itself is a symlink (cwdLstat.isSymbolicLink()), or
  • any path component is a mutable symlink (hasMutableSymlinkPathComponentSync).

This guard ships from the @tdjackey-reported TOCTOU hardening (CHANGELOG entries for 2026.2.26, lines 3437 and 3364) and protects against symlink-rebind attacks between approval display and execution.

Problem

The current behavior has no escape hatch, and several legitimate setups hit this guard:

  • pnpm/yarn workspaces where project roots are symlinked into a monorepo.
  • Users who deliberately keep ~/projects on external storage via a symlink.
  • macOS /tmp -> /private/tmp symlink chain for shared scratch space.
  • Any user who intentionally configures their layout via symlinks and is fully aware that the path is a link.

Existing knobs do not help with this case:

  • OPENCLAW_HOME only redirects the approvals file location (Layer 1 in src/infra/exec-approvals.ts); it has no effect on the cwd canonical check.
  • secrets.allowSymlinkCommand / --provider-allow-symlink-command only affects secrets-resolve exec, not system.run.
  • tools.fs.allowSymlinkTargetWithinRoot only affects fs tools.

Current workarounds either lose approval guarantees or change the user's working context:

  • cd "$(realpath .)" before running — surprising and destroys cwd-as-displayed semantics.
  • Add the command to allowlist with ask: off — bypasses approval entirely, which is exactly what the guard is meant to preserve.

The user-facing error (SYSTEM_RUN_DENIED: approval requires canonical cwd (no symlink cwd)) is also opaque and gives no hint of remediation.

Proposal

Add an opt-in setting, default off, that preserves current behavior unless the user explicitly trusts symlinks:

{
  "execApprovals": {
    "allowSymlinkCwd": true,
    "allowSymlinkCwdInPath": true
  }
}

When enabled, resolveCanonicalApprovalCwdSync should:

  1. Resolve realpath(cwd) and surface both the user-supplied cwd and its canonical target in the approval prompt, so the user explicitly approves the canonical path.
  2. Pin the ApprovedCwdSnapshot to the realpath inode identity, so a later rebind still trips the existing revalidateApprovedCwdSnapshot -> sameFileIdentity check.

This keeps the TOCTOU guarantee — approval remains bound to the inode the user actually saw — while letting users with intentional symlink layouts execute.

Alternative (lower-effort fallback)

At minimum, improve the rejection UX:

  • Include the resolved realpath and remediation hints (set OPENCLAW_HOME, run from canonical path) in the error message.
  • Document the rationale and workarounds in docs/tools/exec-approvals.md.

References

  • src/node-host/invoke-system-run-plan.ts:1102-1159 (resolveCanonicalApprovalCwdSync)
  • src/node-host/invoke-system-run-plan.ts:1195-1228 (hardenApprovedExecutionPaths)
  • src/infra/exec-approvals.ts:241-279 (assertNoSymlinkPathComponents — Layer 1 for completeness)
  • CHANGELOG 2026.2.26: lines 3437, 3364 (original hardening)

extent analysis

TL;DR

To address the issue, consider adding an opt-in setting to allow symlinks in the cwd, or improve the rejection UX by including remediation hints in the error message.

Guidance

  • The current behavior is caused by a security guard that unconditionally rejects approval-bound system.run execution when the cwd is a symlink or contains a mutable symlink.
  • To mitigate this, users can consider using the proposed opt-in setting allowSymlinkCwd and allowSymlinkCwdInPath in their configuration.
  • Alternatively, improving the rejection UX by including the resolved realpath and remediation hints in the error message can help users understand the issue and find a workaround.
  • Users can also consider documenting the rationale and workarounds in docs/tools/exec-approvals.md for future reference.

Example

{
  "execApprovals": {
    "allowSymlinkCwd": true,
    "allowSymlinkCwdInPath": true
  }
}

This configuration allows symlinks in the cwd and path components.

Notes

The proposed solution requires changes to the resolveCanonicalApprovalCwdSync function to support the opt-in setting. The alternative solution only requires changes to the error message and documentation.

Recommendation

Apply the workaround by improving the rejection UX, as it is a lower-effort solution that still provides a better user experience. This approach allows users to understand the issue and find a workaround without requiring significant changes to the codebase.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix Allow opt-in symlink cwd for approval-bound system.run when user explicitly trusts the path [1 comments, 2 participants]