#essay{:title        "Why EACL: Situated AuthZ",       :date         #inst "2026-03-23",       :reading-time "2 min"}

Why EACL: Situated AuthZ

2026-03-23 · 2 min read ·

"Why was EACL: Enterprise Access ControL designed as a situated authorization library?" – you, hopefully.

I can finally disclose the true reason why EACL's permission data lives in Datomic next to your data: it's about materialized UI maintenance.

In Datomic Pro, Peers can subscribe to changes committed by the transactor via datomic.api/tx-report-queue so that every time data is transacted, the collection of changes (assertions & retractions) is broadcast to all listeners.

This feature is heavily used by reactive frameworks like Electric Clojure on top of Datomic Pro, where every Datomic query reruns for every active user. But there's a problem.

If you have N users looking at M screens each running O queries, every transaction triggers N*M*O queries. More active users = more frequent transactions, so you have a cascading fan-out problem, even when 99% of query results don't change and no data is sent to the client. This puts a lot of pressure on Peers at scale, requiring more horizontal scaling. It is especially wasteful if you consider that as your user base grows, most transactions only affect a few users' queries at a time.

So how do you solve this? Well, the correct solution is differential datalog where you subscribe to queries, figure out exactly which queries are affected by a transaction (tracing the computation graph) and only notify users when their active queries are affected, but this is non-trivial to get right.

What if you could get 80% of the way there with a cheap solution?

What if, for every change, you could quickly enumerate the subset of users potentially impacted by that mutation, and only notify users to re-query while they're online? How would you do it?

Well, you'd need to model your data as a dependency graph...almost like a ReBAC permission graph 🤔. Such a system would need to be schema-aware...ideally situated next to your data, and it would need to be consistent for it to be correct.

That is exactly how 0tx (personal tax accounting ledger) uses EACL for reactive queries:

  1. When a new tx arrives, we inspect the tx-data and extract resource IDs (eids),
  2. For each resource ID, call EACL's lookup-subjects to efficiently calculate the set of users who could see the resource (takes <1ms),
  3. Filter the set down to online users only,
  4. Notify those online users, who in turn rerun their queries.

In a growing Datomic system, this cuts out 95% of the backend re-query pressure without having to be "perfectly accurate" (sometimes we will rerun extra queries). This only works well when data is relatively siloed per tenant, which is exactly the case in 0tx even though you can share ledgers and sub-accounts with multiple users.

This is much harder to do correctly with an external AuthZ system due to eventual consistency.

And that is why EACL is a situated ReBAC authorization library.

You can learn more about EACL, or try the EACL Explorer in your browser (backed by DataScript).