Load grant files, failing closed on any invalid file

crates/brokerd/src/grants.rs reads grants/*.toml into a GrantSet: load reports every problem in every file and returns either a complete valid set or the full problem list, never a partial one; from_grants sorts by id and collects every rule-2..9 problem; render prints each problem then the runbook pointer. All 17 grants tests pass; make gate prints gate: ok.

Implemented-By: OpenCode session (model recorded in docs/implementer-log.md)
This commit is contained in:
2026-09-19 02:50:26 -07:00
parent 9150effc8e
commit e2ab29aa15
19 changed files with 1003 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
An empty set of grants is valid: every call is denied with no_grant.
@@ -0,0 +1,8 @@
tool = "http_fetch"
mode = "auto"
max_taint = "private"
secret = "api-token"
[constraints]
hosts = ["api.example.com"]
patterns = ["^GET "]
@@ -0,0 +1,7 @@
tool = "read_file"
mode = "auto"
max_taint = "private"
[constraints]
paths = ["notes", "/home/kyle/../etc", "/"]
hosts = ["example.com"]
@@ -0,0 +1,3 @@
tool = "shell"
mode = "auto"
max_taint =
@@ -0,0 +1,10 @@
# The owner's notes: only the owner writes them, so their content is trusted.
tool = "read_file"
mode = "auto"
max_taint = "secret"
result_class = "private"
untrusted = false
expires = "2027-01-01T00:00:00.000Z"
[constraints]
paths = ["/home/kyle/notes"]
@@ -0,0 +1,7 @@
tool = "http_fetch"
mode = "auto"
max_taint = "private"
result_class = "public"
[constraints]
hosts = ["example.com", "*.example.com"]
@@ -0,0 +1,7 @@
# The owner meant `mode`. If this file were skipped, fetch-example would allow what it forbids.
tool = "http_fetch"
mdoe = "deny"
max_taint = "secret"
[constraints]
hosts = ["internal.example.com"]
@@ -0,0 +1,10 @@
# The owner's notes: only the owner writes them, so their content is trusted.
tool = "read_file"
mode = "auto"
max_taint = "secret"
result_class = "private"
untrusted = false
expires = "2027-01-01T00:00:00.000Z"
[constraints]
paths = ["/home/kyle/notes"]
+1
View File
@@ -0,0 +1 @@
Grants for the tests. This file is not a grant and is ignored.
@@ -0,0 +1,7 @@
tool = "http_fetch"
mode = "auto"
max_taint = "private"
result_class = "public"
[constraints]
hosts = ["example.com", "*.example.com"]
@@ -0,0 +1,6 @@
tool = "http_fetch"
mode = "deny"
max_taint = "secret"
[constraints]
hosts = ["internal.example.com"]
@@ -0,0 +1,10 @@
# The owner's notes: only the owner writes them, so their content is trusted.
tool = "read_file"
mode = "auto"
max_taint = "secret"
result_class = "private"
untrusted = false
expires = "2027-01-01T00:00:00.000Z"
[constraints]
paths = ["/home/kyle/notes"]
@@ -0,0 +1,6 @@
tool = "write_file"
mode = "ask"
max_taint = "private"
[constraints]
paths = ["/home/kyle/scratch", "/home/kyle/scratch/out"]
@@ -0,0 +1,4 @@
# A shell with nothing mounted.
tool = "shell"
mode = "ask"
max_taint = "secret"