Skip to content

fix: restrict shell execution in docs-only repository runs - #546

Open
Gautam Sharma (GautamSharma99) wants to merge 1 commit into
langchain-ai:mainfrom
GautamSharma99:fix/docs-only-shell-execute
Open

fix: restrict shell execution in docs-only repository runs#546
Gautam Sharma (GautamSharma99) wants to merge 1 commit into
langchain-ai:mainfrom
GautamSharma99:fix/docs-only-shell-execute

Conversation

@GautamSharma99

Copy link
Copy Markdown
Contributor

Summary

Fixes #536.

Repository init/update runs now enforce their docs-only boundary across the shell execute tool as well as the structured filesystem tools.

This PR:

  • adds an independent, fail-closed execute allowlist for repository docs-only runs;
  • permits only exact read-only maintenance commands required by the runtime;
  • blocks redirection, chaining, substitution, and arbitrary shell programs before they reach the host shell;
  • updates the agent prompt so restricted runs use the provided git summary and structured filesystem tools instead of repeatedly attempting unavailable shell discovery or shell writes;
  • preserves existing shell behavior for interactive chat and personal/local-wiki ingestion;
  • adds a patch changeset and regression coverage.

Problem

OpenWikiLocalShellBackend already constrained write(), edit(), and uploadFiles() to openwiki/ when docsOnly: true in repository mode.

However, execute() applied a shell allowlist only when .openwikiignore was active. With the normal inactive ruleset, commands were delegated directly to LocalShellBackend.execute(). An agent could therefore bypass the structured path guard with a command such as:

echo changed > AGENTS.md

The same primitive could mutate source files or paths outside the repository. This matters because repository and connector content are untrusted model inputs.

Implementation

Independent docs-only shell policy

OpenWikiLocalShellBackend.execute() now evaluates two independent restrictions:

  1. the existing .openwikiignore allowlist, when ignore rules are active;
  2. a repository docs-only allowlist when docsOnly is true and outputMode is repository.

A command must satisfy every active restriction.

The docs-only allowlist intentionally contains only:

  • pwd
  • git rev-parse HEAD
  • git --no-pager rev-parse HEAD

Patterns are fully anchored after trimming. Appending redirection or another command therefore fails closed:

  • pwd && echo bad > AGENTS.md — blocked
  • git rev-parse HEAD > AGENTS.md — blocked
  • arbitrary shell programs — blocked

This is deliberately an allowlist rather than a mutation denylist. Shell grammar, substitutions, aliases, redirection, and command composition make it unsafe to prove arbitrary input read-only.

The existing .openwikiignore maintenance allowlist remains separate because it has a different read-confidentiality purpose and historically permits deterministic plan cleanup. Repository docs-only execution does not permit shell cleanup; the host-side cleanup path already removes _plan.md.

Prompt alignment

Repository init/update prompts now:

  • direct history analysis to the provided git summary;
  • direct discovery and writes to ls, glob, grep, read_file, write_file, and edit_file;
  • no longer recommend rg, shell git history, or "narrow shell execute" for documentation writes;
  • explicitly explain that execute is limited to a few read-only maintenance commands.

This avoids tool-error churn after the backend is hardened.

Behavior matrix

Run mode Shell behavior after this PR
Repository init/update Restricted to the exact docs-only read-only allowlist
Repository chat without active ignore rules Unchanged; shell remains available
Local/personal wiki init/update Unchanged; shell remains available for connector raw files and configured local repositories
Any run with active .openwikiignore Existing ignore allowlist still applies; repository docs-only runs must satisfy both policies

Tests

Added backend regressions that verify:

  • direct redirection to AGENTS.md is refused;
  • command chaining is refused;
  • redirection appended to an otherwise allowed git command is refused;
  • the target file is never created;
  • exact pwd remains available;
  • local-wiki init/update shell access remains available.

Added prompt regressions that verify:

  • repository init/update no longer recommends shell discovery or shell writes;
  • repository chat retains existing shell guidance;
  • local-wiki init retains shell access guidance.

Validation

  • corepack pnpm test — 67 files, 795 tests passed
  • corepack pnpm run typecheck
  • corepack pnpm run lint:check
  • corepack pnpm run format:check
  • corepack pnpm exec vitest run test/docs-only-backend.test.ts test/openwiki-ignore.test.ts test/prompt.test.ts — 39 tests passed
  • corepack pnpm exec changeset status
  • git diff --check

@changeset-bot

changeset-bot Bot commented Jul 31, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 729bfc0

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
openwiki Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Docs-only init/update guard can be bypassed through shell execute

1 participant