datomic 2026-03-15

http://explorer.eacl.dev/ is now online, demoing the latest https://github.com/theronic/eacl v7 (Enterprise Access ControL). EACL is a situated ReBAC authorization library based on SpiceDB, built in Clojure and backed by Datomic. EACL is tuned for Datomic Pro, but I ported EACL to DataScript this week so you can play with it in the browser (mainly because it saves me money on hosting a Datomic cluster.) The performance of EACL DataScript scales similarly to Datomic Pro because it's heterogeneous tuples all the way down, but Datomic Pro or Datomic Cloud is way faster, because concurrency πŸ™‚. Typically 0.5-3ms for eacl/lookup-resources to query 20 items from 700k resources (typical workloads). For a super admin (who can see everything), you can expect 30-100ms for page of 20. But you won't fit 700k resources into client-side DataScript. You should be able to go up to 200k client-side. Rationale for EACL here: http://eacl.dev.

πŸ‘ 2
πŸ†’ 3
❀️ 1

pretty cool! Q1. how about datomic cloud (`datomic.client.api`) support? i see u use some d/entity calls, which might need to be expressed as recursive datalog queries. there are some d/entid calls, which can be replaced with (:db/id (dc/pull db-val [:db/id] e)). the readme mentions the use of d/seek-datoms for performance reasons. do u have any immediate idea why such a variant would be tricky to implement? Q2. why is the negation operator not implemented? 1. is it just the lack of immediate need? 2. is it because it's tricky to get it right? 3. is it because it's hard to get its performance acceptable?

my colleague has just pointed out the mention of Datomic Cloud on https://eacl.dev/ > What is EACL good for? > EACL is suitable for Clojure & Datomic Pro and Datomic Cloud applications. is that a mistake, since i don't see any mentions of datomic.client.api in the source code?

@onetom EACL Datomic Cloud support is aspirational, but possible. I’m not sure it’ll be fast enough though, so I’ll remove the mention for now. The Negation Operator is hard and slow without a cache. EACL only has no permission cache (only path caching), but I’ll add a good cache eventually. d/entid is fast in Datomic Pro.

πŸ™ 1

On second thought, tuple discontinuation would not help the nil-tuple conflict in EACL v6, but it would help with deprecated composite tuple schema from v6 to v7.

βž• 1

Here is a https://x.com/BraaiEngineer/status/2082483522447548662?s=20 (on X) if you want to understand the EACL Explorer, where I demonstrate how modifying the Spice schema DSL instantly updates permission lookups.

Non-functional EACL v8 improvements: β€’ The EACL kernel & cache are formally verified using Dafny, TLA+ & Apalache. β—¦ I have heard rumours that Clojure Core devs don't care for formal verification. If that is true, well – they are wrong: formal verification found and fixed over 50 consistency bugs in EACL. I can no longer find bugs in EACL, but that doesn't mean there aren't bugs – it just means I can't find them. β€’ EACL is black-box tested against SpiceDB, which means EACL produces the same output as SpiceDB, but lookups may return a different result order (by design), because EACL is a unique implementation. β€’ EACL v8 is much faster than v6 or v7 if you consider recursive schema. v6 only supported acyclic schema. To play around with EACL, try the following demos: β€’ EACL Drive, a Google Drive clone: http://drive.eacl.dev/ β€’ EACL performance demo: https://demo.eacl.dev/ β€’ Or, if you don't to click around or read code, you can listen to this https://www.linkedin.com/posts/freshcode_new-eacl-v8-demos-are-up-at-httpsdemoeacldev-activity-7504477820312596480-2lYX. Remaining EACL feature gaps vs. SpiceDB: β€’ Preconditions on writes, β€’ wildcards, β€’ subject_relation, and β€’ typed schema permissions. *EACL SpiceDB Schema limitations: β€’ wildcards: relation viewer: user:* (will probably add this in 8.1) β€’ intersection arrows: groups.all(member) (will probably add this in 8.1) β€’ subject_relation (todo in 8.1, but arrows can do already it) β€’ nil permissions, e.g. permission view = nil (easy to add in 8.1) β€’ self permissions, e.g. permission view = viewer + self (easy to add in 8.1) β€’ namespaced objects definition docs/document {} (easy to add 8.1)

