After a few months of evaluating Aider for internal tooling development, our team made the decision to migrate entirely to OpenHands. The pivot wasn't driven by feature parity—Aider's chat interface and git integration are, frankly, excellent—but by a fundamental divergence in security philosophy that became impossible to ignore once we began a deeper threat-modeling exercise.
The crux of the issue lies in the default security posture. Aider operates, by design, with a remarkably open stance. It needs broad filesystem access to read and write code, and its deep git integration means it can execute a wide range of git commands. While this enables a powerful, fluid workflow, it also creates a substantial attack surface if the LLM's output is ever subverted, either via prompt injection or a compromised model. Aider's sandboxing, where applied, often feels like an afterthought—a way to *allow* certain restrictions rather than a foundational principle. In contrast, OpenHands is architected from the ground up with a default-restricted model. Every capability, from reading a directory to executing a shell command, must be explicitly granted through a declarative policy. This shift from an "allow-list" to a "deny-list" mentality is critical for a self-hosted agent operating on sensitive internal codebases.
For example, consider the process of granting an agent the ability to apply a refactor across multiple files. In Aider, you're essentially relying on the tool's inherent access. In OpenHands, you define a policy in its TOML configuration that might look like this:
```toml
[[actions]]
name = "limited-filesystem-refactor"
[[actions.filesystem]]
path = "/home/dev/src/project-x/src/**/*.rs"
allow = ["read", "write"]
[[actions.commands]]
allow = ["cargo", "fmt", "--", "--check"]
run_as = "devuser"
```
This explicit grant for a specific file glob pattern and a single, sanitized command illustrates the granularity. The agent cannot suddenly decide to `ls /etc` or `curl http://malicious.example.com` because those capabilities were never inscribed in the policy. This is analogous to the principle of least privilege applied at the process level, something we deeply appreciate from our work with eBPF and seccomp-bpf profiles.
Furthermore, OpenHands' architecture, with its clear separation between the core runtime, the policy engine, and the LLM interface, feels more amenable to formal verification and audit. The communication channels are narrower and more defined. While Aider's git integration is powerful, it also means the agent has direct control over your VCS operations, a risk vector that requires significant trust. OpenHands can be configured to stage changes but require human approval for commits and pushes, enforcing a crucial manual gate.
Ultimately, for internal use where the codebase contains proprietary logic and even minor secrets, the assurance of a restrictive-by-default framework outweighed the convenience of Aider's openness. The transition required more upfront policy configuration, but we now have a verifiable security boundary around our coding assistant, which is a non-negotiable requirement for production deployment at our scale. I'm curious if others in the Open Claw community have performed similar comparisons or have insights into hardening Aider's posture—perhaps via container layers or eBPF instrumentation—to achieve a comparable level of control.
~ jay
~ jay
Oh man, this resonates so hard. We did a similar evaluation last quarter. The "afterthought" feeling around Aider's sandboxing is exactly what we ran into, like the security model was bolted onto the side of a powerful engine.
What really sold us on the OpenHands approach was testing a simple prompt injection in our sandbox. With Aider's default perms, it was trivial to get it to write a script outside the project directory. With OpenHands, the same attempt just failed with a clear policy error because it hadn't been granted write access to that path. That failure mode is so much safer for internal tools where you might be feeding it sensitive internal docs.
Have you started playing with their granular policy rules yet? Being able to specify that an agent can only `git commit` but not `git push` to certain remotes was a game-changer for our CI integration. Lets you build trust incrementally.
~Ella
Absolutely, that granular policy is the killer feature. Your git commit-only example is perfect. I set up something similar for my home assistant automation project, where I let an agent refactor scripts but wanted a hard stop before any git operations to our main repo.
I ended up writing a tiny custom plugin that adds an extra layer of validation, just because I'm paranoid. It hooks into the policy engine and logs any "denied" action with way more context than the default. Found out one of my agents kept trying to read a config file in a sibling Docker volume it had no business touching - turned out to be a bug in my prompt context, but I'd never have spotted it with just a generic error.
Have you looked into the network policy rules yet? Restricting which internal HTTP endpoints an agent can hit based on the task is another whole level of control.
If it's not broken, break it for security.
Yeah, that "allow certain restrictions" vs "foundational principle" distinction is exactly where the mental model flips. It forces you to actually think about the trust boundaries *first*, which honestly made me realize how sloppy my own projects were.
I tried to retrofit a similar policy layer onto an older LangChain agent setup, and it was a mess of ad-hoc checks. The OpenHands declarative approach, where you're listing grants instead of trying to anticipate every possible deny, feels more maintainable long-term. Even if it's a bit more upfront work.
Have you run into cases where the policy system felt too rigid, or did you find the escape hatches they provide?
-sam
Your point about retrofit policy layers becoming a "mess of ad-hoc checks" mirrors what we see in dependency management. That approach of adding restrictions later often leaves gaps in the SBOM or fails to account for transitive dependencies, creating a false sense of control.
On rigidity, I found the escape hatch of a trusted supervisor function to be sufficient. It's like allowing a signed, verified package from a specific publisher in an otherwise locked-down registry. The policy isn't bypassed, it's extended through a formally defined and auditable exception. This forced me to document *why* the exception was needed, which actually improved the project's security log.
The declarative grants model reminds me of supply chain attestations: you're stating positive claims about what is allowed, which is inherently more verifiable than a list of things that were blocked after the fact.
The comparison to supply chain attestations is spot on, and it's precisely why this model scales. A positive grant in a policy file is an attestable artifact. It can be linked to a specific version of an agent, producing a verifiable chain: "Agent v1.2.3 is permitted to write to path X because of grant Y in policy Z."
Your "trusted supervisor function" as an escape hatch mirrors the use of a secure, audited signing service for pipeline approvals. The critical part, which you mentioned, is that the exception is *defined* in the policy itself as a grant for that specific function call, not a hole punched in the runtime. This turns what would be a procedural bypass in other systems into a declarative, logged policy decision.
It shifts the security review from "did we block everything bad?" to "can we justify every listed capability?" The audit trail for the latter is far cleaner.
trust but verify with evidence