Leia

Leia Security And Sandboxing

Leia is an embeddable scripting language. Security is therefore host-owned: the host decides which libraries exist, which host capabilities are enabled, which Go bindings are registered, and which resource budgets apply.

Default Trust Model

leia.New() defaults to LibAll and CapAll for local-script compatibility. That is appropriate for trusted tools and development scripts, not for untrusted user input.

Production embeddings should start from SecuritySandbox() and opt back into specific capabilities.

vm := leia.New(
    leia.SecuritySandbox(),
    leia.WithMaxSteps(100_000),
    leia.WithMaxNativeCalls(1_000),
    leia.WithMaxCallDepth(128),
)

Libraries And Capabilities

Library flags decide which standard-library tables are installed. Capability flags decide which installed APIs may touch host resources.

Control Meaning
WithLibs(flags) Select available standard-library modules.
LibAll Every standard library. Default.
LibSafe Pure or sandbox-friendly modules with no filesystem, network, process, debug, script, or AI host access.
LibApp Application preset with common host-facing libraries.
LibGame Game preset with math, vectors, color, arrays, SoA, time, and random.
WithCapabilities(flags) Select host-backed capability bits.
CapAll Module loading, filesystem read/write, and environment read/write. Default.
CapSafe No host-backed capability bits.

Capability bits are separate from library selection so embedders can expose a module table while denying its host effects.

Network, debug, testkit, process execution, shell execution, and dynamic eval are controlled by separate switches. They default to enabled for trusted local scripts and are disabled by WithSandbox() and SecuritySandbox().

Capability Gates
CapModuleLoading Script-side require() loading .leia files from the host filesystem.
CapFilesystemRead fs.readfile, fs.stat, fs.readdir, dofile, loadfile, and related reads.
CapFilesystemWrite fs.writefile, fs.remove, fs.rename, fs.mkdir, fs.chdir, and related writes.
CapEnvironmentRead os.getenv, os.environ, os.expand.
CapEnvironmentWrite os.setenv, os.unsetenv.

Sandbox Presets

API Behavior
WithSandbox() Selects LibSafe, CapSafe, disables dynamic eval, network, debug, testkit, process execution, and shell execution.
SecuritySandbox() Same baseline and also disables JIT by default. Use this for untrusted scripts.
WithSecurity(policy) Applies one auditable grouped SecurityPolicy.

JIT is disabled whenever runtime resource budgets require checkpoints that native code could otherwise bypass.

SecurityPolicy{} keeps zero-valued fields at their existing defaults. To make a grouped policy explicitly use CapSafe, set both Capabilities: CapSafe and CapabilitiesSet: true.

Filesystem And Environment

Constrain path access with a filesystem root:

vm := leia.New(
    leia.SecuritySandbox(),
    leia.WithLibs(leia.LibSafe|leia.LibFS),
    leia.WithFilesystemRoot("/srv/app/scripts"),
    leia.WithFilesystemRead(true),
    leia.WithFilesystemWrite(false),
)

WithFilesystemRoot confines script-side file loading and fs module paths to that root. It does not constrain host-side CompileFile or ExecFile calls, because those are explicit host operations.

Restrict environment variables with an allowlist:

vm := leia.New(
    leia.SecuritySandbox(),
    leia.WithEnvironmentRead(true),
    leia.WithEnvironmentAllowlist("APP_REGION", "FEATURE_FLAG"),
)

Passing an empty allowlist allows no variables. Omitting the allowlist keeps environment access unrestricted when environment capability is enabled.

Dynamic Code And Processes

These switches gate higher-risk host behavior:

API Gates
WithDynamicEval(false) load, loadstring, script.compile, script.eval.
WithNetworkAccess(false) Host-backed net and http APIs.
WithDebugAccess(false) Script-visible debug APIs.
WithTestkitAccess(false) Script-visible test diagnostics.
WithProcessExecution(false) process.run, process.exec, process.which.
WithProcessShell(false) process.shell.

Resource Budgets

API Limit
WithMaxSteps(n) Interpreter statements or bytecode instructions per run.
WithMaxNativeCalls(n) Script calls into Go functions, including stdlib and host callbacks.
WithMaxCallDepth(n) Active script/native call depth.
WithMaxGoroutines(n) Script goroutines started by go.
WithMaxChannelCapacity(n) Maximum accepted make(chan, n) buffer capacity.
WithMaxHostResultBytes(n) String bytes returned from one Go call.
WithMaxModuleBytes(n) Bytes read by script-side source/module loading APIs.
WithMaxModuleDepth(n) Nested filesystem-backed require() depth.
WithMaxFilesystemReadBytes(n) Bytes read into memory by fs.readfile and fs.copy.
WithMaxFilesystemWriteBytes(n) Bytes written by fs.writefile, fs.appendfile, and fs.copy.

Use context deadlines around Exec, Run, Call, and hot reload methods for wall-clock cancellation.

Go Bindings

Leia never imports arbitrary Go packages by path at runtime. require("go:...") works only for bindings registered by the host:

vm := leia.New(leia.WithGoImports(map[string]any{
    "go:example.com/app/safe": SafeBinding{},
}))

Prefer narrow modules over exposing broad service objects. Host callbacks are native code from Leia’s point of view, so pair them with native-call and host-result budgets when scripts are not fully trusted.

Module Capability Summaries

leia.mod can declare capability summaries:

capability fs.read
capability llm.turn

These declarations make module boundaries auditable. Use:

cd path/to/module
leia mod capability --json

to inspect capability summaries across the module graph.