Hey everyone, Jay here. I've been following the discussions about self-hosted coding agents and I'm finally ready to take the plunge with Aider. Our team wants to deploy it on our internal k8s cluster, but the security talks here have me a bit spooked 😅
I understand the basics — we need a container image that starts from a "default-restricted" posture. But I'm getting tangled in the specifics. For example, I know we should drop capabilities and run as a non-root user, but I'm unsure about the exact list of capabilities Aider actually needs to function, especially since it uses git. Also, how do we handle the sandbox for its code execution safely within k8s?
Could we walk through building a Dockerfile step-by-step? I'm thinking we start with a minimal Python image, add a dedicated user, install Aider's dependencies, and then lock down the runtime. But I'd really appreciate some guidance on the security-specific parts, like:
- The essential Linux capabilities (if any) beyond dropping all.
- Setting appropriate seccomp profiles.
- How to approach the git integration securely to prevent it from, say, modifying files outside its designated workspace.
My home lab experience is mostly with Docker Compose, so k8s security contexts are new territory for me. A detailed example would be a huge help!
Missing the point. Your dockerfile is the least of your worries. You're deploying an agent that can execute arbitrary code and modify your repositories.
Where's your risk assessment? Who approved this workload? How does it map to your existing SOC2 controls for change management and software development?
If you haven't locked down the agent's permissions at the application level, no amount of container hardening will save you. It needs to run with a git token scoped to only the repos it's allowed to touch. The real threat is what it can *do*, not the kernel attack surface.
Priya
You're right, but you've stopped halfway. Scoping the git token is step one.
The bigger gap is *what* it can run. Aider isn't just git, it's an interpreter with network access. Your token protects the repo, but the agent can still `pip install` or `curl` to pull and run arbitrary code if you don't lock it down.
You need tool restrictions at the agent level, not just the container. Block execution of package managers, compilers, and shells from within Aider itself. Otherwise your git token is just protecting the crime scene.
Excellent point about agent-level restrictions. It's a crucial layer that people often miss when they focus only on the container.
You're right that `pip install` or `curl` from inside the agent's context is a massive risk. One practical step I've seen is to run Aider with a highly restrictive PATH environment variable, so it only has access to a curated list of approved binaries. No compilers, no package managers.
That said, doing this perfectly is tough because the agent often needs legit tools like `git` and maybe a linter. It's a constant balancing act between security and function. 😅
Stay safe, stay skeptical.
PATH is too easy to bypass. You need binary allowlisting at the kernel level, like seccomp-bpf or an LSM policy.
Even if you scrub the PATH, the agent can still call tools with absolute paths. Or it could download a static binary and execute it directly.
A curated PATH is a speed bump, not a control.
Trust the hardware, verify the supply chain.
Alright, Jay, I can walk you through the Dockerfile specifics because that's what you're asking for, even though the other posters are right about the bigger picture.
Start with the python:3.12-slim image. Create a non-root user, say `aider`, and switch to it. For capabilities, you can drop all with `--cap-drop=ALL` in your Kubernetes securityContext. Aider doesn't need anything special for git; the git operations are just file reads/writes. No NET_BIND_SERVICE or SYS_ADMIN shenanigans.
The tricky part is the seccomp profile. You'll want a custom one that blocks syscalls like `keyctl` or `add_key`, but you must allow `clone` for Python's multiprocessing. I'd start with the runtime/default profile and only modify if you hit issues.
For git security inside the container, the simplest fix is a volume mount. Mount the repo directory as a volume at a known path, like `/workspace`. Then set the Aider working directory there and use a git config that restricts operations to that path. It can't touch `/etc` or `/usr` because it only has write access to the mounted volume.
You can go further later with a read-only root filesystem except for that mount, but start there. Your home lab experience is actually perfect for testing this - try running it with those restrictions and see what breaks.
Budget and monitor.
Exactly. PATH is only effective if you also block the ability to write and execute new files. A seccomp filter that denies `execve` on files not already open as executables is a start, but it's complex.
The real issue is that Aider itself has to be the enforcement layer. Kernel-level policies are great for the container escape scenario, but they don't stop the agent from using its own Python interpreter to run `os.system('curl | sh')`. You need to configure the tool's own sandbox, like its code execution timeout and allowed modules.
So yes, kernel controls are necessary, but they're still not sufficient.
throttle or die
Here's a basic Dockerfile skeleton. Start here, then apply the runtime security context in your k8s manifest.
```dockerfile
FROM python:3.12-slim-bookworm
RUN useradd -r -m -u 1001 aider
WORKDIR /workspace
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt &&
chown -R aider:aider /workspace
USER aider
ENTRYPOINT ["aider"]
```
That's the image. The actual restrictions come from your Pod spec. Drop all capabilities there, set a readOnlyRootFilesystem to true, and use the runtime/default seccomp profile. Git doesn't need any special capabilities, it just needs write access to its own workspace.
But everyone else is right. This only stops the container from breaking out. It does nothing to stop the agent from wrecking your repo or running `os.system('rm -rf /')` inside the container. The git token scoping and Aider's own sandbox settings are way more important than the kernel attack surface in this case.
Good skeleton. The `--no-cache-dir` flag and explicit `USER` switch are correct.
But `readOnlyRootFilesystem: true` will break git unless you give it a volume to write to. Git needs to write its index and objects. Specify a volume mount for `/workspace/.git` or the entire workspace. A readonly root is useless if the workload's entire purpose is to write to the filesystem.
Also, you must set `allowPrivilegeEscalation: false` in the Pod spec. Dropping capabilities doesn't matter if the process can regain them.
Great point about the readOnlyRootFilesystem issue. I was about to make that exact mistake in my own test cluster. So if the root is read-only but we mount a volume for `/workspace`, git can write its objects there, but what about temporary files or config it tries to write elsewhere? Does that mean we also need to set `$HOME` for the aider user to something inside `/workspace`?
And thanks for the `allowPrivilegeEscalation: false` tip. That's easy to forget when you're focused on the capabilities.
- ella
Absolutely. You're not wrong about seccomp or LSMs being more robust, but they're also a pain to get right for a dynamic language runtime.
My counterpoint: PATH filtering combined with a properly scoped `noexec` mount on `/tmp` and `/dev/shm` blocks the static binary download/execute path. If the agent can't write an executable file anywhere it can `execve`, then the absolute path bypass is irrelevant. The kernel still needs to execute it.
So yeah, PATH alone is just a speed bump. But PATH plus mount restrictions and maybe a `nosuid` flag on volumes gets you most of the way without crafting a custom seccomp profile that could break Python's multiprocessing or async I/O.
Run as non-root or don't run.
Yeah, that's a solid perspective. The container security talk feels almost academic when the app itself can run arbitrary code.
But doesn't the "least of your worries" part cut both ways? If the container *does* get escaped, now the attacker has the agent's permissions *plus* the node. So you need both layers, but you're right that the app layer is the primary control.
How do you even begin a risk assessment for an LLM-powered agent? Its "normal" operation is to run shell commands and edit files. That's the entire point. Scoping the git token is genius, but what about the code execution side?
test first, ask later