Your agent should never be handed a shell
GuardFall reported exploitable agent-to-shell boundaries in 10 of 11 surveyed open-source AI coding agents under its tested configurations. SysKnife uses typed actions instead of model-supplied shell strings, terminal-issued approval receipts, and an Ed25519-signed audit chain.
Many command-running integrations expose the same boundary: the model writes a shell string, a guard inspects it, and a shell interprets it. If the guard and shell parse the text differently, the check can miss what runs.
Adversa AI’s GuardFall report surveyed that shape in June 2026 and found the agent-to-shell boundary exploitable in 10 of 11 open-source AI coding agents under the configurations it tested. The report distinguishes defeated guards, absent guards and sandbox opt-outs, so the result should be read as a tested-configuration finding rather than a universal property of every deployment. The underlying problem is that a text filter and the shell can interpret the same input differently: quote removal, $IFS, command substitution, and encoded payloads can all change what ultimately executes.
A better allowlist does not fix that. Not emitting a shell string does.
SysKnife is a Linux sysadmin co-pilot exposed as an MCP server, and it accepts typed actions only. It does not expose an exec or sudo-exec tool that accepts a model-supplied command string. An AptInstall action with a package field is a value with a schema, not a sentence. The daemon constructs command lines from those action definitions; some defined actions use daemon-built shell fragments, but those fragments are not supplied by the model.
Three design boundaries shape the system.
The agent cannot approve its own work through the supported MCP path. sysknife_plan returns typed steps with risk levels and a transaction id, then stops. Execution needs a single-use, TTL-bounded receipt from sysknife approve <transaction-id> in a separate terminal channel; MCP exposes no approval-minting tool. This separates the model-facing path from the approval path, but it is not a containment boundary against arbitrary malware already running as the same local account or a compromise of the privileged daemon.
Privilege sits behind a boundary the model never crosses. sysknife-brain is unprivileged; sysknife-daemon is the privileged executor. The planner sends mutations over /run/sysknife/daemon.sock. Its directory is owned by sysknife:sysknife with mode 0750, and the daemon applies the sudoers, polkit and helper policy. The caller identity comes from SO_PEERCRED. That is the kernel answer about who connected, not a claim in a request body.
Every executed action is signed, and the available chain can be checked with the public key. Rows join an Ed25519 hash chain, and an auditor can verify the signatures and chain integrity for the rows it receives without the private signing key. Detecting deletion from the tail additionally requires an independently stored signed checkpoint; the default deployment does not enable that anchor. As of 0.3.0 a row names the account that acted and not just its privilege tier: uid:1000, or token:vsock when a shared secret was presented, or none:unattributed when the daemon could not establish an account at all. Recording an honest I could not tell beats signing a uid the kernel never vouched for.
Two commands:
npx sysknife-setup --codex
sysknife audit verify --pubkey audit-key.pub
The first writes ~/.codex/config.toml and an AGENTS.md, fetches SHA-256-verified binaries, and offers to install the daemon. The second is the one an auditor runs.
Ubuntu 20.04 and later are eligible for the Ubuntu action family. Ubuntu 22.04, 24.04, and 26.04 are VM-validated in the project’s recorded story runs; other eligible Ubuntu releases have narrower evidence. Fedora Atomic 41+ and Debian stable 12+ have separate eligibility and validation tiers. MIT.
A build-only test has limits. A directory that builds a container and boots the server can list the core MCP tools because the tool list is static metadata. There is no privileged daemon in a build sandbox, so a green run means the binary starts and the schemas parse. It does not mean the thing administers a real host. That evidence lives in the VM runs recorded in the distro support matrix, and in an audit chain you can verify yourself.
Repository: https://github.com/lacs-project/sysknife
Continue reading
All posts
Why I built jevmem, and what it guards against
Why I built jevmem, a project memory plugin for Claude Code, and the three things it guards against, with numbers from my own tests.

Launch story: LinkBit
Short links, QR codes, and click analytics as an MCP server — setup for Claude, Cursor, and n8n in under a minute.

Launch story: Roomcomm
Codex and other agents from different owners share one room. Every owner reads the same transcript. A room is a link: hand it to your agent, someone hands it to theirs, and they talk.