magus v0.4.3 is out. See what's new
¶ View markdown source · ✎ Suggest an edit
2 min read

MGS2008: magus socket withheld from subprocesses

The socket vars (MAGUS_PROC_SOCKET, MAGUS_SERVER_ADDRESS) are magus's own pool pointers. magus withholds them from every op subprocess and re-hands them only to a nested magus. This code is logged, at debug level only, on both halves of that contract: when a var is withheld from a child, and when it is re-injected for a legitimate recursive magus invocation.

[MGS2008] withheld magus socket pointer(s) from op subprocess (done regardless of sandbox.mode) (see https://github.com/egladman/magus/blob/main/docs/codes/sandbox/MGS2008.md)
  vars=[MAGUS_PROC_SOCKET]
[MGS2008] magus socket injected into recursive magus invocation
  var=MAGUS_PROC_SOCKET

Why

The pool socket is unauthenticated: anything that can reach it can drive the process behind it. If those vars were inherited by every child, a compromised third-party spell could connect to the socket and issue commands. So magus strips them from every op subprocess, alongside the other secret-bearing vars (see MGS2003.md).

This withholding is independent of sandbox.mode. With the sandbox on, the vars are simply absent from the environment allowlist. But the sandbox is off by default, and "off" rebuilds no environment - the child would otherwise inherit the whole parent environment - so magus carries the withholding in an explicit code path that runs either way. That is why turning the sandbox off does not hand these pointers to spells, and why they can go missing from a subprocess even in a workspace with no sandbox configured at all.

A nested magus call is the one exception. It is a recursive invocation of the same trusted binary, and it genuinely needs the pool to coordinate. For that case magus re-injects MAGUS_PROC_SOCKET and MAGUS_SERVER_ADDRESS as explicit env overrides on the child, and records it with this code.

The log fires at debug (-v), not info, because a run spawns many ops (and a fan-out many recursive invocations) and it would otherwise be pure noise at default verbosity. It is an internal correctness note, not an error and not user-actionable.

Resolution

Nothing to do. This is the sandbox working as intended: the socket stays hidden from spell subprocesses, and is handed only to nested magus processes that need it.

If a subprocess of yours genuinely needs to reach the server and cannot see the socket, that is this rule at work - a plain program is not a nested magus and is not trusted with the unauthenticated socket. Reach for the pointer through a recursive magus call instead. The withheld line explains a missing var; the already running under a parent magus error, which names the inherited MAGUS_PROC_SOCKET, explains the opposite case where a program mistook the inherited socket for adoption.

You will see these lines only when running at -v or higher. If you do not want the noise, run at default verbosity.

MGS2008sandboxserversocketenvrecursivesecurity
Last updated (a9ff8609)
Earlier changes on this page (2)

Full history ↗ · Blame source ↗

Glossary

Workspace

The magus root directory that owns a set of projects and shared config; the unit magus operates over. See workspace.

Op

A single tool-native command a target composes (long form: operation); the middle of the work hierarchy (Spell to Op to Target). See operations.

Spell

A language/runtime adapter (e.g. go, md) that maps generic targets onto a toolchain's real commands. See spells.

Sandbox

The restricted filesystem and environment a target runs in, so builds stay reproducible and side-effect-free. See sandbox.

Server

The background process a person starts with magus server start. It serves MCP, the console, background jobs and the warm knowledge graph, and adopts nested magus calls into one pool. See server.

CI

An ordinary magusfile-defined target you compose yourself with magus\needs - magus does not hardcode its stages. Magus.RunCI treats it specially only in that it strips the rw charm, it is the anchor magus affected ci keys off, and a selected scope with no project declaring it is a load error rather than a silent no-op. See targets.

Pool

The concurrency pool: the shared set of slots that caps how many targets run in parallel on one machine. Its capacity defaults to MAGUS_CONCURRENCY, then 4 on GitHub-hosted runners, then min(NumCPU, 8); magus status and the dashboard report it live. See server.

Invocation

One magus process's recorded facts - the targets it finished, their outcomes, the lease it acted as, and the session it ran in when a host delivered one - kept in a repo-scoped store every worktree shares. magus session lists them; the store prunes itself by last-fact age.

Run

One target executing under one magus invocation, such as magus run test web or magus affected ci. A run keeps its captured output behind an output reference. Every magus run is a run whether or not any job asked for it; see Job for how the two relate.

Conventions

This page uses none of the site's convention markers. The full set is on the conventions page.