Environment Variables
Guest code reads environment variables through familiar APIs -- process.env in JavaScript and
the equivalents in other languages. Underneath, every host-environment read flows through a single
Elide-controlled access point. This page documents what guest code sees, how that set is decided,
and the limits of the model as it stands today.
process.env in JavaScript
Elide installs the Node-style process global, and process.env is a plain JavaScript object:
console.log(process.env.HOME);
process.env.MY_FLAG = "1"; // observable to later reads in this realmprocess.env is materialised once per realm, on first access, and cached. The accessor
(ProcessGlobal.envForRealm) iterates HostEnvironment.snapshot() and installs each entry as a
writable, configurable, enumerable own data property. Consequences:
- Guest writes are visible to later guest reads in the same realm, because they mutate the cached object.
- Guest writes do not reach the OS environment. Elide does not propagate them back; a future
child_process.spawnwould inherit the pre-mutation host environment unless given an explicitenv. process.envcannot be reassigned wholesale (process.env = {...}); it is an own data property ofprocess. Individual entries remain writable.
For the rest of the process surface (argv, execArgv, exitCode, platform, ...), see the
process global reference.
The host-environment exposure model
All host-side reads of OS environment variables performed on Elide's behalf -- both engine-startup
queries and the data backing guest-visible surfaces like process.env and os.userInfo().shell
-- route through dev.elide.cfg.HostEnvironment. This class exists to be the single chokepoint at
which two policy layers can be enforced:
- Sandbox policy -- restricts which host names a realm or invocation can see (deny-list, allow-list, or namespace gate).
- Secrets provider -- shadows or supplies values from Elide-managed secret stores instead of the OS environment, so e.g.
process.env.DATABASE_URLcan resolve to a managed secret never visible to the OS.
Both layers are realised as alternative HostEnvironment.Provider implementations installed via
HostEnvironment.install(...). A provider's get(name) returns null for unknown or denied
names, and its snapshot() returns only the visible entries -- so guest code **cannot distinguish
an absent name from a denied one**, nor an OS-backed value from an Elide-managed secret.
process.env object built from one snapshot keeps
its values even if a different provider is later installed. A sandbox or secrets provider must
therefore be installed before the first guest realm boots; post-boot rotation requires
invalidating and re-evaluating the affected realm.The default: full passthrough
The default provider is HostEnvironment.SYSTEM -- an unfiltered passthrough of
System.getenv(). The shipped CLI installs no other provider, so in a normal elide run /
elide serve invocation **process.env reflects the complete OS environment of the Elide
process**, matching Node. Sandbox- or secrets-mediated runs (which install their own provider) are
the mechanism by which that set is narrowed or overlaid; that wiring is internal and not yet
surfaced as a user-facing option.
Relationship to the polyglot environment knob
The runtime builds each guest context with allowEnvironmentAccess(EnvironmentAccess.NONE). That
context setting governs the polyglot engine's own environment-inheritance behavior; it does not
gate process.env. Elide's process.env is populated from HostEnvironment.snapshot()
independently, which is why the default OS-passthrough is observable even though the polyglot
EnvironmentAccess is set to NONE. (When the debugger is active, DebuggerComponent switches the
context to EnvironmentAccess.INHERIT as part of its broad trusted-principal grants.)
What is NOT injected
To be precise about behavior you might expect from other runtimes:
NODE_ENVis not injected. Elide does not set or defaultNODE_ENVfor any language. If it is present in your environment it shows through the normal passthrough like any other variable; if it is not set, it is simply absent. There is nodevelopment/productiondefault.- No synthetic
ELIDE_*variables are injected into guest environments (e.g. there is noELIDE_ROOTorELIDE_INTERNALenv var added for guests). The__Elide_token is an internal guest-symbol prefix, not an environment variable.
Flags
There are no CLI flags that control host-environment exposure today -- specifically, there is
no --allow:host-env, no --env=allowlist, and no per-name allow/deny flag. The allow-list and
secrets concepts described above are realised through HostEnvironment.Provider installation in
the embedding/host layer, not through command-line options. Selection of the guest language is by
file extension, not by flags, so there is likewise no language-selecting REPL flag in this area.
Summary
process.envis a per-realm snapshot taken on first access, sourced fromHostEnvironment.snapshot(); guest mutations are realm-local and never reach the OS.- The default
HostEnvironmentprovider is an unfilteredSystem.getenv()passthrough, so the CLI exposes the full OS environment by default (Node-compatible). - Sandbox/secrets filtering is a provider-swap mechanism (
HostEnvironment.install), not yet a user-facing flag; denied names are indistinguishable from absent ones. NODE_ENVand syntheticELIDE_*env vars are not injected.EnvironmentAccess.NONEon the polyglot context does not gateprocess.env.
What's next
processglobal -- the full Node-shapedprocesssurface- File System Access -- the companion host-I/O isolation model