Skip to content

No product-build way to relocate the daemon runtime directory when %LOCALAPPDATA% has a capability-SID ACE #1574

Description

@tmonestudio

Summary

On Windows the daemon/CLI coordination endpoint is created under
%LOCALAPPDATA%, resolved by SHGetFolderPathW(CSIDL_LOCAL_APPDATA) with no
override in a product build. If that ancestry carries a capability-SID ACE with
mutation rights — common on real machines once packaged apps are installed — the
binary cannot start at all, and there is no supported way to point it elsewhere.

The only relocation hook, CBM_TEST_DAEMON_RUNTIME_PARENT, is compiled out
unless CBM_ENABLE_TEST_SEAMS is defined, so the test binary starts fine while
the product binary does not.

Environment

  • Windows 11 Pro 10.0.26200, single user, non-domain.
  • Working build: main @ 7d6cdb23 + local cc56d509.
  • Failing build: current main, built 2026-08-12.

Observed

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

Every invocation path fails, including config list, so the settings surface is
unreachable. Independent of CBM_CACHE_DIR: with the cache on a clean
volume-root path the cache check passes and the endpoint failure remains.

Walking the ancestry with the same predicate as
win_private_directory_tree_secure, the only rejected entries under
%LOCALAPPDATA% are a single capability SID:

C:\Users\<user>\AppData        S-1-15-3-...  mask=0x000D0152  inherit_only=false
C:\Users\<user>\AppData\Local  S-1-15-3-...  mask=0x000D0152  inherit_only=false

0x000D0152 includes WRITE_DAC, WRITE_OWNER and DELETE. We are not
asking you to trust that — we agree it is a real tamper vector. Note it is not a
Windows default: C:\Users\Default\AppData\Local has no such ACE. It arrived
with an installed application, and it is present on AppData, Local,
Roaming and LocalLow.

Requests, in order of preference

  1. A product-supported override for the runtime parent directory — a config
    key or environment variable, validated by the same
    win_private_directory_tree_secure. The operator picks a path with clean
    ancestry; the check keeps its full strength. This is the one that unblocks us
    without weakening anything.
  2. Name the offending path in the endpoint error. The cache failure prints
    ipc_validation_detail and is immediately actionable; the endpoint failure
    prints neither the path nor the ACE, so diagnosing it took reading
    src/daemon/ipc.c.
  3. Document the required DACL shape for the runtime and cache directories,
    so operators can provision one deliberately instead of discovering it from a
    rejection.

Cache directory: works, with a caveat worth documenting

Our cache lives on a secondary data volume (46.5 GB; the system volume has 31.8
GB free, so relocating is not an option). F:\IndexadorData\... is rejected for
an inherited Authenticated Users → Modify from the volume root — correctly, we
think. Putting the cache directly under the volume root passes, since the
tool then owns the final directory's DACL and the only ancestor is the root
itself. That is a useful and non-obvious property; documenting it would save
others the same investigation.

Offer

We have the working and failing binaries side by side and an 823-project cache.
Happy to run any diagnostic build.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingeditor/integrationEditor compatibility and CLI integrationpriority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.securitySecurity vulnerabilities, hardeningux/behaviorDisplay bugs, docs, adoption UXwindowsWindows-specific issues

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions