SCUA

How-to

Read environment variables

Environment variables are authority, not inert data: they're invisible, often hold secrets (DATABASE_URL, AWS_SECRET_ACCESS_KEY), and span the whole process. So unlike command-line arguments (which are public and need no grant), reading the environment is a host-granted capability — the env module doesn't exist unless you turn it on.

#Granting the capability

scua --allow-env=PORT,HOST,LOG_LEVEL  script.scua   # grant exactly those three names (the safe default)
scua --allow-env                       script.scua   # grant every variable (trusted-host shorthand)

Without a grant, import env is a compile error, before a line runs:

$ scua script.scua
script.scua:1: module `env` needs the `env` capability, which this run was not granted — grant it with `--allow-env` on the CLI, or the host's capability API when embedding

The per-name allowlist is the point: a variable you didn't grant reads as nil even when it is set in the environment, so a script can never see a secret it wasn't given. Prefer --allow-env=NAME,...; reach for bare --allow-env only when the script and the operator are the same trusted party.

#Reading values

import env

let port = env.get("PORT") ?? "8080"      -- missing/un-allowlisted → nil; ?? gives a default
let host = env.get("HOST") ?? "localhost"

-- required variable
if env.get("API_KEY") == nil then
  error("API_KEY is required — set it in your environment")
end

env.get(name) returns the value as a string, or nil if the variable was unset or not in the allowlist. A missing variable is a normal nil, not an error. The module is read-only — there is no env.set.

#What you can rely on

  • Snapshot at launch. The environment is captured once when the script starts, so env.get is a pure lookup with no surprises mid-run — and a run's inputs are reproducible (recorded alongside the RNG seed). A change to the environment after launch is not seen.
  • Per-partition. Inside a spawned actor, env is not granted — authority doesn't leak across partitions. Pass an actor what it needs in its starting message.
  • UTF-8. Values are UTF-8 strings. A non-UTF-8 allowlisted value fails the launch with a clear message (rather than silently returning nil); under bare --allow-env, a non-UTF-8 variable is skipped with a warning.

See the runnable examples/env.scua (scua --allow-env=PORT,HOME examples/env.scua).