Repository navigation
Description
Add a new section to Developer Tooling Ideas about storing and querying access control rules in Minigraf. Follow the same shape as the other sections: the problem, questions it answers, why Minigraf fits, a schema sketch with REPL queries, and limits.
Scope
Cover three models, from simple to complex:
- RBAC. Users have roles. Roles grant permissions. Roles can inherit from other roles through a recursive rule. No negation needed.
- Cascading group permissions. Grants sit on groups and on nodes in a resource tree. A user can act on a resource if a grant exists on that resource or on any ancestor, for the user or for any group the user is in. This needs two recursive rules:
withinfor the resource tree andmemberfor nested groups. - ACLs with allow and deny entries. Each ACE is an entity with principal, resource, permission and effect. Show three precedence policies:
- Deny overrides. Any matching deny anywhere up the tree wins. One
not-join. - Nearest entry wins (NTFS / POSIX ACL style). Allow when an allow exists at ancestor
aand no deny exists at a nodedwith(within ?r ?d)and(within ?d ?a). Deny wins over allow on the same node. No depth counting needed. - Break inheritance. A flag on a node stops the
withinrecursion at that node.
- Deny overrides. Any matching deny anywhere up the tree wins. One
What the two time axes add
- Audit. "Could Alice read this file last Tuesday?" is the same query with
:as-of. - Time-bound grants. A grant with a valid-time window expires on its own under
:valid-at. No cleanup job. - Corrections. A wrong grant can be fixed in valid time, and the record of what the system believed then stays queryable.
To check before writing
Stratified negation over recursive rule predicates. The deny-overrides and nearest-entry-wins queries put recursive rules (within, member) inside not-join. The docs say this should work, but nothing shows or tests it yet.
What the docs say:
- The grammar allows it.
not-jointakeswhere-clause+, and awhere-clausecan be arule-invocation. - The Datalog reference says negation uses stratified evaluation, and only negative cycles are rejected. The ACL rules have no negative cycle:
withinandmembernever depend on the deny rule. But the page never says in plain words that negation over a recursive rule is supported, and has no example of it.
Where examples exist:
- Docs site. Only one: an untested inline note in Graph traversal, Recipe 5 puts the recursive
ancestorrule insidenot-join. It has no expected output. Recipe 8 (noton a base fact inside a recursive rule) does cover the break-inheritance model. Tutorials 4, 5, 9 and 11 and the other cookbook pages have nothing. - Playground, visualizer samples, core
demos/. Nothing. The only rule calls under negation are non-recursive. - Core tests (
main). Negation over non-recursive rules is tested (test_not_negates_derived_rule,test_not_join_body_with_rule_invocation_end_to_end). So is recursion through a rule that hasnotornot-join(#628, #633). No test negates a recursive rule.
Before writing the section:
- Add a test in
tests/not_join_test.rs: awithinrule over a small tree with a deny ACE midway. Assert both deny overrides and nearest entry wins. - Turn the Recipe 5 note into a real query with expected output.
If the test fails, the section should show only the models that work today (RBAC, cascading grants, break inheritance) and link the bug.
No or inside not-join. The reference does not allow or or or-join inside not-join. A deny that matches "the user or any group the user is in" needs a helper rule such as (principal ?u ?p) with two bodies. The section should show this pattern.
Limits to mention
- It is a policy store, not a policy engine. The semantics live in user-written rules. There is no built-in check API like SpiceDB or OpenFGA.
- Checks run on every request. Recursive queries over deep trees and large group graphs need latency measurement before use on a hot path.
- One writer per file. It suits an authorization service that owns its own
.graphfile, not many services writing to one store.
Generated by Claude Code
Activity