Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 56s
Datalog ACL layer (schema/facts/engine/api) over lib/datalog/. Direct grant permits unless explicit deny names same (S,A,R) — deny-overrides via stratified negation. Conformance wrapper + scoreboard. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
30 lines
1.2 KiB
Plaintext
30 lines
1.2 KiB
Plaintext
;; lib/acl/engine.sx — ACL ruleset + decision reducer over lib/datalog/.
|
|
;;
|
|
;; The engine is a thin layer: it owns the permit ruleset (SX data rules) and
|
|
;; reduces a (subject, action, resource) decision to a Datalog query against a
|
|
;; db built from EDB facts. The rule engine itself is Datalog's.
|
|
;;
|
|
;; Phase 1 policy — direct grants with deny-overrides:
|
|
;;
|
|
;; permit(S, A, R) :- grant(S, A, R), not deny(S, A, R).
|
|
;;
|
|
;; A grant permits unless an explicit deny names the same (S, A, R). Deny wins:
|
|
;; the negated literal {:neg (deny S A R)} stratifies cleanly because deny is an
|
|
;; EDB relation (no rule derives it), so the fixpoint is well-defined.
|
|
|
|
(define
|
|
acl-phase1-rules
|
|
(quote ((permit S A R <- (grant S A R) {:neg (deny S A R)}))))
|
|
|
|
;; Build a Datalog db from a list of EDB facts under the Phase 1 ruleset.
|
|
(define acl-build-db (fn (facts) (dl-program-data facts acl-phase1-rules)))
|
|
|
|
;; Core decision: does the db permit subject S to perform action A on
|
|
;; resource R? Reduces to a ground Datalog query on the derived `permit`
|
|
;; relation — non-empty result means permitted.
|
|
(define
|
|
acl-permit?
|
|
(fn
|
|
(db subj act res)
|
|
(> (len (dl-query db (list (quote permit) subj act res))) 0)))
|