#757 removes 37 configuration keys from the docs that were never implemented. This issue records what, if anything, should become real — and why most of it should not.
Context
The docs promised these as [job-run] options, several under "container hardening" in SECURITY.md. Git history shows no commit ever introduced them — they were never implemented, so no working config regressed. But anyone who set them believed their jobs were constrained while ofelia discarded the lines. Operators may still be running with that assumption.
SECURITY.md also contradicted itself: its own responsibility model puts "Resource limits (cgroups, ulimits)" under infrastructure, and forty lines later it showed ofelia INI keys for exactly those. #757 removes the contradiction.
ADR-002 already decided most of this
ADR-002 (Accepted) assigns container privileges, capabilities and resource limits to the Docker daemon or orchestrator, on the grounds that ofelia is a scheduler, not a policy engine: anyone who can create a job already has docker run-equivalent access, so a flag ofelia refuses to pass buys nothing.
That reasoning holds, and it rules out capabilities-add, capabilities-drop, devices and privileged as security features. Nothing in #757 asks to reopen it.
The one case the ADR does not quite cover
The ADR says the container runtime "already has proper enforcement". For job-exec that is true — the container exists and its limits came from whoever created it. For job-run and job-service-run, ofelia creates the container from an image, so the runtime can only enforce a limit ofelia passes to it. The only remaining lever is daemon-wide defaults, which cannot differ per job.
So a memory or CPU cap on a run job is not a security control against a malicious operator — the ADR is right that this would be theatre. It is an operational safety belt against a runaway job taking down the host, which is a different argument the ADR does not address.
Whether that is worth a feature is a maintainer decision. If yes, it needs ADR-002 amended or explicitly scoped first, not a quiet addition. The plumbing is short: domain.HostConfig already carries Memory, MemorySwap, CPUShares and CPUQuota, and the Docker adapter already passes them through; core/runjob.go populates only Binds and VolumesFrom.
Out of scope regardless
dns, dns-search, labels, restart-on-failure, delete-timeout, and project/dir/environment on job-compose. This is where ofelia becomes a second container-spec DSL beside Compose and has to chase the Docker API forever. Anyone needing that much control should define the container in Compose and use job-exec.
#757 removes 37 configuration keys from the docs that were never implemented. This issue records what, if anything, should become real — and why most of it should not.
Context
The docs promised these as
[job-run]options, several under "container hardening" inSECURITY.md. Git history shows no commit ever introduced them — they were never implemented, so no working config regressed. But anyone who set them believed their jobs were constrained while ofelia discarded the lines. Operators may still be running with that assumption.SECURITY.mdalso contradicted itself: its own responsibility model puts "Resource limits (cgroups, ulimits)" under infrastructure, and forty lines later it showed ofelia INI keys for exactly those. #757 removes the contradiction.ADR-002 already decided most of this
ADR-002 (Accepted) assigns container privileges, capabilities and resource limits to the Docker daemon or orchestrator, on the grounds that ofelia is a scheduler, not a policy engine: anyone who can create a job already has
docker run-equivalent access, so a flag ofelia refuses to pass buys nothing.That reasoning holds, and it rules out
capabilities-add,capabilities-drop,devicesandprivilegedas security features. Nothing in #757 asks to reopen it.The one case the ADR does not quite cover
The ADR says the container runtime "already has proper enforcement". For
job-execthat is true — the container exists and its limits came from whoever created it. Forjob-runandjob-service-run, ofelia creates the container from an image, so the runtime can only enforce a limit ofelia passes to it. The only remaining lever is daemon-wide defaults, which cannot differ per job.So a memory or CPU cap on a run job is not a security control against a malicious operator — the ADR is right that this would be theatre. It is an operational safety belt against a runaway job taking down the host, which is a different argument the ADR does not address.
Whether that is worth a feature is a maintainer decision. If yes, it needs ADR-002 amended or explicitly scoped first, not a quiet addition. The plumbing is short:
domain.HostConfigalready carriesMemory,MemorySwap,CPUSharesandCPUQuota, and the Docker adapter already passes them through;core/runjob.gopopulates onlyBindsandVolumesFrom.Out of scope regardless
dns,dns-search,labels,restart-on-failure,delete-timeout, andproject/dir/environmentonjob-compose. This is where ofelia becomes a second container-spec DSL beside Compose and has to chase the Docker API forever. Anyone needing that much control should define the container in Compose and usejob-exec.