Crust fetches its installer from main, so the tagged release and the running binary disagree
🌟 Open Source AI Agent Security Infrastructure — intercepts and blocks dangerous agent behaviors before they happen. Just one command! Join us to build safer Human-AI Symbiosis!
At a glance
- What is it?
- Crust is a local Go gateway that sits between an AI agent and its LLM provider and scans tool calls before they run. It installs by piping a script from the main branch into a shell, it publishes three tagged releases that all stopped in March 2026, and its container listens on every interface while the pitch says everything stays on your machine.
- Who is it for?
- Crust is a real gateway with a real rule pipeline rather than a prompt-level filter, and it is worth a trial on a machine where a leaked key would actually hurt. Two things to settle first.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 3, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One wrap command covers three protocols and a fallback guess
The entry point table offers five rows and only two commands. `crust start` runs the HTTP proxy, which sits between the agent and the LLM API and scans tool calls in both directions: the request side, meaning conversation history, and the response side, meaning new actions the model has just proposed. The other four rows all invoke `crust wrap`: an MCP stdio gateway, an MCP HTTP reverse proxy for Streamable HTTP servers, an ACP stdio proxy for IDEs speaking the Agent Client Protocol, and an auto-detect mode that inspects both protocols at once. No row gives a flag that selects one of the four, so the distinction between wrapping an MCP server and wrapping an ACP agent is made by inspection rather than by configuration. The MCP path intercepts `tools/call` and `resources/read` in both directions, including scanning server responses for leaked secrets, which matters because a tool result is as much an exfiltration route as a tool argument. The ACP path intercepts file reads, writes and terminal commands before the IDE executes them, and the two documented invocations show how little configuration each takes:
crust wrap -- npx -y @modelcontextprotocol/server-filesystem /path/to/dir
crust wrap -- goose acpThe first wraps any MCP server that runs over stdio, and the second wraps an ACP agent, with JetBrains IDEs named as supported. All five routes run the same evaluation pipeline.
The installer is fetched from main and piped into a shell
Three installation routes are documented, and all three execute code that the machine has not seen yet. On macOS, Linux and BSD the documented command is a single pipeline that fetches a script from the main branch of the repository and runs it through bash:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/BakeLens/crust/main/install.sh)"Windows gets the PowerShell equivalent, fetching install.ps1 and piping it into iex. Docker has its own compose file or a manual build and run pair:
docker build -t crust https://github.com/BakeLens/crust.git
docker run -p 9090:9090 crustNone of these pin a version. The URL points at main, not at a tag, so two people running the same line on the same day can get different binaries, and the tags that would allow pinning stopped moving in March. The container build has the same shape, since it sets CI=true and then runs the same installer with its non-interactive flags, `--local .`, `--prefix /usr/local/bin`, `--data-dir`, `--no-font`, `--no-completion` and `--no-tui`, which means the image contents move whenever install.sh on main moves. A fourth script, install_openclaw.sh, sits at the root for one specific editor, so the installer surface is wider than the three routes the quick start shows.
Three tags in six days, then six months of nothing
The release history is v4.2.0 on 2026-03-18, v4.3.0 on 2026-03-20 and v4.4.0 on 2026-03-24, three tags inside a week. The last push to the repository is dated 2026-09-21, roughly six months later. So the version a cautious operator would pin, v4.4.0, is the code as it stood in March, while the installer everyone is told to run fetches September code from an untagged branch. That gap is not visible from the quick start, which gives no version command and no upgrade note; the only runtime commands shown are:
crust status # Check if running
crust status --agents # Detect running AI agents and protection status
crust logs -f # Follow logs
crust doctor # Diagnose provider endpoints
crust stop # Stop crustNone of those prints a version, so a running gateway cannot be traced back to a commit from its own interface. What can be pinned is the repository state, which means checking out v4.4.0 and building it yourself rather than trusting the branch.
Fifteen agent configs across two URL shapes and two config styles
The agent setup section covers more than a dozen clients, and the entries are not uniform. Claude Code is pointed with `ANTHROPIC_BASE_URL=http://localhost:9090`, and OpenClaw is pointed with `baseUrl` set to the same bare host inside `~/.openclaw/openclaw.json`. Everything else gets the `/v1` suffix: Codex CLI through `OPENAI_BASE_URL`, Aider through `OPENAI_API_BASE`, OpenCode through `OPENAI_BASE_URL`, Continue through `apiBase`, Zed through `api_url`, Tabby through `api_endpoint`, avante.nvim through `endpoint`, codecompanion.nvim through `url`, and any OpenAI-compatible agent through its base URL. Cursor, Cline, Windsurf and JetBrains AI are instead given as settings paths, since those clients have no environment variable to set. Two gaps are worth naming. Clients that send `/api/v1/...` paths, which the text attributes to some JetBrains configurations, are handled by a compatibility path rather than a documented URL. And providers with non-standard base paths, OpenRouter at `https://openrouter.ai/api` being the named example, need the `--endpoint` flag, so the zero-configuration claim holds only for the default shapes.
The container listens on every interface while the pitch says local
The headline is that everything is 100% local and no data ever leaves the machine, and the proxy itself does run on the operator's host. The container path is where that gets interesting. The image entry point is `crust start --foreground --auto --listen-address 0.0.0.0`, and the compose file publishes 9090:9090, so the gateway is bound to all interfaces inside the container and mapped to the host rather than to loopback. The image runs as a non-root user created with uid 1000, exposes 9090, and health-checks itself with a curl against `localhost:9090/health` every 30 seconds with a 3 second timeout and 3 retries, so the container will restart-loop on a gateway that accepts the port but stops answering. The same compose file passes `OPENAI_API_KEY` in as an environment variable and mounts `./config.yaml` read-only into the data directory, with `restart: always` and `tty: true` set on the service. Local therefore means local to the host, and on a host reachable from the network the proxy is an unauthenticated LLM relay carrying the operator's own key, with a firewall as the only boundary. The claims about locality and about auth being passed through are both true at once: `crust start` forwards whatever credentials the agent already had, and the request still has to reach the provider, which is not on that machine.
Eight pipeline steps and not one published latency number
Every entry point runs the same pipeline: self-protection, input sanitization, Unicode normalization, obfuscation detection, DLP secret scanning, path normalization, symlink resolution, and rule matching, with the whole thing described as taking microseconds per step. No figure is attached to that number, and the repository does not publish one, so the latency claim cannot be checked against the interception it sits in front of. The design choices are more informative than the timing. Unicode normalization and obfuscation detection sit before rule matching, which means the rules see a normalized form rather than raw input. Path normalization and symlink resolution sit before matching too, which is the part that decides whether a path rule can be walked around with a relative path or a link. DLP scanning is not limited to arguments: the MCP gateway scans server responses as well. The dependencies back this up, with a gitleaks library pulled into the binary, SQLCipher for the encrypted local store that holds the activity log, and an OS keyring library for secrets.
A Go gateway with an iOS library, a Swift linter and a font folder
The root listing mixes several toolchains. Alongside the Go module, the CLI in `cmd/`, `internal/`, `pkg/` and the usual tests, there is an `ios/` directory, a `.swiftlint.yml`, a `.swiftformat` configuration and a `fonts/` directory, and the visible text says Crust ships as a native iOS 15+ library called CrustKit for embedding in mobile apps, running the same rule engine. The Go module also pulls in `golang.org/x/mobile`, so the mobile side is reachable from the server binary as well as from Swift. The font folder is not decorative: the container build passes `--no-font` because containers get no Nerd Font, which means the terminal UI is a first-class part of the binary rather than an optional extra. Other root files describe the project's own plumbing, with a `.gitleaks.toml` and `.pre-commit-config.yaml` for secret scanning, a `.golangci.yml`, a `sqlc.yaml` for generated database access, a `Taskfile.yml` in place of a Makefile, and a `tools.go` pinning tool dependencies. No licence is identified in the repository's own metadata, while a LICENSE file sits at the root, so the terms have to be read from that file rather than from the repository description.
Editorial conclusion
Crust is a real gateway with a real rule pipeline rather than a prompt-level filter, and it is worth a trial on a machine where a leaked key would actually hurt. Two things to settle first. The installer is fetched from main with no version pin, so what you install is whatever that branch holds, not the v4.4.0 tag that stopped in March 2026; fetch and read install.sh first, or build from source instead. Second, the container entry point listens on 0.0.0.0 with the compose file publishing 9090 and your API key passed in as an environment variable, so a firewall is the only thing keeping that proxy local. And check the LICENSE file directly, because no licence is identified in the repository metadata at all.
Frequently asked questions
How do I install Crust?
Three routes are documented: a bash pipeline that fetches install.sh from the main branch and runs it, a PowerShell equivalent using install.ps1, or Docker via the included compose file or a manual docker build and run. After any of them you start the gateway with `crust start`, which auto-detects the provider from the model name.
Which AI agents can be pointed at the Crust gateway?
The setup table names Claude Code, Codex CLI, Cursor, Cline, Windsurf, JetBrains AI, Continue and Aider, plus Zed, Tabby, avante.nvim, codecompanion.nvim, CodeGPT, OpenClaw and OpenCode behind a collapsed section. Most are configured with a base URL pointing at localhost:9090 or localhost:9090/v1, while Cursor, Cline, Windsurf and JetBrains are configured through settings screens.
What exactly does Crust intercept?
In HTTP proxy mode it scans tool calls in the request, meaning conversation history, and in the response, meaning new proposed actions, before they execute. In MCP mode it intercepts tools/call and resources/read in both directions, including DLP scanning of server responses for leaked secrets. In ACP mode it intercepts file reads, writes and terminal commands before the IDE runs them.
What licence is Crust released under?
No licence is identified in the repository metadata for the project, even though a LICENSE file is present at the repository root. The README text does not name the terms either, so the LICENSE file itself is the place to check before use.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/bakelens-crust)