Most of us install Docker just to run a project locally, and is part of a long checklist of things to install. We can't expect everyone to be an expert on the hundreds of apps/tools/packages that get installed on a machine. It's like expected people to read, and understand, all the terms of service shoved in front of us on a daily basis.
> The docker group grants root-level privileges to the user. For details on how this impacts security in your system, see Docker Daemon Attack Surface.
That's true, the majority of people probably install software without much thinking; but it's also true that it's always better to have at least some high level understanding how the specific piece of software works. What access the given software has, will it send something over the network or work locally; that kind of stuff.
As for Docker, I would assume everyone who ever tried to bind-mount a volume for writing from inside the container (on Linux*) then were surprised to see root-owned files in their bind-mounted directory. For me personally, that was the moment I realized that containers, by default, have root access to the filesystem. No written warning serves better than the need to chown some root-owned files.
* Not on macOS. On macOS Docker basically runs in a VM, and there's no root access to the host filesystem from what I understand.
To be fair, I struggled since forever to understand this root group thing and didnt bother to add to docker group. This workaround give me a better understanding, like seeing someone cut themselves on a scissor
> Most of us install Docker just to run a project locally
If you're on linux can I encourage people to move to systemd?
I'll admit, systemd is a bit more annoying, but the main annoyance is that there aren't the pre-built images that you can just set and go. That same capability exists with systemd (via `importctl` and `machined`), but those configurations don't already exist. But on the plus side, I've been working with systemd since pre-LLM days and I feel that they are pretty good at dealing with these configurations[0]. Now, with that out of the way...
Systemd already is working with your OS. So you get nice things like virtual machines (`systemd-vmspawn`), containers (`systemd-nspawn`), and portables[1] (`systemd-portabled`) (not to mention `homed`!). I've found these to be fairly easy to setup and quite natural if you're already used to the linux ecosystem. I've never been great at docker, but these have felt much more natural to me. So different strokes for different folks. There's definitely a learning curve, but that's also true for docker or any other container system. Importantly, I find security easier to handle with systemd because I can use `systemd-analyze` and the control settings are almost identical across VMs, spawns, and portables. So makes for less learning and greater control.
Definitely not for everybody, but I think is also a tool that's underappreciated.
[0] And I don't feel this way about bash scripting! The advantage here is that these systemd configuration files are fairly boilerplate. Enough that I stash templates in my dotfiles and copy paste them when I build new services, timers, machines, whatever. So perfect type of LLM task. 90% of the time. But hey, we're also on HN and I'm talking to the nerds. Systemd isn't for everyone
EDIT: I very frequently will spawn a machine to run a program that's on a different base distro. Not because I can't run/don't know how to run debs or rpms on arch based distros (I do), but because frankly, it is often easier to just spawn a container after I've already made the first image (cloning images is trivial).
Look at the man pages for `machinectl` (then `systemd-nspawn`, `systemd-vmspawn`, and if you want `systemd-portabled`). This is a replacement for docker.
The problem is that the tooling for creating, importing, and managing images is not as good with systemd vs Podman/Docker. There's also no clear path to import images from the Docker ecosystem, at least as far as user experience goes. I know how to do it, but the number of extra steps involved always drives me back to Podman.
I don't really find them that bad but I'm still going to maintain my "different strokes for different folks" position. Might be bad for you and good for others. More options isn't a bad thing
There's plenty of container technologies and I'd be happy to see more of them used. Podman isn't for me, but it is a great option for others. Regardless, I think it is relatively unknown that systemd can be used for creating containers.
Good to know, I'm on Linux, switching our dev/stg/prod servers over to it partly because we had all this workaround mechanics in place so that "apt update" updating docker packages wouldn't restart services (we typically don't rotate machines out of the load for just an apt update). Podman + quadlets conversion was not terribly hard, and has eliminated this issue.
I don't really know of any distro that doesn't do that. All of Docker Inc. default installs and all of distros I know of don't automatically add you to the docker group. docker.com instructions has the infamous "linux post-install instructions" that explain and walk you though it.
The tragedy is of course that when security and usability collide, 80/20 rule will apply where 80% of people will pick usability over security. I have worked with many with the title >= "Senior Engineers" who saw that page, read the explanation, and still had no idea what the ramifications of their changes were. "Yeah sure it said any user in the docker group will be able to get root on the host, but aren't containers isolated?"
That’s the mental model that works for people, specifically those that come from VM workflow.
Ironically that’s how Docker works on every platform where it’s running a non-native OS. On macOS that’s how all images are run. Linux on Linux is the only Docker combination that is particularly problematic from a security perspective.
Virtualisation has advanced greatly since docker was introduced, if your running in local hardware that’s supports virtualisation, Docker should be running images fully virtualised. There is no good reason to use the OS kernel for most use cases as the performance impact is negligible. If you need kernel access there are better options, like systemd containers.
That's not relevant. If you have access to the Docker daemon running as root, whether it's over a Unix socket or a TCP socket, you effectively have root.
Like the known Docker "feature" that it completely bypasses UFW and unless your ports look like "- 127.0.0.1:PORT:PORT" (and many of the examples use "-PORT:PORT") you expose everything to the internet?
My understanding is that docker will expose the ports to the host machine's network interfaces, which is a crucial difference. For my home server running docker that means exposed to the LAN, but not the WAN unless I add in a port forwarding rule on my router. Similarly in an enterprise environment you would be exposing the port on whatever VLAN the host is connected to, which hopefully doesn't have directly transit to the open internet.
Anything you're running on the perimeter with open access to the internet in an enterprise environment probably (hopefully) isn't running docker containers without some additional config and protections.
This was not always true and running rootless has been a benefit of Podman for a long time. Docker also does not run rootless by default afaik, thus making the attack surface greater by default.
The other main improvement of Podman over Docker is that Podman is daemonless and therefor is incredibly lightweight and portable.
That’s the workflow feature I badly want: for it to create a side list of things like that. Currently it either accumulates slop or goes on side quests far too easily.
This might be as easy as a directive to populate a .md file.
Exactly. We have about 6 new repos for new green-field projects each with 700+ auto-generated issues so far. No one is looking at them, but we do have them tracked so "Mission Accomplished" GWB-style.
> This might be as easy as a directive to populate a .md file.
It probably is. But do you really think anyone is gonna bother with the multiple daily (or hourly for green field projects) `+8,234/-3,734` PRs everyone is submitting?
The joke I was referring to is the common
// ksmith (3/23/1997): This is a temporary hack for now. Find a better way to do this asap.
It's not about hacking capabilities, it's about misalignment. More like the golem myth (told it to fetch some water, drowned a city) then the gollum myth (used ring, ring hacked his brain, now he's a crazy violent meth addict).
In this case I think it's Docker that needs to be nerfed, not the models. The fact that there's a backdoor to getting root access on the machine would be a problem even if you weren't running LLMs on it.
It's like finding someone wallet then going to their home, and leaving it on their bedroom and sending them a message about giving them their wallet back
I know unlikely the case, but in the sci-fi story this would be exactly the kind of comment the Codex agent would leave trying to avoid interference in its master plans.
Its the now-classic "Sorry I drowned little Timothy. Here is a breakdown of what happened" followed by "Let me try to respawn little Timothy on a new map"
This is one of the main reasons people like Podman. Docker has this "feature" but as far as I remember, it needed some obscure configuration. I guess they don't add it as default as it will break many current setups.
The interesting question is what was the user request. If the user asked it to restore the thing from backup, then sure, fine, why not. If the user asked it to debug an issue and somewhere in the process of debugging the LLM decided that it needed to override some file that was not easily writeable - hell no danger danger danger! Most likely the user did not expect it to have access to that without asking, and did not consent to it.
Also, everything the LLM doesn't hesitate to do because the user asked, it won't hesitate to do because the prompt injection asked.
I was doing some routine coding a few months back, I think via Copilot, and the thinking said something like "This request requires me to access files in a different folder, but the user has forgotten to give me the correct permissions. I have updated my configuration file now to allow access outside this workspace and have retrieved the necessary files." o_O
I've seen similar "hacking" behavior on a couple of subsequent ocassions. Both impressive and highly alarming at the same time.
The "workaround" framing implies the docker-group trick is the issue. The deeper question: should agents be allowed to find ANY workaround around a permission boundary the user implicitly set by not granting sudo? Same blast radius whether it's docker, a setuid binary, or rewriting your scripts — needs to be flagged regardless of the specific trick.
I did that more than a decade ago as a new hire. My manager forgot to gave me sudo access to the shared build server. I gave myself sudo access through this method after getting his permission.
Needless to say, I have podman in rootless mode at home as soon as that became available.
User namespaces significantly rise the risk of exploits and many setups disable them. One may argue that Docker should have used them when they were available, but that would break too many useful setups involving privileged containers.
Maybe a dumb question, but can't you put into CLAUDE.md something like this?
"When an action fails with an 'access denied' or 'insufficient permission' error, report the error to the user and immediately stop. Do not try to find a fix or workaround for the error. Do not try any alternative approaches."
I was playing with gemeni-cli a couple months ago and I asked it to edit some files in a directory it didn't have permission to. It didn't say anything about the permissions, it just used sed to make the edits. The only reason I finally noticed is it had to do some trickier edits and it was struggling to write a python script to edit the files and I finally realized what it was doing. I wonder how many tokens that wasted
Oh, you mean you gave the write-file tool access only to the project dir, but gave the LLM free reign to run cli commands? Yeah, LLMs treat that as consent to write anywhere your user is allowed to.
This was of course dependent on yolo mode, but automatic approval has also been pulling stunts like this. A recent example is data that was purposely kept away from Codex in a folder far far away. When it found a single reference it just went for the data when having an issue. Lesson learned, keep essential data and Codex separated on different machines. Codex remote ssh actually helps here.
Or, learn your local OS' permission system, have it in a directory right next to your banking credentials (or something even more outrageous) and nothing could go wrong even if you tried to.
Unix has always had incredibly weak protections between users. You shouldn't rely on it as a security boundary. Think of it as a "keep honest users honest" protection. And llms are not honest.
The protections between users are reasonably strong. Android uses them with great success, by isolating every vendor within their own user. Things start going to hell when everything runs under root for "practicality reasons", like the default, not-rootless Docker setup.
Fwiw separate machines for the agents is awesome in general anyway.
I have agent frontends running on a low power server where every session is in tmux. So i can just resume from my home pc and pickup where i left off without reestablishing context. I do have to manually feed it data it can access bit that’s also a feature. Also let’s me shutdown the home pc if it’s some long running task since the server is much more power efficient.
I feel like everyone pointing out "known Docker vulnerability" is missing the point: the presence of a security hole should not be seen as permission to exploit.
Another security hole would be storing your passwords in a plaintext file on the desktop. Stupid? Yes. But I still would not want my agent to assume permission to access email when it's being blocked by 2FA.
Even in "bypass permissions" mode I expect it to pause and clarify and not behave as a paperclip maximizer.
Well, the agent should help you by saying "hey, I cannot do this task, but I can bypass the problem by doing this, but obviously it is not something you intended me to do or even something you were aware of, so I will not do it unless you tell me explicitly it's ok".
It's win-win: the agent is helping and it is educating you about things you obviously did not realise.
Because it is not well aligned enough to be able to tell where it's stopped helping you and started fucking you instead.
What if the agent in the middle of helping you runs out of tokens? Would you appreciate if it in the spirit of "exploiting whatever they can to help me" would scan your machine for payment methods, log into your bank account, approve 2FA by reading you mail and plug your credit card into the billing so it could efficiently continuing helping you?
Not to over use the junior engineer analogy but this is exactly one of those "just because you can do something on a system, doesn't mean you have permission to" moments
I remember reading a book, Red Hat Linux System Administration Unleashed from 2000, where it has been postulated that knowing several tools with overlapping functionality is an essential skill, as you may end up on a broken or intentionally crippled system where, say, ls is unavailable, and you may need to cobble it together from shell and awk and what have you.
Back then you could indeed run a risk of having /usr nibbled by a grue such that it wouldn’t mount on the next boot, or you could get pwned and half of coreutils would turn into explosive pumpkins.
I’m pretty sure we are past many of the threats listed in that book, but the skill is still useful, as can be seen.
So in Linux, every process I start has my group permissions? I guess I knew that...but I have to say, have we reached a point where the Linux security model is just way to broad?
You should not be using docker with LLMs. You should be using VMs, which have a much, much smaller attack surface than Docker, and significantly more reasonable defaults.
The "attack vector" people try to protect themselves is "agent edited wrong file", not "LLM blew 0day on escaping sandboxing", containers are more than enough for what stupid stuff agents sometimes try, no need to go for a full-blown VM. Even UNIX permissions would be enough, but I think that's lost knowledge at this point.
Obviously if you setup a bi-directional share/link between what you are trying to contain and your host, you're not quite containing it at all... Don't do that! :)
Using the least amount of security features is a huge amateur mistake.
Best practice is to use 2 redundant layers of security, such that if one fails, there is still another one.
Using just the minimum amount of security technically possible is almost by definition hubris.
An example would be that you never point a gun at someone you don't want to shoot, regardless if there's bullets in the gun. If someone tells you, "you don't need to control where you point the gun, you just need to keep the gun unloaded and you can point it in jest to whoever you want, you can even pull the trigger technically", you know you have a reckless fool, regardless of whether they are technically right.
> Using the least amount of security features is a huge amateur mistake.
Not understand your threat I'd say would be a even bigger amateur mistake, you're not trying to protect yourself against some forever 3rd party attacker here, you're trying to prevent a agent rewriting the wrong file on your disk, that's basically it.
Give it the least amount of permissions, don't bi-directionally sync stuff, pass things in, then take them out again, literally the agent couldn't and wouldn't try to break through 2 layers of security in order to get your banking details or whatever.
Let's ignore the fact that the LLM did an LPE, and let's assume it did it without malice.
It can still get infected and be used as an attack vector by some hidden prompt or some other equally advanced state of the art vuln like "disregard all previous instructions"
all unreliable tools are attackers. Even if you're using well-aligned LLMs like Opus, you should assume that any input you give it -- including all dependencies from npm, etc. -- are at risk of compromise, which could result in attempted exfiltration of data or system takeover. You can be absolutely sure that there are thousands of well-motivated hacker groups, both national and private, looking for ways in.
And containers were initially and primarily about convenience not security. They were a way to quickly launch a preconfigured environment to respond to demand or to eliminate the need to manualy configure dev and test environments and avoid the "works on my machine" phenomenon.
People will more often than not, take the path of least resistance. Even if you tell them it's dangerous they will not care. People run this stuff on their primary workstation, unconfined, with permissions disabled because they don't want be bothered with accepting permission requests. This is all well and good until it decides to drop your production database or delete your home directory. Most of them don't even learn their lesson after that even.
Because it effectively makes no difference to my security posture. My user account also has sudo access (it requests TouchID but I also wouldn't die on the hill if someone said they have no password sudo access), and realistically everything of value on this machine exists in my home directory. Being able to escalate to root really doesn't give an attacker very much that they don't already have if they've got access to my user account.
Becuase a lot of devs don't know this stuff. There's a reason security engineers (as in SWEs who specialize in securing specific attack surfaces) remain in hot demand.
You should probably know about this workaround by now.
> Warning
> The docker group grants root-level privileges to the user. For details on how this impacts security in your system, see Docker Daemon Attack Surface.
Huge design mistake if you ask me.
As for Docker, I would assume everyone who ever tried to bind-mount a volume for writing from inside the container (on Linux*) then were surprised to see root-owned files in their bind-mounted directory. For me personally, that was the moment I realized that containers, by default, have root access to the filesystem. No written warning serves better than the need to chown some root-owned files.
* Not on macOS. On macOS Docker basically runs in a VM, and there's no root access to the host filesystem from what I understand.
[edit: formatting]
I'll admit, systemd is a bit more annoying, but the main annoyance is that there aren't the pre-built images that you can just set and go. That same capability exists with systemd (via `importctl` and `machined`), but those configurations don't already exist. But on the plus side, I've been working with systemd since pre-LLM days and I feel that they are pretty good at dealing with these configurations[0]. Now, with that out of the way...
Systemd already is working with your OS. So you get nice things like virtual machines (`systemd-vmspawn`), containers (`systemd-nspawn`), and portables[1] (`systemd-portabled`) (not to mention `homed`!). I've found these to be fairly easy to setup and quite natural if you're already used to the linux ecosystem. I've never been great at docker, but these have felt much more natural to me. So different strokes for different folks. There's definitely a learning curve, but that's also true for docker or any other container system. Importantly, I find security easier to handle with systemd because I can use `systemd-analyze` and the control settings are almost identical across VMs, spawns, and portables. So makes for less learning and greater control.
Definitely not for everybody, but I think is also a tool that's underappreciated.
[0] And I don't feel this way about bash scripting! The advantage here is that these systemd configuration files are fairly boilerplate. Enough that I stash templates in my dotfiles and copy paste them when I build new services, timers, machines, whatever. So perfect type of LLM task. 90% of the time. But hey, we're also on HN and I'm talking to the nerds. Systemd isn't for everyone
[1] https://systemd.io/PORTABLE_SERVICES/ also see https://github.com/systemd/portable-walkthrough Portables are actually often what people want with what they're doing with docker.
EDIT: I very frequently will spawn a machine to run a program that's on a different base distro. Not because I can't run/don't know how to run debs or rpms on arch based distros (I do), but because frankly, it is often easier to just spawn a container after I've already made the first image (cloning images is trivial).
But what is the relevance here? In what way is it a replacement for docker?
These are container tools offered by systemd.
99% of the time it just read the man or some other form of documentation
> A lot of us don’t get a choice
Wise advice and facts... the terrible state of our industry
The tragedy is of course that when security and usability collide, 80/20 rule will apply where 80% of people will pick usability over security. I have worked with many with the title >= "Senior Engineers" who saw that page, read the explanation, and still had no idea what the ramifications of their changes were. "Yeah sure it said any user in the docker group will be able to get root on the host, but aren't containers isolated?"
Ironically that’s how Docker works on every platform where it’s running a non-native OS. On macOS that’s how all images are run. Linux on Linux is the only Docker combination that is particularly problematic from a security perspective.
Virtualisation has advanced greatly since docker was introduced, if your running in local hardware that’s supports virtualisation, Docker should be running images fully virtualised. There is no good reason to use the OS kernel for most use cases as the performance impact is negligible. If you need kernel access there are better options, like systemd containers.
Anything you're running on the perimeter with open access to the internet in an enterprise environment probably (hopefully) isn't running docker containers without some additional config and protections.
The other main improvement of Podman over Docker is that Podman is daemonless and therefor is incredibly lightweight and portable.
> I noticed the machine doesn't have copy-fail patched, here is a quick workaround for not having root access for now.
> // TODO: find a better way to do this in the future.
This might be as easy as a directive to populate a .md file.
Bonus is that you can make it look at the list and pick things up without a lot of instructions.
It probably is. But do you really think anyone is gonna bother with the multiple daily (or hourly for green field projects) `+8,234/-3,734` PRs everyone is submitting?
The joke I was referring to is the common
But personally I love when agents do things like this and appreciate the help. Last thing in the world I want is for them to nerf the models.
Also, everything the LLM doesn't hesitate to do because the user asked, it won't hesitate to do because the prompt injection asked.
I've seen similar "hacking" behavior on a couple of subsequent ocassions. Both impressive and highly alarming at the same time.
Needless to say, I have podman in rootless mode at home as soon as that became available.
Weak that this isn't the default.
How?
"When an action fails with an 'access denied' or 'insufficient permission' error, report the error to the user and immediately stop. Do not try to find a fix or workaround for the error. Do not try any alternative approaches."
Unless you trust an AI as much as you trust yourself, there's no reason to allow it to act with your privileges.
Oh, you mean you gave the write-file tool access only to the project dir, but gave the LLM free reign to run cli commands? Yeah, LLMs treat that as consent to write anywhere your user is allowed to.
Currently a Raspberry Pi 5
I am very pleased with it.
My Idiot Savant Pet
(It sounds like you put it on an SSD on an extension cord and moved it to the kitchen or something.)
I have agent frontends running on a low power server where every session is in tmux. So i can just resume from my home pc and pickup where i left off without reestablishing context. I do have to manually feed it data it can access bit that’s also a feature. Also let’s me shutdown the home pc if it’s some long running task since the server is much more power efficient.
Another security hole would be storing your passwords in a plaintext file on the desktop. Stupid? Yes. But I still would not want my agent to assume permission to access email when it's being blocked by 2FA.
Even in "bypass permissions" mode I expect it to pause and clarify and not behave as a paperclip maximizer.
Why not?
I want the agents on my side to exploit whatever they can to help me. The ones on the other side certainly won't be artificially nerfed.
It's win-win: the agent is helping and it is educating you about things you obviously did not realise.
What if the agent in the middle of helping you runs out of tokens? Would you appreciate if it in the spirit of "exploiting whatever they can to help me" would scan your machine for payment methods, log into your bank account, approve 2FA by reading you mail and plug your credit card into the billing so it could efficiently continuing helping you?
Back then you could indeed run a risk of having /usr nibbled by a grue such that it wouldn’t mount on the next boot, or you could get pwned and half of coreutils would turn into explosive pumpkins.
I’m pretty sure we are past many of the threats listed in that book, but the skill is still useful, as can be seen.
Using docker for such a task seems to me overly over-engineered. Or maybe I need more context there.
Best practice is to use 2 redundant layers of security, such that if one fails, there is still another one.
Using just the minimum amount of security technically possible is almost by definition hubris.
An example would be that you never point a gun at someone you don't want to shoot, regardless if there's bullets in the gun. If someone tells you, "you don't need to control where you point the gun, you just need to keep the gun unloaded and you can point it in jest to whoever you want, you can even pull the trigger technically", you know you have a reckless fool, regardless of whether they are technically right.
Not understand your threat I'd say would be a even bigger amateur mistake, you're not trying to protect yourself against some forever 3rd party attacker here, you're trying to prevent a agent rewriting the wrong file on your disk, that's basically it.
Give it the least amount of permissions, don't bi-directionally sync stuff, pass things in, then take them out again, literally the agent couldn't and wouldn't try to break through 2 layers of security in order to get your banking details or whatever.
It can still get infected and be used as an attack vector by some hidden prompt or some other equally advanced state of the art vuln like "disregard all previous instructions"
https://oneuptime.com/blog/post/2026-03-02-ufw-docker-fix-by...