EMILUA(7)
πΈ EMILUA(7) β the Emilua reference, bestie edition πΈ
okay so welcome to EMILUA(7), straight out of the Emilua reference π this is the page about Emilua - Lua execution engine, and it's honestly kind of a whole philosophy lecture disguised as documentation. grab a snack, we're getting into it.
β¨ DESCRIPTION β¨
so here's the tea β Emilua gives you support for creating actors in isolated processes using Capsicum, FreeBSD jails, Seccomp, Linux namespaces or Landlock. the whole idea? stop potentially exploitable code from touching resources beyond what has been explicitly handed to it. that's the entire basis for capability-based security systems, and ngl it maps pretty well to APIs implementing the actor model β which is, like, exactly what Emilua is. π«Ά
Figure 1. XKCD 1200: Authorization
[If someone steals my laptop while I'm logged in, they can read my email, take my money, and impersonate me to my friends, but at least they can't install drivers without my permission.]
π it's giving "we suffer but make it a bit funny."
even modern operating systems are still somehow rooted in an age where we didn't know how to properly partition computer resources adequately to user needs while keeping a design focused on practical and conscious security. so what happens? several solutions get stacked together to somehow fill this gap, and they usually work for most of the applications β but not all of them, and that's the problem π
consider the web browser. there is an active movement pushing for a future where only the web browser exists and users handle all of their communications, store & share their photos, book hotels & tickets, check their medical history, manage their banking accounts, and much more... all without ever leaving the browser. and in that scenario, any protection the OS offers to protect programs from each other is rendered useless! only a single program exists. if a hacker exploits the right vulnerability, all of the user's data will be stolen. there is no real compartmentalisation. π
the browser is part of a special class of programs. the browser is a shell. a shell is any interface that acts as a layer between the user and the world. the web browser is the shell for the www world. www browser or not, any shell will face similar problems and has to be consciously designed to safely isolate contexts that distrust each other. and the Emilua team is not aware of anything better than FreeBSD's Capsicum to do just this. in the absence of Capsicum, we have Linux Landlock which can be used to build something close. browsers actually use Linux namespaces which are older. π
π¦ THE API π¦
Compartmentalised application development is, of necessity, distributed application development, with software components running in different processes and communicating via message passing. β Robert N. M. Watson, Jonathan Anderson, Ben Laurie, and Kris Kennaway β Capsicum: practical capabilities for UNIX
the Emilua API to spawn an actor lies within the reach of a simple function call:
local my_channel = spawn_vm(module)
that's it. that's the whole flex β¨ check the manual elsewhere to understand the details. as for sandboxes, the idea is to spawn an actor where no system resources are available (e.g. the filesystem is mostly empty, no network interfaces are available, no PIDs from other processes can be seen, ...).
consider the hypothetical sandbox class:
local mysandbox1 = sandbox.new()
local my_channel = spawn_vm(mysandbox1:context(module))
mysandbox1:handshake()
that would be the ideal we're pursuing π nothing other than 2 extra lines of code at most under your application. all complexity for creating sandboxes taken care of by specialized teams of security experts. literally the dream.
the Capsicum paper[1] released in 2010 analysed and compared different sandboxing technologies and showed some interesting figures. consider the following figure that we reproduce here:
Table 1. Sandboxing mechanisms employed by Chromium
- Operating system: Windows β Model:
ACLsβ Line count:22350β Description: Windows ACLs and SIDs - Operating system: Linux β Model:
chrootβ Line count:605β Description: setuid root helper sandboxes renderer - Operating system: Mac OS X β Model:
Seatbeltβ Line count:560β Description: Path-based MAC sandbox - Operating system: Linux β Model:
SELinuxβ Line count:200β Description: Restricted sandbox type enforcement domain - Operating system: Linux β Model:
seccompβ Line count:11301β Description: seccomp and userspace syscall wrapper - Operating system: FreeBSD β Model:
Capsicumβ Line count:100β Description: Capsicum sandboxing usingcap_enter
do notice that line count is not the only metric of interest π the original paper accompanies a very interesting discussion detailing applicability, risks, and levels of security offered by each approach. just a few years after the paper was released, user namespaces was merged to Linux and yet a new option for sandboxing is now available. fast-forward a few more years and we also have Linux Landlock which is even better than Linux namespaces. within this discussion, we can discard most of the approaches β DAC-based, MAC-based, or too intrusive to be even possible to abstract away as a reusable component β as inadequate to our endeavour. π
out of them, Capsicum wins hands down. it's just as capable to isolate parts of an application, but with much less chance to error (for the Chromium patchset, it was just 100 lines of extra C code after all). unfortunately, Capsicum is not available in every modern OS. π
do keep in mind that this is code written by experts in their own fields, and their salary is nothing less than what Google can afford. 11301 lines of code written by a team of Google engineers for a lifetime project such as Google Chromium is not an investment that any project can afford. that's what the democratization of sandboxing technology needs to do so even small projects can afford them. that's why it's important to use sound models that are easy to analyse such as capability-based security systems. that's why it's important to offer an API that only adds two extra lines of code to your application. that's the only way to democratize access to such technology. π₯
Note π§ Rust programmers' vision of security is to rewrite the world in Rust, a rather unfeasible undertaking, and a huge waste of resources. in a similar fashion, Deno was released to exploit v8 as the basis for its sandboxing features (now they expect the world to be rewritten in TypeScript). the heart of Emilua's sandboxing relies on technologies that can isolate any code (e.g. C libraries to parse media streams).
back to our API β the hypothetical sandbox class that we showed earlier will have to be some library that abstracts the differences between each sandbox technology in the different platforms. the API that Emilua actually exposes as of this release abstracts all of the semantics related to actor messaging, work/lifetime accounting, process reaping, DoS protection, serialization, lots of Linux namespaces details (e.g. PID1), and much more, but it still expects you to actually initialize the sandbox. π«Ά
π THE init.script π
okay so bestie, every process carries associated credentials β little permission passes that enable operation on system-wide addressable objects such as filesystem objects and sockets. We set up a sandbox by disabling the ambient authority so the address space itself becomes inaccessible. That means sandboxed code should be run only after such setup already completed successfully β no early entrances, periodt. The proper hook to perform this setup is init.script, and init.script runs right after the process is created.
After the sandboxed actor is up, it can receive access to new resources through its inbox. And if any security exploit is performed on the sandboxed code? Then only the objects it has access to are rendered vulnerable β so the damage is contained in its compartment. Itβs giving containment, honestly π .
π¦ Landlock (Linux) π¦
Hereβs the whole vibe for Landlock on Linux:
local init_script = [[
local rules = C.landlock_create_ruleset{ handled_access_fs = {
"execute", "write_file" "read_file", "read_dir", "remove_dir",
"remove_file", "make_char", "make_dir", "make_reg", "make_sock",
"make_fifo", "make_block", "make_sym", "refer", "truncate" } }
set_no_new_privs()
C.landlock_restrict_self(rules)
]]
spawn_vm{
subprocess = {
init = { script = init_script }
}
}
Landlock as of now can only control access to filesystem objects, but future versions will be more complete. foreshadowing, bestie β¨
π Capsicum π
And for Capsicum, itβs literally this:
spawn_vm{
subprocess = {
init = { script = "C.cap_enter()" }
}
}
π NOTES π
[1]β https://www.cl.cam.ac.uk/research/security/capsicum/papers/2010usenix-security-capsicum-website.pdf
π This iconic page is from Emilua 0.12.1-nixpkgs1, dated 1980-01-01 β slay and goodbye, bestie ππ
π¦ where this page comes from
- nixos 26.05: emilua 0.12.1
- nixpkgs unstable: emilua 0.12.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms