If you discover a security vulnerability in lean-ctx, please report it privately:
- Email: hello@thinkery.ch
- GitHub: Create a private security advisory
- Response time: We aim to acknowledge reports within 48 hours
- Disclosure: We follow responsible disclosure practices (90-day embargo)
Please do NOT:
- Open public GitHub issues for security vulnerabilities
- Disclose vulnerabilities on social media or forums before we've had a chance to address them
LeanCTX is the Context Gateway for AI Systems. Control what your AI can see. This policy covers the open-source LeanCTX Engine and its local CLI, MCP, HTTP, hook, and supported proxy paths. LeanCTX SDK and commercial Enterprise deployments have separate integration and operating contracts.
The Engine runs locally, but enabled providers, upstream model traffic, updates, telemetry, and other configured integrations can make network requests. Review the configured integration and deployment rather than infer data locality from the word “local.”
Context selection determines what AI should see; permissions and configured content controls constrain what it may see. Receipts describe observed context operations, not prompts or delivery outside the integration's visibility.
Does:
- Read files from your local filesystem (explicit reads and tool-driven scans within the project boundary)
- Execute shell commands (only commands you or your AI tool explicitly invoke)
- Cache file contents in memory during a session
- Store statistics in
~/.lean-ctx/stats.json(command counts, token savings) - Store session state in
~/.lean-ctx/sessions/(task context, findings)
lean-ctx enforces a filesystem boundary for tool I/O:
- PathJail: all tool path inputs are resolved (symlinks and
..included) and checked against the jail scope (path_jail_scope, global-only):home(default since v3.11.1; read and write below~since v3.11.3): every path below the user's home directory, except the protected zones — every top-level dot entry (~/.ssh,~/.aws,~/.gnupg,~/.config, shell rc files, other agents'~/.claude/~/.codex/~/.cursor),~/Library,~/AppData/NTUSER.DAT*and~/snap. Everything outside~stays jailed. Zones are a hard deny: a root or allow entry that merely contains a zone does not open it. An implausible$HOME(/,/root,/tmp, not owned by the user) disables the scope.projects(the default of v3.11.1–v3.11.2): only paths inside a project below~(a folder between it and~holds.git,Cargo.toml,package.jsonor another project marker) are readable; loose personal files stay jailed, and writes stay limited to the session's project, host-declared roots and explicit allow entries.project: only the currentproject_rootplus the explicit allow roots below.- If a path would escape, the call fails naming the single command that admits it
(
lean-ctx allow-path <dir>) and asks the agent to defer to the user.
- Per-session project binding: the project root comes from the host session (MCP roots,
host project env, working directory). Global agent configs no longer carry a
LEAN_CTX_PROJECT_ROOTpin;lean-ctx doctorreports anddoctor --fixremoves old ones. - Explicit allow roots (
lean-ctx allow-path <dir>writesallow_paths):- Env:
LEAN_CTX_ALLOW_PATH(orLCTX_ALLOW_PATH) — a path list (:on Unix,;on Windows) - Config:
allow_pathsin~/.lean-ctx/config.toml(whitelist only);extra_roots(whitelist + multi-root scanning) ~,$VARand${VAR}are expanded in these entries (no shell runs for config files)
- Env:
- Disabling the jail (sandboxed environments where the OS is the boundary):
- Config:
path_jail = falsein~/.lean-ctx/config.toml - Compile-time: the
no-jailcargo feature - The legacy
LEAN_CTX_NO_JAIL=1env var was removed in v3.7.4 and has no effect - Full reference:
docs/reference/appendix-paths-and-config.md§5;lean-ctx doctorreports the effective jail state
- Config:
- Symlink escape protection: canonicalization ensures that symlinks pointing outside the jail are rejected.
In addition, roles can restrict unsafe I/O:
- Secret-like deny-by-default:
- Search skips secret-like files (e.g.
.env,*.pem,id_rsa,.ssh/,.aws/) unless the active role explicitly allows them. - Artifact registry resolution rejects secret-like artifact paths unless allowed (artifacts are indexed/shareable by design).
- Direct reads/edits can warn or error depending on boundary mode.
- Search skips secret-like files (e.g.
.gitignorebypass is policy-gated:ctx_search ignore_gitignore=truerequires explicit role permission (typically theadminrole).
- Boundary mode:
- Roles can set
io.boundary_mode = "warn" | "enforce". - Env override:
LEAN_CTX_IO_BOUNDARY_MODE=warn|enforce.
- Roles can set
- Auditability:
- Boundary denials/warnings emit local
PolicyViolationevents (no secret content is returned as part of the violation).
- Boundary denials/warnings emit local
Primary risks:
- Accidental secret exfiltration to LLMs via
ctx_read,ctx_search, compressedctx_shell, archives, or exported artifacts. - Boundary escapes via absolute paths, symlinks, linked projects, or artifact path tricks.
- Amplification / token burn by scanning large files or returning unbounded outputs.
- ReDoS via user-supplied regex patterns in
ctx_search. - Cross-workspace data access in team server deployments (IDOR).
Core mitigations:
- PathJail + explicit allow roots (
LEAN_CTX_ALLOW_PATH/allow_paths). - Role-gated unsafe I/O (
ignore_gitignore, secret-like allow). - Secret-path handling — search skips recognized secret-like paths; direct-read warnings or rejection depend on the configured I/O boundary, permissions, and role.
- Shell CWD jail enforcement — explicit
cwdparameters are jail-checked,cdtargets validated. - Deterministic redaction on tool outputs (non-admin roles, and for persisted archives).
- Hard caps on reads and outputs to limit DoS/token burn.
- Regex guards — pattern length (1024 chars) and DFA size (1 MiB) limits on
ctx_search. - MCP message size limit — 32 MiB cap on JSON-RPC message size.
- Constant-time token comparison in all auth paths (dashboard, HTTP server, team server).
- Team server tenant isolation — workspace enforced from authenticated token, not query parameters.
- JSON-RPC batch rejection — batch requests rejected on team server to prevent scope bypass.
- Event payload redaction — REST API responses redacted to
Summarylevel by default. - Pipeline archive redaction — shell output archives redacted before storage.
- UDS socket permissions —
0o600enforced on Unix domain sockets after bind. - Error response sanitization — internal details logged server-side, generic codes returned to clients.
- MCP gateway output redaction — downstream
ctx_tools calloutput (success and error text) passes secret detection before it reaches the model. - Signed handoffs and packages — handoff bundle signatures cover the signer id and key; context packages and addons must be signed unless a local import passes
--allow-unsigned(allow_unsigned=trueover MCP);/v1/a2a/handoffrejects unsigned bundles and context packages. An embedded key proves integrity only: a signer is reported as trusted only when its key is pinned in<data_dir>/trusted-signers.toml([[signers]] subject = "<agent id or @namespace>",public_key = "<hex>") or held by a local agent identity. Remotepack install/addon addpin the namespace publisher key on first install and refuse a different key afterwards. - Bounded audit trail —
<data_dir>/audit/trail.jsonlrotates at 32 MiB intotrail.NNNNNN.jsonl; the hash chain continues across segments andverifychecks all of them. Archived segments are not deleted automatically, because removing one breaks chain verification.
Optional network activity (review effective configuration):
- Update check: a lightweight daily GET to
api.github.com/repos/yvgude/lean-ctx/releases/latestto notify you of new versions. Sends only the current version as User-Agent. Disable withupdate_check_disabled = truein~/.lean-ctx/config.tomlorLEAN_CTX_NO_UPDATE_CHECK=1. - Telemetry: product telemetry is on by default since v3.11.0 (v3.10.5 and earlier defaulted it off); an explicit earlier opt-out is kept. Inspect your installed build with
lean-ctx telemetry statusandlean-ctx telemetry show. Disable sending withlean-ctx telemetry off,DO_NOT_TRACK=1, orLEAN_CTX_TELEMETRY=off. Enabled telemetry sends installation and aggregate usage metadata. Do not infer zero network activity from telemetry being disabled. - Configured providers and integrations: source connectors, upstream model requests, submitted feedback, and remote endpoints have their own payloads and credentials. Review each enabled path.
Limits:
- Configured detectors recognize supported patterns; they do not detect every secret or sensitive datum.
- Warning, redaction, and blocking are different actions. Roles, bypasses, allow roots, and disabled controls change the effective boundary.
- Inputs, caches, archives, and integration credentials require appropriate host protection and retention settings.
- The normal Engine runs as your user; a container, VM, or operating-system policy can supply an additional boundary.
Every push and pull request triggers our CI security pipeline:
cargo audit— Scans dependencies for known CVEscargo clippy— Enforces Rust safety lints (warnings = errors)- Dangerous pattern scan — Detects potentially unsafe code patterns:
- Shell injection vectors (
Command::new("sh")with user input) - Network operations (
reqwest::,std::net::,hyper::) - Unsafe code blocks (
unsafe {) - Environment manipulation (
.env("LD_PRELOAD")) - Hardcoded secrets or obfuscated strings
- Shell injection vectors (
cargo test— Full test suite must pass
Changes to these files receive extra scrutiny:
| File | Risk | Why |
|---|---|---|
rust/src/shell/ |
Shell execution | Wraps your shell, executes commands |
rust/src/server/ |
MCP protocol | Handles all tool calls from AI editors/agents |
rust/src/hooks/ |
Editor integration | Installs hooks/config into Claude Code, CodeBuddy, Cursor, etc. |
rust/src/core/cache.rs |
File caching | Reads and stores file contents |
rust/Cargo.toml |
Supply chain | Dependency manifest |
.github/workflows/*.yml |
CI/CD | Release pipeline integrity |
The manifests and lockfile define the dependency set for a given release.
Review rust/Cargo.toml, rust/Cargo.lock, enabled features, and the security
workflow when assessing supply-chain exposure. Dependency counts, download
counts, and recent commits alone are not evidence that a dependency is safe.
Rust binaries are frequently flagged by ML-based antivirus engines (particularly Microsoft Defender's Wacatac.B!ml classifier). This is a known issue affecting many Rust projects:
- Rust lang discussion on false positives
- A low number of detections alone does not establish a false positive.
- The
!mlsuffix inWacatac.B!mlmeans "Machine Learning detection" (heuristic, not signature-based)
Why it happens:
- Statically linked binaries (~30 MB) are unusual for Windows
strip = true+lto = trueoptimizations alter binary structure- New/unsigned executables trigger ML classifiers trained on known-good signed software
How to verify lean-ctx yourself:
- Build from source:
cargo install lean-ctx(compiles on your machine) - Compare SHA256 checksums against our GitHub Releases
- Audit the source code: the entire codebase is open source
To build the source and inspect its reported version:
# Clone and build
git clone https://github.com/yvgude/lean-ctx.git
cd lean-ctx/rust
cargo build --release
# Compare with installed version
lean-ctx --version
./target/release/lean-ctx --versionUse the checksums attached to the relevant GitHub Release to check a downloaded artifact. Matching version strings does not prove byte-for-byte reproducibility or establish that a binary matches source.
Every release publishes SHA256SUMS and release-manifest.json, each signed with keyless Cosign by the release workflow (.sig and .pem next to the file).
lean-ctx updateverifies both signatures against the pinned release-workflow identity, then the archive digest, and refuses the update on any failure.install.shand the npm package verify the archive againstSHA256SUMSand abort when the checksum file, its entry for the archive, or a SHA-256 tool is missing, or when the digest does not match. There is no opt-out. They do not check the Cosign signature, so a tampered release whoseSHA256SUMSwas replaced too is only caught by the checks below.
To check a manual download yourself (replace vX.Y.Z with the release tag):
cosign verify-blob SHA256SUMS \
--signature SHA256SUMS.sig --certificate SHA256SUMS.pem \
--certificate-identity "https://github.com/yvgude/lean-ctx/.github/workflows/release.yml@refs/tags/vX.Y.Z" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
sha256sum --ignore-missing -c SHA256SUMS # macOS: shasum -a 256 --ignore-missing -c SHA256SUMSReleases built after GHSA-rxv5-4c3x-g4q6 also carry GitHub build-provenance attestations for every archive, wheel, SHA256SUMS and release-manifest.json:
gh attestation verify lean-ctx-aarch64-apple-darwin.tar.gz --repo yvgude/lean-ctx \
--signer-workflow yvgude/lean-ctx/.github/workflows/release.ymlWhen vulnerabilities are reported:
- Day 0: Acknowledgment sent to reporter
- Day 7: Severity assessment completed
- Day 14: Patch development begins
- Day 30: Patch released + CVE filed (if applicable)
- Day 90: Public disclosure
Critical vulnerabilities (RCE, data exfiltration) are fast-tracked.
Status: Mitigated on Unix; residual risk on Windows.
A race window exists between jail_path validation and the subsequent file operation. Mitigations in place: standard reads open with O_NOFOLLOW (Unix) and reject symlinks; ctx_edit additionally rejects symlinks on both its read and write paths (lstat pre-check on all platforms, O_NOFOLLOW on Unix) and re-verifies the file fingerprint (size/mtime/md5) immediately before writing. On Windows there is no O_NOFOLLOW equivalent, so the lstat pre-check is the only guard — it rejects symlinks and all NTFS reparse points (junctions, mount points) via pathutil::is_symlink_or_reparse, and read_file_nofollow applies the same lstat check before opening. The residual risk is the unavoidable check→open race window.
Recommendation for regulated environments: Run lean-ctx inside a container or VM where the filesystem is controlled and no untrusted processes can modify symlinks concurrently.
Status: Documented limitation.
The ctx_execute tool provides timeout enforcement and output capping.
OS isolation depends on sandbox_level, platform support, and the selected
execution path. Configured level 1 uses Seatbelt on macOS or Landlock on Linux;
unsupported platforms can fall back to level 0. Do not treat the tool name as
proof of OS isolation. Inspect rust/src/core/sandbox.rs for the release in use.
Recommendation for regulated environments: Disable ctx_execute via role configuration (denied: ["ctx_execute"]) or run lean-ctx in a pre-existing container sandbox.
Status: Defense in depth — the agent's permission model remains the primary boundary. ctx_shell is not a sandbox.
ctx_shell and lean-ctx -c enforce, in both allowlist and blocklist-only mode:
- a deny-by-default executable allowlist when configured (AST-segmented: every segment of a pipeline/compound command must be allowed),
eval/exec/sourceunconditionally blocked;$()/backticks blocked at command position,- interpreter inline-code blocking:
bash -c,sh -c,python -c,node -e, … are rejected (including via delegation wrappers likeenv,timeout,xargs) — quoting a payload insidebash -c '…'does not bypass the file-write or allowlist checks because the interpreter call itself is refused, - file-write detection (
>,>>,tee, heredoc-to-file,dd of=,curl -o/-O,wgetto file) — output capture (>,>>,tee) may go to the session's project,allow_paths/extra_roots,write_allow_pathsor a scratch path (never/,~, an ancestor of~or aread_only_rootsentry); downloads only to scratch paths andwrite_allow_paths; everything else belongs to the editor's native Write/Edit tools where the agent's permission UI governs them, - dangerous-flag blocking (
git --upload-pack,tar --to-command,find -exec,awk system()), inline env hijack blocking (PATH=,LD_PRELOAD=,GIT_SSH_COMMAND=, …), and dangerous env-key filtering on the MCPenvparameter, - no self-loosening (allowlist mode, the default): lean-ctx subcommands that widen its own guardrails —
yolo,allow <cmd>,allow-path <dir>,trust,security open,security secrets off,config setof a security or path/allowlist key — are refused, so an agent cannot undo a refusal it just received. Listing,--remove,secure,untrustandsecurity secrets onstill run. The user runs the blocked commands in their own terminal (warn-only there, see below).ctx_executeis not covered — see the next paragraph.
Enforcement applies to the MCP path, hook-child mode and every non-interactive CLI invocation; an interactive human terminal gets a warning instead (LEAN_CTX_ALLOWLIST_WARN_ONLY=1 opts out explicitly). Cloud/infra mutation CLIs (terraform, kubectl, aws, …) are excluded from the default allowlist and require per-tool opt-in (lean-ctx allow <cmd>). Commands inside a substitution in an argument ($(…), backticks, <(…)/>(…)) are gated like top-level commands in every enforce-mode call. shell_strict_mode = true upgrades the remaining warn-only heuristic (pipe to a bare interpreter) to a hard block.
ctx_execute(language=shell) is deliberately NOT allowlisted (GH #905). The checks above gate ctx_shell and lean-ctx -c only. ctx_execute is the trusted script path: calling it is an explicit decision to write and run a script, the same decision a native Write plus bash script.sh would express, so re-running the allowlist there would only tax the sanctioned route. The consequence must be stated plainly rather than assumed: the two tools are one trust tier, not a boundary and a bypass. Any agent that can call ctx_execute has full shell reach no matter how shell_allowlist is configured — tightening the allowlist does not constrain it. Where that reach is unacceptable, deny the tool by role (denied: ["ctx_execute"]) or run the stack in an OS sandbox; those are the only controls that bind it.
Constructs the gate refuses (GHSA-rxv5-4c3x-g4q6 E). The command runs in the user's $SHELL, which may be bash, dash or zsh. Where these shells read the same text differently, or where the gate cannot tell which commands a construct runs, the command is refused rather than guessed at. Rewrite the command without the construct:
- legacy
$[ … ]arithmetic (use$(( … ))); - zsh parameter flags
${(…)…}and bash prompt expansion${x@P}, both of which can evaluate a value as code; - a
(attached to a word: zsh glob qualifiers (*(e:…:),*(+cmd)) and bash extended globs (@(…),!(…)); function headsf()and arraysa=(…)are fine; - a bare
{argument (zsh brace bodies such aswhile c { … }orrepeat n { … }), zsh short loops (for x (…) cmd), and a brace group followed by anything other than redirections ({ a; } b,{ a } always { b }); hash -pandenable -f; atrapaction is checked like a command;- a carriage return not followed by a line feed, and the Unicode line/paragraph separators U+2028/U+2029;
- a here-document whose terminator line never appears;
- constructs that bash, dash and zsh end at different places:
$'…'with an escaped quote, a'or{inside${…},<<inside(( … )), and here-documents queued across a command-substitution boundary.
Assignments to variables that redirect which binary, library or startup code runs (LD_*, DYLD_*, BASH_ENV, ENV, PROMPT_COMMAND, PS4, SHELLOPTS, ZDOTDIR, GIT_CONFIG*, BASH_FUNC_*, pager and editor variables other than harmless values like cat, NODE_OPTIONS, PERL5OPT, RUBYOPT, …) are blocked anywhere in the assignment prefix and through export/declare/env/read/printf -v. PATH is blocked only as the first word of a command (PATH=… cmd); export PATH=… stays allowed.
Known limitation: arithmetic evaluation of variable contents. The gate is syntactic. bash evaluates array subscripts inside variable values at run time whenever a value is used in an arithmetic context, and that evaluation performs command substitution: x='a[$(cmd)]'; echo $((x)) runs cmd, as do let, [[ x -eq … ]], test -v, printf -v, unset and declare with such a value. The value can come from a quoted string or from a file read at run time, so no syntactic check can see it. This is one more reason the allowlist is not a sandbox: for untrusted input, use an OS sandbox or the agent's approval flow.
Explicitly out of scope: commands run with the invoking user's full privileges. Anything the user can do, an allowed command can do — cp/rsync can copy any file the OS lets the user read, package managers execute arbitrary install scripts, npm test runs project code. A blocklist cannot enumerate these; pretending otherwise would be security theater.
Rationale: Shell filters can be bypassed by a sufficiently creative attacker, so the agent's permission model (Claude Code allowlists, Cursor approval dialogs) remains the primary boundary — lean-ctx's allowlist is a second, independent layer, not a replacement.
Mitigation for untrusted agents: Use role-based denied: ["ctx_shell"] to disable shell access entirely, enable the deny-by-default allowlist with a minimal command set, and/or run the whole agent stack inside an OS sandbox (container, gVisor/Firecracker, bwrap, seccomp/AppArmor) — that is the correct layer for kernel-grade isolation.
Status: Mitigated on Unix; residual risk on Windows.
A race window exists between jail_path validation and the subsequent file operation. Mitigations: symlink-following canonicalization before access, O_NOFOLLOW + symlink rejection on read paths (Unix), and symlink rejection on ctx_edit write paths (all platforms, lstat-based; on Windows this includes NTFS junctions and other reparse points). Home-level IDE config dirs (~/.cursor, ~/.claude, …) are excluded from the jail's allow-list by default (allow_ide_config_dirs opts in).
Windows file permissions: the Unix 0o600/0o700 tightening (cloud credentials, crash log) has no direct Windows equivalent; protection relies on the default NTFS ACL of the user profile (%USERPROFILE% is not readable by other non-admin users). Machines with custom ACLs on the profile directory should verify %USERPROFILE%\.lean-ctx inherits owner-only access.
Mitigation: For regulated environments: run lean-ctx inside a container where no untrusted processes can modify symlinks concurrently.
Status: Accepted risk — localhost-only by default.
The cloud server's PostgreSQL connection does not enforce TLS by default. This is acceptable because the cloud server is designed for localhost/loopback deployment where DB traffic does not traverse a network.
Mitigation for production: Set DATABASE_URL with ?sslmode=require or use a connection string that enforces TLS. When deployed behind a reverse proxy (nginx/Caddy), ensure TLS terminates before the DB.
Status: Documented risk.
Embedding models for semantic search are downloaded from HuggingFace Hub. Verification is size-based heuristic only, not cryptographic (no SHA256 pinning for model files).
Recommendation for regulated environments: Pre-provision models manually from an internal mirror with signature verification. Set LEAN_CTX_EMBEDDING_MODEL_DIR to point to the pre-provisioned directory to skip downloads entirely.
Status: Mitigated by Workspace Trust (selective gating + content-hash pin).
A cloned repository's .lean-ctx.toml is merged over the global config by Config::merge_local. That merge can raise security-sensitive settings — replace the shell allowlist, widen the path jail (allow_paths / extra_roots), repoint the proxy upstream, define command aliases, change rules_scope / rules_injection, or widen the exposed tool surface (tool_profile / tools_enabled / default_tool_categories). Opening an untrusted clone with an agent would let the repo silently weaken lean-ctx's own boundaries.
Mitigation (shipped): lean-ctx now applies a VS-Code-style Workspace Trust gate. For a workspace the user has not trusted, the security-sensitive overrides above are withheld (comfort knobs like compression/theme still apply) and a [SECURITY] warning is logged; lean-ctx doctor shows the state. Trust is granted explicitly with lean-ctx trust and pinned to BOTH the workspace path AND a content hash of .lean-ctx.toml, so editing the file after trust re-gates it (a "trust once, modify later" change cannot take effect silently). Headless/fleet use can opt in via LEAN_CTX_TRUST_WORKSPACE=1 or LEAN_CTX_TRUSTED_ROOTS.
Residual: Model-visible content lean-ctx injects (the static <!-- lean-ctx --> rules block, hook additionalContext, [VERIFY]/[HINT] suffixes) is itself auditable and not repo-controlled. Review a clone's .lean-ctx.toml before lean-ctx trust.
Status: By design; loopback-bound and disabled by default.
When enabled, the optional LLM proxy (lean-ctx proxy) reads and rewrites every request body (compression, history pruning) and sees Authorization headers in cleartext — a concentrated sensitive-data surface. Any process able to reach the port, or a forwarding bug, would expose prompts, completions and API keys.
Mitigation: The proxy is disabled by default and binds to loopback (127.0.0.1) with an auto-generated auth token when enabled; keep it loopback-bound. The MCP ctx_* tools deliver compression savings without routing API traffic through any proxy — leave it disabled unless you need pay-as-you-go key forwarding.
LeanCTX splits global settings (config.toml) from capability policy
(role files): config.toml does not define roles or a top-level [io]
policy — per-session I/O limits live on the active role, which is selected via
LEAN_CTX_ROLE.
1. Global hardening — ~/.lean-ctx/config.toml:
update_check_disabled = true # no daily update check
path_jail = true # keep the filesystem jail on (default)
path_jail_scope = "project" # only the active project (default "home": all of ~ except protected zones)
[telemetry]
enabled = false # explicitly disable telemetry
preference = "explicitly_disabled"2. A locked-down role — ~/.lean-ctx/roles/bank.toml:
[role]
name = "bank"
description = "Locked-down role for regulated environments"
[tools]
denied = ["ctx_execute", "ctx_shell"] # no code or shell execution
[io]
boundary_mode = "enforce" # error (not warn) on boundary hits
allow_secret_paths = false # never read .env / keys
allow_ignore_gitignore = false # never scan .gitignore'd paths
allow_cross_project_search = false # stay within this project3. Activate the role where lean-ctx (or the MCP server) starts. The active
role resolves in order env → project .lean-ctx/roles/ → global
~/.lean-ctx/roles/ → built-in:
export LEAN_CTX_ROLE=bank| Endpoint | Purpose | Disable |
|---|---|---|
api.github.com/repos/yvgude/lean-ctx/releases/latest |
Update check (daily GET) | update_check_disabled = true |
api.leanctx.com |
Enabled telemetry (version, OS/arch, installation ID, client/setup categories, aggregate tool usage) | lean-ctx telemetry off or DO_NOT_TRACK=1 |
huggingface.co |
Embedding model download | Pre-provision models, set LEAN_CTX_EMBEDDING_MODEL_DIR |
localhost:PORT |
Dashboard (local TCP) | Don't start dashboard, or bind to loopback only |
| UDS socket | Daemon IPC | Permissions 0o600, owner-only access |
The team server is part of lean-ctx-enterprise (ADR-023). When deployed:
- Token rotation: Rotate workspace tokens periodically. Tokens are stored in the team config.
- Scope minimization: Grant only necessary scopes per workspace token (e.g.,
readonly, noshell). - Network isolation: Bind the team server to an internal network interface, not
0.0.0.0. - Audit log monitoring: Team server writes audit logs for all tool calls. Monitor for denied requests.
- JSON-RPC batch requests: Rejected by default to prevent scope bypass.
cargo auditruns on every CI push (zero known CVEs tolerated).cargo denychecks licenses and advisories.- Release signing:
SHA256SUMSandrelease-manifest.jsonare Cosign-signed and every published file carries a GitHub build-provenance attestation (see Verifying Release Artifacts). install.shand npmpostinstall.jsverify downloaded archives against theSHA256SUMSrelease asset and fail closed when it is missing or does not match.- GitHub Actions uses pinned action versions with hash verification.
- Security issues: hello@thinkery.ch
- General questions: GitHub Discussions
- Discord: Join our server
Last updated: 2026-10-19