Skip to content

jmecom/capable

Repository files navigation

Capable

Capable is a small systems language built around capabilities: values that explicitly grant permission to perform privileged operations. It currently targets native code via Cranelift and links against a minimal runtime.

This is an experimental and toy project. Inspired by Austral.

fn main(rc: RootCap) {
  // Mint a capability from the root
  let console = rc.mint_console();
  let alloc = rc.mint_alloc_default();

  // Acquire a ReadFS capability at ./here.
  // We pass this capability struct to functions that require
  // one: otherwise the code won't compile. Moreover, the runtime
  // enforces the scope of the capability to allow only reading at ./here.
  let fs = rc.mint_readfs("./here");

  // Attempt to read beyond the capability's scopes: this will print "blocked".
  match fs.read_to_string(alloc, "../etc/passwd") {
    Ok(_)  => console.println("BUG: escaped"),
    Err(_) => console.println("blocked"),
  }
}

Capabilities are explicit values that grant permission to perform privileged operations (filesystem, network, clock, etc.). This is in contrast to ambient authority: normally, any code running in your process can reach the outside world, which makes dependency behavior difficult to constrain or reason about.

Capable aims to reduce supply-chain risk by making authority non-ambient: if a dependency didn’t receive a capability value, it can’t do the thing. The compiler enforces this by requiring capabilities at call sites for privileged operations, and the runtime can enforce attenuation (for example, a filesystem capability scoped to a root directory that cannot be escaped). The result is a smaller blast radius and fewer “surprising” dependency updates, because new code can’t silently acquire new powers—you have to explicitly hand them over.

About

An experimental capability-secure systems language

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •