Skip to content

Net grants

vow-web-server v0.2.2 introduces a three-tier grant model. Vow grants are process-scoped; the framework separates supply (what the operator allows) from demand (what routes declare they need).

Tier User action Meaning
1. Global grants.toml / CLI --grant Supply — max caps for the process
2. Middleware vws.use_grant_at(a, prefix, kind) Demand — routes under prefix require cap
3. API vws.get_needs / vws.post_needs Demand — this route requires cap

Tiers 2 and 3 never mint grants; they declare requirements. vws.serve(a, rt, port) validates demand ⊆ supply before listen.

vow run src/main.vow auto-loads grants.toml from the project root (or next to the source file) when you omit --manifest.

[[grant]]
kind = net
detail = ":8787"
[[grant]]
kind = fs-read
detail = "./public"

Build a runtime once in main:

fn main(caps: Caps) -> int {
let rt = vws.runtime(caps);
let a = vws.get(vws.app(), "/health", health);
return vws.serve(a, rt, 8787);
}

If a route requires a cap missing from grants.toml, serve exits with an actionable message before accepting connections.

Path-scoped requirements (Express-style app.use('/api', …)):

let a = vws.use_grant_at(a, "/files", vws.kind_fs_read());
let a = vws.use_grant_at_scope(a, "/files", vws.kind_fs_read(), "./public");

Routes whose path matches the prefix inherit the requirement at dispatch (merged into the request grant view).

let a = vws.post_needs(a, "/upload", upload, vws.kind_fs_read());
let a = vws.static_dir(a, "/", "./public");

Handlers access caps without module globals:

fn upload(req: request.Request) -> response.Response {
let fr = match vws.fs_read(req) {
Ok(c) => c,
Err(_e) => return vws.json(503, "{\"error\":\"fs-read unavailable\"}"),
};
// use fr with read_file ...
}
Grant Bind address Port
net: 127.0.0.1 (loopback) any
net::8787 127.0.0.1 8787 only
net:*:8787 0.0.0.0 (all interfaces) 8787 only
Terminal window
# Local dev — grants.toml auto-loaded
vow run src/main.vow
# Explicit CLI grants
vow run src/main.vow -- --grant net::8787 --grant fs_read:./public

Combine grants when serving files and HTTP:

Terminal window
vow run vow-examples/vow-web-server/static_site.vow -- --grant net: --grant fs_read:

Or use grants.toml with both net and fs-read entries.

Section titled “Reverse proxy (recommended for production)”

vow-web-server has no TLS. Terminate HTTPS at a reverse proxy and forward plain HTTP to loopback:

Client ──HTTPS──► nginx/Caddy ──HTTP──► 127.0.0.1:8787 (vow listen)

Run Vow with net::8787 so it only accepts local connections from the proxy.