1

@onetom SpiceDB set algebra, including the Exclusion operator (`-`) is now implemented in EACL v8, e.g. https://github.com/theronic/eacl#schema--relationships

sounds exciting, but we are still on datomic cloud and not sure when can we migrate off of it, so first i would need to see, if it's possible to port eacl to datomic cloud, even at the cost of performance loss.

@onetom it seems technically possible to port EACL v8+ to Datomic Cloud, but it will cost $200–$2000 in tokens to implement & verify correctness (send PR?). I personally don't use Datomic Cloud and I see no benefit in using EACL in an un-situated environment where you have already relinquished your DB to an external provider, i.e. your application Peers have no cache. The whole benefit of EACL is situated AuthZ, i.e it lives in our database, and Peers have cache locality. So as soon as you externalise your DB (e.g. to Datomic Cloud), you might as well externalise your AuthZ too and use SpiceDB, and deal with the distributed pain, because you already have distributed state problems. Unfortunately, EACL will likely have a native Postgres extension (coming soon) before it supports Datomic Cloud. I would recommend that you use SpiceDB and deal with the distributed state problems, because you already have to deal with them.

πŸ™ 1

@onetom it is possible that it would only costs $20–$400 to implement a correct module for eacl/datomic-cloud. If you, Nubank or someone on the Datomic Pro team would like to sponsor it, I am happy to attempt a port, but for now Datomic Pro remains a stronger target for EACL v8+ than Datomic Cloud. Like Clojure, EACL is totally free & open-source under EPL 2.0. Bear in mind the estimated cost of building EACL was ~$80k–$120k+, most of which was out-of-pocket (some from a previous employer.) There is not a strong reason for EACL to support an un-situated use-case when EACL's whole deal is "avoid distributed state" to begin with.

In cloud, running an ion is the way to run with your application situated alongside the database and the same cache as peers have in pro. Many cloud users choose ions to be situated in this way and I’m sure they would love to use EACL (I know I would have back when I was a cloud customer ).

Just my 2 cents @petrus

@petrus thanks for giving it some thoughts! about 2 months ago, i've already let some llm look into what would a port entail and i was meaning to ask you this question, but something was always more important... in the meantime, i've done some preliminary tests with in-mem spicedb, just to validate the idea, that a ReBAC system would be suitable for our use-case and im quite convinced it would be. re: "avoid distributed state" i don't see how datomic cloud with multiple query groups is different from a datomic pro transcript, which multiple peers connect to. or is that configuration not supported by EACL?

@onetom In general, ReBAC is the better option. ReBAC subsumes both RBAC and ABAC (given Caveats, which EACL supports now). I need to better understand Datomic Cloud query groups architecture better before I can comment on that. EACL heavily leverages low-level calls like d/seek-datoms & d/rseek-datoms for speed. These calls only became available in Datomic Cloud on 2026-07-01 (refer client-cloud 1.0.137 with :limit), which feels very new, so I am wary to touch it. As an authorization library, EACL is fast-moving, but it can never risk saying "yes" when it should say "no." Which is why every EACL build takes ~40 minutes to run formal verification on GH (faster locally). If you choose to propose an EACL PR, please use the Michelangelo of models you can afford. The formal models and graph traversal algorithms + cache are IME simply too complex for non-frontier models. Luckily the extensive EACL test suite will catch regressions. What it won't catch is changes to the formal models and uncertified changes. I independently certify that the EACL implementation matches the formal models (SpiceDB is not formally verified at all, btw.) The EACL codebase is certainly not optimal, but the algorithms are good, and AFAICT, EACL is correct.

πŸ™ 1

> wary to touch it why the hesitation? The rseek-datoms code has been powering index-pull for nearly a decade.

@joe.lane link to source code please.

