Files
yvgude--lean-ctx/docs/contracts/extension-trust-v1.md
T
wehub-resource-sync 26382a7ac6
CI / Clippy (push) Failing after 15m13s
CI / Test (ubuntu-latest) (push) Failing after 16m1s
CI / Test (macos-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Build (no embeddings / no ORT) (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / Cookbook (Node) (push) Has been cancelled
CI / Pi Extension (Node) (push) Has been cancelled
CI / Rust SDK (lean-ctx-client) (push) Has been cancelled
CI / Embed SDK (lean-ctx-sdk) (push) Has been cancelled
CI / Python SDK (leanctx) (push) Has been cancelled
CI / Hermes Plugin (Python) (push) Has been cancelled
CI / SDK Conformance Matrix (push) Has been cancelled
CI / Coverage (push) Has been cancelled
CI / cargo-deny (push) Has been cancelled
CI / Adversarial Safety (push) Has been cancelled
CI / Benchmarks (push) Has been cancelled
CI / Output-Quality Gate (eval A/B) (push) Has been cancelled
CI / Documentation (push) Has been cancelled
CI / CI Green (push) Has been cancelled
JetBrains Plugin / Actionlint (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (rust) (push) Has been cancelled
JetBrains Plugin / Validation (push) Has been cancelled
JetBrains Plugin / Build (push) Has been cancelled
JetBrains Plugin / Test (push) Has been cancelled
Security Check / Security Scan (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:35:30 +08:00

3.1 KiB

Extension Trust & Sandbox — extension-trust-v1

Status: stable · EPIC 12.3 · Code: rust/src/core/plugins/sandbox.rs

Every plugin subprocess — lifecycle hooks (executor) and manifest-declared tools (tools) — runs under a [SandboxPolicy] derived from the plugin's [trust] manifest section. The model is least privilege by default and deliberately split into two honest categories so lean-ctx never claims enforcement it does not perform.

Declaring trust

[plugin]
name = "my-plugin"
version = "0.1.0"

[trust]
permissions = ["network"]   # default: [] (least privilege)

Recognized permissions (anything else is a manifest validation error — fail-closed, no silent grant):

Permission Category Effect
env_passthrough Enforced Opt out of env scrubbing; the child receives the full host environment. Without it the child only sees the allowlist.
network Declared Plugin intends outbound network access. Surfaced for user consent + in /v1/capabilities; not OS-blocked.
fs_write Declared Plugin intends to write outside its own dir. Surfaced; not OS-blocked.

Enforced controls (deterministic)

Applied to every child before spawn, regardless of declared permissions:

  1. Environment isolation — without env_passthrough the child's env is cleared and rebuilt from a fixed allowlist (PATH, HOME, LANG, LC_ALL, LC_CTYPE, TMPDIR/TEMP/TMP, and the Windows boot vars). Host secrets living in the ambient environment never reach the plugin. lean-ctx's own trusted vars (LEAN_CTX_PLUGIN_DIR, LEAN_CTX_HOOK/_TOOL) are set after scrubbing so they always apply.
  2. Working-directory jail — cwd is pinned to the plugin directory (when it exists), so relative paths resolve inside the plugin, not the host cwd.
  3. Timeout — each call is bounded by the hook/tool timeout_ms (enforced by the executor's wait loop; default 5000 ms).

network and fs_write cannot be blocked portably without OS namespaces / seccomp / sandbox-exec, which lean-ctx does not assume. Instead they are declared capabilities: recorded on the manifest, surfaced to the user, and exposed in the capabilities document so a harness/operator can decide whether to trust the plugin. This is honest by design — a green checkmark you can audit, not a guarantee we cannot keep.

Discovery

GET /v1/capabilitiesextensions.plugins[] carries the declared set:

{
  "extensions": {
    "plugins": [
      { "name": "my-plugin", "version": "0.1.0", "permissions": ["network"] }
    ]
  }
}

An empty permissions array means least privilege (scrubbed env, nothing declared).

Versioning

extension-trust-v1 is additive. New permissions may be added in a minor revision; removing or repurposing one is a breaking change requiring -v2. The enforced/declared split is part of the contract.