Summary
On Ubuntu 24.04, openshell-gateway.service (the systemd --user unit shipped by the
openshell package) cannot create a usable user namespace: AppArmor transitions the
unconfined gateway process into the stock unprivileged_userns profile and then denies
CAP_SYS_ADMIN inside the namespace. As a result the gateway's sandbox setup fails and no
sandboxed command can run.
This is the Ubuntu 24.04 default kernel.apparmor_restrict_unprivileged_userns=1 behavior,
and OpenShell currently ships nothing to accommodate it.
Environment
- Ubuntu 24.04, kernel
6.17.0-35-generic, x86_64
openshell 0.0.40-1 (from the .deb)
kernel.apparmor_restrict_unprivileged_userns = 1 (distro default)
Symptom
The consuming sandbox client fails when setting up the namespace, with:
write /proc/self/setgroups (nested userns is capability-restricted;
caller must provide CAP_SYS_ADMIN): Permission denied
Root cause (kernel audit evidence)
At the moment of failure, dmesg / the audit log shows the gateway being launched and its
user-namespace creation transitioned, immediately followed by a CAP_SYS_ADMIN denial:
apparmor="AUDIT" operation="userns_create" class="namespace"
info="Userns create - transitioning profile" profile="unconfined"
comm="(-gateway)" execpath="/usr/lib/systemd/systemd-executor"
target="unprivileged_userns"
apparmor="DENIED" operation="capable" class="cap"
profile="unprivileged_userns" capability=21 capname="sys_admin"
Two contributing factors:
-
Unconfined → unprivileged_userns transition. Because the gateway runs with no
AppArmor profile, Ubuntu 24.04's apparmor_restrict_unprivileged_userns=1 transitions it
into the restrictive unprivileged_userns stub on userns_create, which strips
CAP_SYS_ADMIN — exactly what's needed to write setgroups and set up the sandbox
mounts.
-
PrivateTmp=true on a user service compounds it. openshell-gateway.service sets
PrivateTmp=true. For a systemd --user (unprivileged) manager, honoring PrivateTmp
requires creating a mount namespace, which in turn forces creation of a user
namespace at service launch — so the gateway hits the restriction even before its own
logic runs.
Note that the documented Ubuntu 24.04 remedy of adding an AppArmor profile for
/usr/bin/bwrap does not help here, because the binary creating the failing namespace
is systemd-executor launching the gateway unit — not bwrap.
Suggested fixes (any one unblocks it; ship-side preferred)
-
Ship an AppArmor profile for the gateway binary that grants userns, so it isn't
transitioned into unprivileged_userns. e.g.:
# /etc/apparmor.d/openshell-gateway
abi <abi/4.0>,
include <tunables/global>
profile openshell-gateway /usr/bin/openshell-gateway flags=(unconfined) {
userns,
include if exists <local/openshell-gateway>
}
-
Drop / make optional the namespace-requiring directive in the user unit (e.g.
PrivateTmp=true) so systemd --user doesn't need a user namespace just to launch the
gateway. The gateway's persistent state already lives under StateDirectory, not
/tmp.
-
Document the Ubuntu 24.04 requirement and detect/log it clearly at startup, since the
downstream error (setgroups / CAP_SYS_ADMIN) is opaque and points users at the wrong
component (bubblewrap).
Workaround used
Removing the package (apt remove openshell) and falling back to the other sandbox runtime
present on the host restored command execution. The global AppArmor restriction was left
untouched, confirming the gateway's namespace setup was the failing element rather than the
kernel policy needing to be disabled.
Additional notes
A per-host setup may have two agent-sandbox runtimes installed at once (OpenShell plus
another). When OpenShell's gateway is broken as above, it can break sandboxed command
execution on the host. Clearer startup diagnostics (suggestion 3) would make this much
faster to attribute.
Summary
On Ubuntu 24.04,
openshell-gateway.service(thesystemd --userunit shipped by theopenshellpackage) cannot create a usable user namespace: AppArmor transitions theunconfined gateway process into the stock
unprivileged_usernsprofile and then deniesCAP_SYS_ADMINinside the namespace. As a result the gateway's sandbox setup fails and nosandboxed command can run.
This is the Ubuntu 24.04 default
kernel.apparmor_restrict_unprivileged_userns=1behavior,and OpenShell currently ships nothing to accommodate it.
Environment
6.17.0-35-generic, x86_64openshell0.0.40-1(from the.deb)kernel.apparmor_restrict_unprivileged_userns = 1(distro default)Symptom
The consuming sandbox client fails when setting up the namespace, with:
Root cause (kernel audit evidence)
At the moment of failure,
dmesg/ the audit log shows the gateway being launched and itsuser-namespace creation transitioned, immediately followed by a
CAP_SYS_ADMINdenial:Two contributing factors:
Unconfined →
unprivileged_usernstransition. Because the gateway runs with noAppArmor profile, Ubuntu 24.04's
apparmor_restrict_unprivileged_userns=1transitions itinto the restrictive
unprivileged_usernsstub onuserns_create, which stripsCAP_SYS_ADMIN— exactly what's needed to writesetgroupsand set up the sandboxmounts.
PrivateTmp=trueon a user service compounds it.openshell-gateway.servicesetsPrivateTmp=true. For asystemd --user(unprivileged) manager, honoringPrivateTmprequires creating a mount namespace, which in turn forces creation of a user
namespace at service launch — so the gateway hits the restriction even before its own
logic runs.
Note that the documented Ubuntu 24.04 remedy of adding an AppArmor profile for
/usr/bin/bwrapdoes not help here, because the binary creating the failing namespaceis
systemd-executorlaunching the gateway unit — notbwrap.Suggested fixes (any one unblocks it; ship-side preferred)
Ship an AppArmor profile for the gateway binary that grants
userns, so it isn'ttransitioned into
unprivileged_userns. e.g.:Drop / make optional the namespace-requiring directive in the user unit (e.g.
PrivateTmp=true) sosystemd --userdoesn't need a user namespace just to launch thegateway. The gateway's persistent state already lives under
StateDirectory, not/tmp.Document the Ubuntu 24.04 requirement and detect/log it clearly at startup, since the
downstream error (
setgroups/CAP_SYS_ADMIN) is opaque and points users at the wrongcomponent (bubblewrap).
Workaround used
Removing the package (
apt remove openshell) and falling back to the other sandbox runtimepresent on the host restored command execution. The global AppArmor restriction was left
untouched, confirming the gateway's namespace setup was the failing element rather than the
kernel policy needing to be disabled.
Additional notes
A per-host setup may have two agent-sandbox runtimes installed at once (OpenShell plus
another). When OpenShell's gateway is broken as above, it can break sandboxed command
execution on the host. Clearer startup diagnostics (suggestion 3) would make this much
faster to attribute.