~technomancy/capabilities.fnl

Object Capabilities library for Fennel
Initial commit.

refs

main
browse  log 

clone

read-only
https://git.sr.ht/~technomancy/capabilities.fnl
read/write
git@git.sr.ht:~technomancy/capabilities.fnl

You can also use your local clone with git send-email.

#capabilities.fnl

Local Object capabilities for Fennel.

This allows you to write your program in such a way that it does not have ambient access to the outside world.

The ability to read and write to disk is restricted to just the directories you specify, and only functions which are passed the relevant part of the caps table are able to do even the restricted reads and writes. Access to the ability to launch subprocesses and make network calls is similarly restricted and must be passed around as arguments instead of being available to any function that wants them.

This obviously results in programs with excellent security properties, but it also makes it easier at a glance to see which parts of your program are doing I/O and which parts are doing pure calculation, which makes program maintenance easier.

For now, please see pengbot and my talk from FennelConf for details about how to use it. For another explanation of the concept, see Justin Pombrio's blog post about log4j.

Note that distributed Object Capabilities are not in scope for this library.

#Basic example

(local capabilities (require :capabilities))
(local commands ["^mkdir " "^ln " "^curl "])
(local caps (capabilities.for _G {:os {:getenv ["DEBUG" "PWD"]
                                       :remove ["data/"]
                                       :execute commands
                                       :date os.date
                                       :time os.time}
                                  :io {:open {:write ["/tmp/" "data/"]
                                              :read ["data/"
                                                     "config.json"]}
                                       :stdin io.stdin
                                       :popen commands}}))

;; we trust dkjson to run without sandboxing
(set caps.json (require :lib.dkjson))

(local arg _G.arg)

;; _ENV works with Lua 5.2+ but otherwise use setfenv
;; nothing below has access to the outside world except thru `caps` table
(local _ENV (capabilities.env))
(local myprogram (require :myprogram))
(myprogram.run caps arg [...])

#License

Copyright © 2022-2024 Phil Hagelberg and contributors, released under the MIT license.