Remix.run Logo
qarl2 a day ago

I wonder how he imagines you can give shell access but securely prevent arbitrary command execution.

His complaint that "echo git | bash" still works is particularly nutty.

wren6991 a day ago | parent | next [-]

Sure, the two main approaches are revoking execute permission from the executable itself, and write-protecting the things that it would modify (like $PWD/.git). Both of these are achievable with sandbox-exec or landlock_restrict_self(2).

This works for the `bash` example too. Spawning a new shell and running arbitrary commands is not an escalation because the child shell inherits the parent's restrictions.

qarl2 a day ago | parent [-]

And what would prevent the LLM from downloading and compiling its own version of git? But it names it "not-git".

lucideer 21 hours ago | parent | next [-]

It's an allowlist so not-git would be disallowed by default. Renaming it to a binary that is already listed in the allowlist should fail due to a cryptographic binary signature mismatch.

qarl2 21 hours ago | parent [-]

LLM harnesses build executables and run them. That is their primary purpose.

Changing an executable's signature by inserting a single extra printf() is well within that spec.

lucideer 13 hours ago | parent | next [-]

That's a pretty oddly narrow & specific definition of what LLM harnesses are for & it certainly doesn't match my experience. In fact I'm genuinely struggling to think of any scenario where an agent CLI would need to execute a build artifact. Sure many devs might ask it to for convenience of not having to spend 3 seconds typing & running the command themselves but I can't see it ever being explicitly necessary.

I will note you used the term "harness" which - while terms around LLM tooling is still inconsistently defined - in my experience generally pertains to agentic automations: e.g. LLM CI integrations, etc. Rather than interactive local tooling like OpenCode. So maybe you're referring to that (though even then I still can't think of examples)

qarl2 13 hours ago | parent [-]

> In fact I'm genuinely struggling to think of any scenario where an agent CLI would need to execute a build artifact.

You should look into "testing". It's when you run the code you just wrote to make sure it works.

For example, in LLM harnesses, it's used to ensure the produced code has the desired properties. It is the key element needed to allow agents to continue to work until they have succeeded.

Anthropic's harness Claude Code:

https://code.claude.com/docs/en/best-practices — "Claude does the work, runs the check, reads the result, and iterates"

https://www-cdn.anthropic.com/58284b19e702b49db9302d5b6f135a... — "autonomous loops where Claude writes code, runs tests, and iterates continuously"

https://www.anthropic.com/research/long-running-Claude — "Run pytest tests/ -x -q before every commit"

https://platform.claude.com/docs/en/agents-and-tools/tool-us... — "Claude edits a file with one tool and requests the command that runs it"

https://platform.claude.com/docs/en/agents-and-tools/tool-us... — "writes Python with the file operations sub-tool and runs it with a Bash command"

OpenAI's harness Codex:

https://openai.com/index/introducing-codex/ — "can iteratively run tests until it receives a passing result"

https://openai.com/index/introducing-upgrades-to-codex/ — "iterating on its implementation, fixing test failures, and ultimately delivering a successful implementation"

Aider harness:

https://aider.chat/ — "Automatically lint and test your code every time aider makes changes"

https://aider.chat/docs/usage/lint-test.html — "run your test suite after each time the AI edits your code"

Devin harness:

https://cognition.com/blog/introducing-devin — "Devin writes and debugs code to run a computer vision model"

https://cognition.com/blog/introducing-devin-2-2 — "Devin runs through your app and sends back screen recordings"

https://cognition.com/blog — "Devin now builds, runs, and tests natively in Windows VMs"

SWE-bench harness:

https://www.vals.ai/benchmarks/swebench — "running unit tests against the generated patch"

Copilot:

https://github.blog/changelog/2025-05-19-github-copilot-codi... — "makes changes, and even validates its work with your tests and linter"

https://docs.github.com/copilot/concepts/agents/coding-agent... — "how to build, test and validate its changes"

https://docs.github.com/copilot/how-tos/agents/copilot-codin... — "If Copilot is able to build, test and validate its changes"

https://github.blog/ai-and-ml/github-copilot/github-copilot-... — "coding agent can independently write, run, and test code"

layer8 18 hours ago | parent | prev [-]

The executables built by LLMs should only given access to a restricted test environment by default.

wren6991 21 hours ago | parent | prev [-]

I mean, ideally enforce W ^ X, and enforce stricter permissions on executables where the agent has flipped the W to X. My broader point is we should be using operating system primitives instead of regex and wishful thinking.

qarl2 21 hours ago | parent [-]

I don't know what you mean by "enforce W ^ X".

You can't give shell access and then revoke special parts of it. This is not controversial.

All your criticisms apply to all LLM harnesses - and everyone who genuinely cares about these things is using security on top of the harness, because OBVIOUSLY.

Your complaints are misguided.

wren6991 21 hours ago | parent [-]

Here: https://en.wikipedia.org/wiki/W%5EX

This doesn't require cooperation from the shell. If writable paths are non-executable, and executable paths are non-writable, then executing `cp $(which git) my-new-favourite-binary` doesn't grant you permission to run it.

The part which does require cooperation (from outside of the shell, i.e. from the harness) is the ability to upgrade writable paths to executable, at the cost of writability and whatever other restrictions you place on the binaries generated by your agent.

This kind of W^X invariant is widely deployed in every desktop operating system, and the type of W-X upgrade hook I described is used by every JIT engine.

wren6991 21 hours ago | parent | next [-]

Replying inline because this hit max depth:

> You are confusing CPU-level security with filesystem-level security.

> I'm curious - how do you expect an LLM harness to build and test executables without being able to build and execute executables?

W^X applies to file systems as well as page tables, and this is called out in paragraph 4 of the Wikipedia article you didn't read. Respectfully, I'm leaving this conversation at this point because it doesn't seem productive.

qarl2 21 hours ago | parent [-]

You did not hit max depth - you hit a timer designed to prevent rage posting.

My question stands - if you accept that LLM harnesses are designed to allow the building and testing of executables - how do you imagine you can prevent the building and running of executables?

Respectfully.

qarl2 21 hours ago | parent | prev [-]

You are confusing CPU-level security with filesystem-level security.

I'm curious - how do you expect an LLM harness to build and test executables without being able to build and execute executables?

lucideer 21 hours ago | parent | prev [-]

This is very doable - it's a shell you're creating within the cli so you have a lot of control over the environment. If you look at tools like sandbox-exec & apparmor, they specifically target binaries, not string input. E.g. if I write a bash script & put it in my path, OpenCode's allowlists aren't looking at the commands my bash script is exec-ing, nor monitoring subshells it creates. A proper sandbox has full context of the execution chain. Not only that, it's potentially much more powerful & expressive in that you can allowlist indirect filesystem access from commands run.

For example, I recently ran opencode via sandbox-exec & naively granted the sandbox access to the aws cli. First attempt to exec it failed because I hadn't granted the sandbox access to the credential file in ~/.aws. This took 2 seconds to resolve but effectively highlights how utterly useless the tree-sitter string-parsing they're doing is. It's so concerning because implementing tree-sitter for that is non-trivial to the point that any competent dev should surely realise quickly while implementing it that this avenue is utterly useless. Yet every high-profile agent cli has taken this approach.

qarl2 20 hours ago | parent [-]

Yes, I am aware that sandboxing technology exists. I use them. I don't expect them to be built into my LLM harness because I value modular software composition - and sandboxing should be provided by a product that specializes in that area.

OpenCode's allowlists are not there for security. They exist for LLM behavior guidance.

lucideer 17 hours ago | parent [-]

> allowlists are not there for security

I don't honestly believe that the allowlist isn't (naively) intended to be there for security. It's certainly not a very useful ux for providing LLM guidance: prompts, memories & AGENTS.md already provide an avenue for this & having it in a formalised, structured format isn't conducive to LLM guidance. The implementation brings in a lot of dependencies (tree-sitter) & contains enough complex targeted string parsing that's definitely superfluous for something intended to be fed to an LLM as guidance. Perhaps most importantly - the LLM behaviour on encountering limits of the allowlist is neither intuitive nor consistent enough to be considered reliably guiding (& system prompt doesn't do anything to mitigate this).

> I don't expect them to be built into my LLM harness because I value modular software composition

I value software modularity, in particular where software architecture is concerned, but I wouldn't go as far as being prescriptive about the unix philosophy. Direct integration does have its pros, & most of the cons associated with it in practice are specific to bad architecture (or black box software). For example Claude cli does integrate sandbox-exec internally, but it does do in a closed-source inaccessible way that negates its value. I am confident it can be done well though, even if I'm somewhat less confident that it ever will be.

qarl2 13 hours ago | parent [-]

Well - pretty much everyone knows it's lousy security, because you know, it's pretty obvious.

But maybe some people think it's not obvious, and point it out because they think they're clever?

I suppose that's possible.