@joe.lane ah, I see you work for Datomic: I was being slightly facetious – but in jest there is truth. I love Datomic Pro and took a https://petrustheron.com/posts/why-clojure.html in adopting Clojure & Datomic Pro in 2014, but new Datomic Cloud APIs are new. I don't want to spend $100–$500 porting EACL v8 to Datomic Cloud until those APIs are stable. Nubank is welcome to sponsor a port, but it's simply too risky for an authorization library to adopt a new backend API until other people have found the bugs. I can't read the source, or I'd audit it myself, so I have to wait 1-2 years before I am comfortable to use it. Put differently, if EACL was closed-source, would you use EACL until it had ~2 years of good reviews? Probably not. Heck, would you use it if was open-source (it is) without good reviews? Probably not. Same goes for Datomic Cloud. Hence "wary to touch it."

given you have formal verification and spicedb doesn't, i already trust eacl more ;) but what's the alternative? hand-rolled authz, which is what we have now. compared to that, i still trust eacl more, even if its freshly adapted to datomic cloud. also, i don't think anyone expects you to do the adaptation to datomic cloud. here is a potential plan outline of eacl adoption for datomic cloud users, like us: 1. migrate the data from cloud to pro. we already have some code which moved datomic cloud dbs from one aws region to another, so i would reuse that. 2. the current application can access the migrated dbs via the datomic pro client-api server (can't remember what is it called exactly) but it exposes the same network api which datomic.client.api/* can talk to 3. the eacl logic can talk to the same databases via the peer api

@onetom EACL is stronger than hand-rolled AuthZ, but I would not recommend moving from Datomic Cloud to Pro just because of EACL...unless EACL has something you truly need, so I will assume you understand the trade-offs. EACL has not not been independently certified for correctness – it's just me + frontier models and I use it in production, i.e. "Who watches the watcher?" That's why it's open-source: so don't trust me on this – ask your models to break EACL – issues & PRs welcome. I haven't been able to break it yet, but feel free to try. If you find a bug, I guarantee it will be a weird snapshot/consistency thing, unrelated to happy path. Every bug I have found & fixed has been of this nature. I'll need to look at the Datomic Cloud architecture before I can comment on it. I avoided Datomic Cloud because it lacked d/(r)seek-datoms, but now that those APIs are available, Datomic Cloud is more attractive as a target, so I'll consider it. Make your own assessments. I am not affiliated with Datomic – I built EACL because I needed it for my commercial agentic ledger, so if EACL is incorrect, I go out of business, i.e. have an incentive for EACL to be correct, which is why it's formally verified. Very soon, all software will have to be formally verified, or it won't be viable, because the models are too good at finding vulnerabilities.

πŸ‘Œ 1

@joe.lane I'll have a look at Datomic Cloud as a potential target for EACL. d/(r)seek-datoms was a blocker last I checked, but I see it was recently added. How does load-balancing work with Ions? I assume it's ALB round-robin + Lambda scatter? EACL uses Caffeine for local & in-memory cache (though it can persist to storage), so round-robin would hit a cold cache between eacl/can? & eacl/lookup-* queries: 1. Can application code use valcache, or is it exclusive to Datomic instances? 2. EACL cache could go in a shared memcached, or DynamoDB (pricey), but not sure how many Cloud customers use memcached? 3. Are Ions' memory persistent between queries, i.e. would an in-memory Caffeine cache survive between requests? (I think it will) I take it that queries are "sticky" to query groups but not sticky to an individual Peers (by design). I see Cloud does not support d/entity or d/entid, only d/pull, so that would require some changes in EACL.

we are already using d/datoms to simulate d/entid, though we call it dc/eid (datomic component entity id). it's probably not as performant as d/entid, but i would worry about performance issues later, since our use-case would probably deal with a few thousand resources (uploaded and generated documents, llm chats, oauth authorizations) only, for the next year or so.

(defn eid
  "It returns the entity ID of `entity:ref` or `nil` if there are no facts
   associated to it.

   `entity:ref` can be nil, an entity ID, a `:db/ident` keyword or a lookup-ref.

   It's useful in queries, where a query input is an ident, but it should
   participate in a data-pattern of a datalog `:where` clause, which has a
   dynamic attribute (e.g. a logic var or `_`).

   It's also useful for checking the existence of an entity at the basis-t of
   `dc|db-val`.

   It's similar to the Datomic Pro `d/entid` function:
   
   "
  [dc|db-val entity:ref]
  (when entity:ref
    (-> dc|db-val
        (datoms
          {:index      :eavt
           :components [entity:ref]
           :limit      1})
        first :e)))