Understand Process Controls

View as Markdown

OpenShell limits the capabilities available to managed sandbox processes. NemoClaw entrypoints retain only direct root-to-user transitions and resource-limit hooks for the paths that still consume them.

OpenShell enforces additional process-level controls not covered here, including seccomp BPF socket domain filters and a specific enforcement application order (namespace entry, privilege drop, Landlock, seccomp). Refer to the Process Controls section of the OpenShell Security Best Practices.

Capability Ownership

OpenShell owns capability enforcement for managed agent processes. The OpenClaw and Hermes entrypoints do not inspect, drop, record, or reconcile Linux capabilities. This keeps one enforcement owner for the entrypoint, later exec processes, and connect shells.

A direct container runtime can explicitly override the image user to root. That compatibility path retains the existing capsh bounding-set drop and supports NEMOCLAW_REQUIRE_CAP_DROP=1 for fail-closed verification. It is not used by OpenShell-managed launches and is not a substitute for container-runtime capability configuration.

The managed images install setpriv from util-linux and require it when the entrypoint switches from root to the sandbox and gateway users. When CAP_SETPCAP is available, the same setpriv operation removes the remaining privilege-separation capabilities from the child process at the same time as the user change. That direct root-to-user transition is separate from managed OpenShell enforcement and removes cap_setuid, cap_setgid, cap_fowner, cap_chown, and cap_kill from the child bounding set when the runtime permits it.

For root-to-user transitions, the extra bounding-set capability drop is best effort. If capsh or CAP_SETPCAP is unavailable, the root entrypoint logs a warning and uses setpriv without the extra bounding-set drop.

When a root entrypoint must change identity, it fails closed if setpriv is unavailable instead of starting an agent service as root.

For additional protection, pass --cap-drop=ALL with docker run or Compose. Refer to Review Sandbox Hardening.

AspectDetail
DefaultOpenShell owns capability enforcement for managed processes. Root-to-user transitions outside that topology still require setpriv.
What you can changeSelect the required OpenShell enforcement posture. When launching with docker run directly, pass --cap-drop=ALL at the container runtime. NEMOCLAW_REQUIRE_CAP_DROP=1 keeps the retained direct-root compatibility check fail closed.
Risk if relaxedCAP_SYS_ADMIN and CAP_SYS_PTRACE expand kernel and process attack surface. CAP_NET_RAW allows raw socket access for network sniffing. CAP_DAC_OVERRIDE bypasses filesystem permission checks.
RecommendationKeep OpenShell enforcement enabled. For direct containers, make the container runtime the capability owner and pass --cap-drop=ALL.

Gateway Process Isolation

Gateway and agent UID isolation depends on the container process topology. The stock OpenClaw image defaults to the sandbox user for OpenShell compatibility. An OpenShell-managed container has OpenShell as PID 1 and launches nemoclaw-start as a non-root process, so the supervisor, gateway, and agent all use the sandbox UID. The managed-image publication workflow explicitly sets NEMOCLAW_MANAGED_IMAGE_RUNTIME_USER=sandbox for its reviewed release images because OpenShell 0.0.116 rejects a root OCI image user. A direct container runtime can override the image user to root. That root-entrypoint topology runs the gateway as the separate gateway user and agent commands as the sandbox user.

AspectDetail
DefaultA stock Dockerfile build declares USER sandbox. The OpenShell-managed topology runs the gateway and agent under the same sandbox UID because no-new-privileges prevents the non-root entrypoint from changing users.
What you can changeOpenClaw managed and custom images must keep USER sandbox as the default for OpenShell 0.0.116. A direct container runtime outside OpenShell can still override the image user to root.
Risk if relaxedA same-UID agent can signal peer processes and can attempt to imitate the expected gateway process shape. The root managed controller prevents PID-reuse mistakes, but it cannot prove provenance against a malicious same-UID process or provide the direct root-entrypoint restart seal for mutable config.
RecommendationKeep the OpenShell-managed image user as sandbox. Use a direct root-entrypoint deployment only outside OpenShell when separate gateway and agent UIDs are required. Treat an OpenShell-managed controller that shares the sandbox UID as an authenticated lifecycle control, not as proof that the target process is trustworthy.

No New Privileges

The no-new-privileges flag prevents processes from gaining additional privileges through setuid binaries or capability inheritance.

AspectDetail
DefaultOpenShell sets PR_SET_NO_NEW_PRIVS using prctl() inside the sandbox process as part of the seccomp filter setup. The NemoClaw Compose example also shows the equivalent security_opt: no-new-privileges:true setting.
What you can changeOpenShell’s seccomp path enforces this inside the sandbox. It is not a user-facing knob.
Risk if relaxedWithout this flag, a compromised process could execute a setuid binary to escalate to root inside the container, then attempt container escape techniques.
RecommendationNo action needed. OpenShell enforces this automatically when the sandbox network policy is active. When an OpenShell-managed topology starts an entrypoint as a non-root user, this flag prevents that process from changing users.

Process Limit

A process limit caps the number of processes the sandbox user can spawn. The entrypoint sets both soft and hard limits using ulimit -u 512. This behavior is best effort. If the container runtime restricts ulimit modification, the entrypoint logs a security warning and continues without the limit.

