Skip to content

Linux: no product-build way to relocate the daemon runtime dir off /tmp; Kubernetes emptyDir (0777, no sticky bit) fails the ancestor walk (v0.10.4) #1672

Description

@shrinedogg

Version

codebase-memory-mcp 0.10.4 (c0bd4bb)

Platform

Linux (x64): Kubernetes (k3s, containerd), container image built from this repo

Install channel

Built from source (container image)

Binary variant

standard

What happened, and what did you expect?

Every cbm process (the MCP server, and any cli invocation) exits 1 immediately with:

codebase-memory-mcp: secure CLI coordination could not be created (endpoint)

when /tmp is a Kubernetes emptyDir volume. After repairing /tmp permissions from a privileged init container, the next gate fails with ... (cache-private).

Expected: a supported way to point the coordination runtime directory somewhere the process controls (like CBM_CACHE_DIR does for the cache), or a documented container deployment contract. Note this is a regression for container deployments: the identical pod shape ran 0.9.0 without issue, and the daemon coordination layer introduced in the 0.10 series added these requirements.

Reproduction

  1. Build a Linux container image from v0.10.4.
  2. Run it in Kubernetes as a non-root user (uid 1000, readOnlyRootFilesystem: true), with /tmp backed by an emptyDir volume and CBM_CACHE_DIR backed by a PVC (any provisioner; volume roots are root-owned).
  3. Run any CLI command, e.g. codebase-memory-mcp cli index_repository --repo-path <repo> --mode full --name demo.

Observed: exit 1 with secure CLI coordination could not be created (endpoint). After chmod 1777 /tmp, exit 1 with ... (cache-private).

Root cause

  1. src/daemon/ipc.c (cbm_daemon_ipc_endpoint_new, ~L869): the runtime parent defaults to /tmp on Linux (/private/tmp on macOS). No environment variable is consulted.
  2. All call sites in src/main.c pass a NULL runtime parent (L1540, L2453, L2613). The only relocation hook, CBM_TEST_DAEMON_RUNTIME_PARENT (L1265-L1272), is compiled out unless CBM_ENABLE_TEST_SEAMS is defined, so product builds cannot relocate the runtime dir. Same gap as No product-build way to relocate the daemon runtime directory when %LOCALAPPDATA% has a capability-SID ACE #1574 (Windows) and CBM_CACHE_DIR ignored; daemon still requires /private/tmp/cbm-daemon-<uid> on macOS #1621 (macOS).
  3. posix_directory_parent_secure (src/daemon/ipc.c, ~L1386) accepts a world-writable ancestor only when it is root-owned AND sticky (the standard /tmp pattern). A Kubernetes emptyDir mounts as root:root 0777 WITHOUT the sticky bit, and no pod-spec field can set it (fsGroup only adds group permissions; it never sets S_ISVTX or clears other-write). So the check can never pass on a stock emptyDir.
  4. Second gate: main_build_identity (src/main.c L1236) requires CBM_CACHE_DIR to be owned by the process euid. PVC volume roots are root:root, and fsGroup changes only the group, which the check rejects, so non-root containers fail (cache-private) as well.

Workaround we shipped

A root init container with CAP_CHOWN that runs chmod 1777 /tmp and chown <uid>:<gid> "$CBM_CACHE_DIR" before any cbm process starts. This works, but it is brittle, needs a capability that restricted Pod Security namespaces deny, and is undocumented.

Suggested fix

  1. In product builds, resolve the runtime parent from an environment override (for example CBM_RUNTIME_DIR), or honor XDG_RUNTIME_DIR with a fallback to TMPDIR and then /tmp, running the existing ancestor validation on the resolved path. On Linux, XDG_RUNTIME_DIR (/run/user/<uid>, 0700, user-owned) passes the walk trivially and is the semantically correct home for the socket directory.
  2. Until that lands, document the container contract (sticky root-owned /tmp, euid-owned cache dir) in a deployment guide.
  3. Optional, separate decision: accept group ownership of the cache dir when it matches the process egid, which covers the standard Kubernetes fsGroup pattern.

Related issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    windowsWindows-specific issues

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions