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

MGS2013: a sandboxed read of a set variable answered unset

Code running under the sandbox read an environment variable that is set in magus's own environment, and the sandbox withholds it, so the read answered "unset":

[warn] [MGS2013] a sandboxed read of a set variable answered unset name=ACTIONS_RUNTIME_TOKEN project=. target=test

Why

os\env, env\get, env\lookup and env\expand read through the sandbox's environment allowlist, and a name the allowlist withholds reads exactly like a name nobody set. The code gets nothing it was not granted.

It also makes the failure invisible. The variable is right there in your shell, the code that reads it sees nothing, and whatever it does next (skip a step, report a cache miss, fall back to a default) looks like ordinary behavior. This line says what happened. It goes to the run's log, never back to the code that read, and names the variable, never its value. It fires once per target and variable. A listing (env\list) reports nothing: it would name every withheld variable at once.

The line does tell whoever reads the log that a variable of that name is set. Names are not secrets, but a workflow that keeps one private should know the log carries it.

MGS2003 is the other half: the variables a child process did not inherit.

Resolution

If the code needs the variable and it is not a credential, declare it in the narrowest layer that needs it: the target's own sandbox policy, the spell that drives the tool, or, for every target, the workspace:

sandbox:
  env:
    passthrough:
      - GOFLAGS

If it is a credential, do not pass it through to every target. Read it with magus\secret.read, which keeps it out of logs, and hand it to the one command that needs it.

A remote cache backend reads its own credentials under its own declaration, never a target's: its lookups and stores run under the workspace policy plus that spell's layer. A cache backend whose read still hits this has not declared the variable in its mgs_getSandbox.

See also

  • MGS2003: variables a child process did not inherit
  • Sandbox model: which spell layers a process gets, and why a service spell's reach only its own ops
  • Secrets: reading a credential so magus can protect it
MGS2013sandboxenvironmentpassthroughos.envenv.lookupenv.expandsecrets
Last updated (895d94e4)
Earlier changes on this page (1)

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.

Project

A directory magus recognizes as a unit of work (it has a magusfile); the unit of caching, scheduling, and dependency tracking. See workspace.

Target

A named operation (build, test, ...) you invoke with magus run <target>; it may compose a spell's tool-native operations and depend on other targets. See targets.

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.

Cache

The content-addressed store magus consults before running a target, so unchanged work is skipped. See cache.

Sandbox

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

Service

A long-running or shared process magus manages across runs, distinct from a one-shot target. See services.

Remote cache

A CI-only backend that shares content-addressed artifacts across runners: a cold machine replays a build another runner already did instead of rebuilding. Every remote artifact must be signed by a trusted key. See remote.

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.