AspectDetail
Default512 processes (ulimit -u 512), best-effort.
What you can changeIncrease or decrease the limit with --ulimit nproc=N:N in docker run or the ulimits section in Compose. The runtime-level ulimit takes precedence over the entrypoint’s setting.
Risk if relaxedRemoving or raising the limit makes the sandbox vulnerable to fork-bomb attacks, where a runaway process spawns children until the host runs out of resources. If the entrypoint cannot set the limit (logs [SECURITY] Could not set soft/hard nproc limit), the container runs without process limits.
RecommendationKeep the default at 512. If the agent runs workloads that spawn many child processes (such as parallel test runners), increase to 1024 and monitor host resource usage. If the entrypoint logs a warning about ulimit restrictions, set the limit through the container runtime instead.

Open File Descriptor Limit

An open file descriptor limit caps the number of files, sockets, and pipes the sandbox user can hold open at once. The entrypoint sets both soft and hard limits using ulimit -n 65536. This behavior is best effort. If the container runtime restricts ulimit modification, the entrypoint logs a security warning and continues without the limit.

AspectDetail
Default65536 open files, soft and hard (ulimit -n 65536), best-effort.
What you can changeIncrease or decrease the limit with --ulimit nofile=N:N in docker run or the ulimits section in Compose. The runtime-level ulimit takes precedence over the entrypoint’s setting.
Risk if relaxedWithout this cap, the sandbox inherits the Docker daemon default (nofile ~1048576). A runaway or hostile process can then open file descriptors until it exhausts them, causing a denial of service that can starve the gateway, the agent, or the host of file handles. If the entrypoint cannot set the limit (logs [SECURITY] Could not set soft/hard nofile limit), the container runs without a file-descriptor cap. For more information, refer to #4527.
RecommendationKeep the default at 65536. If the agent legitimately keeps many connections or files open, raise it deliberately and monitor host file-descriptor usage. If the entrypoint logs a warning about ulimit restrictions, set the limit through the container runtime instead.

Non-Root User

The sandbox runs agent processes as a dedicated sandbox user and group. The stock OpenClaw image starts the entrypoint as sandbox for OpenShell compatibility. A build from the managed-image publication workflow keeps the entrypoint, gateway, and agent commands under the sandbox UID for OpenShell 0.0.116. A direct runtime can override the image user to root, which lets the entrypoint separate the gateway and sandbox UIDs before it runs agent commands.

AspectDetail
Defaultrun_as_user: sandbox, run_as_group: sandbox. The stock OpenClaw image runs the entrypoint, gateway, and agent under the sandbox UID.
What you can changeChange the process section in the policy file to run as a different non-root user. Direct container runtimes outside OpenShell can override the image user to root.
Risk if relaxedRunning agent commands as root gives the agent access to modify any file in the container filesystem and increases the impact of container escape vulnerabilities.
RecommendationKeep the OpenShell image and agent commands under the sandbox user. Use a root entrypoint only in a direct-container topology outside OpenShell.

PATH Hardening

The entrypoint locks the PATH environment variable to system directories, preventing the agent from injecting malicious binaries into command resolution.

AspectDetail
DefaultThe default sandbox entrypoint sets PATH to /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin at startup. Agent-specific images may add locked read-only runtime directories, such as /opt/venv/bin for LangChain Deep Agents Code.
What you can changeThis is not a user-facing knob. The entrypoint enforces it.
Risk if relaxedWithout PATH hardening, the agent could create an executable named curl or git in a writable directory earlier in the PATH, intercepting commands run by the entrypoint or other processes.
RecommendationNo action needed. The entrypoint handles this automatically.

Build Toolchain Removal

The Dockerfile removes compilers and network probes from the runtime image.

AspectDetail
DefaultThe Dockerfile purges gcc, gcc-12, g++, g++-12, cpp, cpp-12, make, netcat-openbsd, netcat-traditional, and ncat from the sandbox image.
What you can changeModify the Dockerfile to keep these tools, or install them at runtime if package manager access is allowed.
Risk if relaxedA compiler lets the agent build arbitrary native code, including kernel exploits or custom network tools. netcat enables arbitrary TCP connections that bypass HTTP-level policy enforcement.
RecommendationKeep build tools removed. If the agent needs to compile code, run the build in a separate, purpose-built container and copy artifacts into the sandbox.

Image Digest Pinning

The managed blueprint references the sandbox image by an immutable @sha256: digest instead of a mutable tag such as :latest. A registry-side tag change cannot silently select another managed sandbox image.

AspectDetail
DefaultNemoClaw selects the managed sandbox image by its digest.
What you can changeUse the onboarding --from path when you need to build from a reviewed custom image. Locally built custom images do not use the managed registry digest.
Risk if relaxedReverting to a mutable tag (:latest) allows a registry-side change to replace the sandbox image without any blueprint update, which is a supply-chain risk.
RecommendationKeep the managed digest-pinned image unless you need a reviewed custom image. Pin the custom image’s base and dependencies before you build it.

Auth Profile Permissions

The entrypoint and migration flows enforce chmod 600 on all auth-profiles.json files under ~/.openclaw. This prevents other users on the host from reading stored credentials.

AspectDetail
Default600 permissions applied recursively at startup and after migration restores.
What you can changeThis is not a user-facing knob. The entrypoint enforces it.
Risk if relaxedLooser permissions let other users or processes on the host read provider API keys and tokens stored in auth profiles.
RecommendationNo action needed. If you see a permission denied error when reading auth profiles, verify that you are running as the same user who created them.