grithdocs

6. Capability enforcement

Grant a caller a set of operation classes, and everything outside them scores 10.0.

Phase1, static
Score10.0, on all three failure paths
Sourcecrates/grith-proxy/src/filters/capability.rs
Configconfig/filters/capabilities.toml

The strictest filter grith ships, and the only one that is inert out of the box.

ℹ️It ships permissive

config/filters/capabilities.toml contains no grants, only commented examples. With no grants defined the filter scores nothing on every call. It switches to enforcement the moment you add your first [[grants]] entry - and from then on any caller without a grant is denied.

Capability strings

Each call maps to exactly one capability string.

CapabilityCovers
fs:readFileRead
fs:writeFileWrite, FileAppend, FileRename, FileLink, FileChmod, DirCreate
fs:deleteFileDelete
fs:listDirList
fs:ownershipOwnershipChange
fs:mountFilesystemMutation
shell:execShellExec, ProcessSpawn
net:httpHttpRequest
net:connectNetConnect, DnsQuery
net:listenNetListen
process:ptraceCrossProcessAccess
process:namespaceNamespaceOp
ipc:dbusDbusMethodCall
*everything

Configuring it

config/filters/capabilities.toml

toml
[[grants]]
plugin = "claude-code"
capabilities = ["fs:read", "fs:list", "fs:write", "shell:exec", "net:http"]

plugin is the caller identity on the call. Repeated entries for the same plugin are merged.

Once grants exist, an ungranted operation scores 10.0 - past the deny line on its own, before any other filter has contributed:

terminal
$ grith proxy test '{"type":"ShellExec","command":"ls","args":["-la"]}'

Score:       11.0
Decision:    DENY
Reason:      Shell execution: ls -la; Plugin 'cli-test' has no capability grants

Filter Breakdown:
  + operation-risk         1.0  [notice]  Shell execution: ls -la
  + capability            10.0  [critical]  Plugin 'cli-test' has no capability grants

Exit code:   2 (deny)

That call came from cli-test, which the file above never mentions - and once any grant exists, a caller with no entry is denied outright. A caller that does have an entry but not the right capability is denied identically, at the same 10.0, with Plugin '<id>' lacks capability '<capability>'. Enforcement is all-or-nothing: once one grant exists, every caller needs one.

A broken file turns enforcement off, quietly

⚠️Check your file parses

If your capabilities.toml does not parse, grith falls back to the grant-free copy embedded in the binary. The daemon starts, the filter registers, and it scores nothing - so enforcement is silently off. There is no error at the default log level. After editing the file, run one call you expect to be denied and confirm it is.

See also

Last updated: 2026-08-24Edit this page on GitHub →