datomic

braai engineer 2025-06-20T15:03:03.029739Z

Datomic enthusiasts, behold https://github.com/CloudAfrica/eacl (Enterprise Access ControL), a SpiceDB-compatible* https://en.wikipedia.org/wiki/Relationship-based_access_control authorization system built in Clojure and backed by Datomic On-Prem: • https://authzed.com/spicedb is a faithful open-source implementation of https://research.google/pubs/zanzibar-googles-consistent-global-authorization-system/, Google's Globally Consistent Authorization System. ◦ SpiceDB powers YouTube, Google Drive & Google Calendar, serving billions of requests per day. ◦ Authentication (AuthN) means "who are you?" whereas Authorization (AuthZ) means "what can do?" ◦ Every enterprise Clojure app needs authorization. ◦ AuthN is a solved problem, but AuthZ is not – at least not embedded in Datomic, which is what EACL is about. • EACL implements the core SpiceDB API in Datomic and exposes an idiomatic IAuthorization Clojure protocol that cleanly maps to the SpiceDB https://buf.build/authzed/api/docs/main:authzed.api.v1: ◦ Check permissions via eacl/can? which maps to SpiceDB's CheckPermission, e.g. ▪︎ (eacl/can? client (->user "rich") :edit (->product "datomic")) => true | false ◦ Enumerate authorized resources via (eacl/lookup-resources client filters) ala SpiceDB's LookupResources ▪︎ ...which returns {:keys [data cursor]}, where data is a coll of {:keys [type id]}. ▪︎ Resource lookups are fast enough to populate UI menus in real-time, e.g. "which servers can user rich view?"

(eacl/lookup-resources client
  {:subject        (->user "rich")
   :permission     :view
   :resource/type  :server
   :limit          1000
   :cursor         nil}) ; pass nil cursor for 1st page
=> {:data [{:type :server, :id "server-1"}
           {:type :server, :id "server-2"}
           ...}],
    :cursor 'next-cursor-map} ; returns 1k of 100k matching results in ~6ms using Datomic :dev transactor on Apple M3 Pro.
▪︎ Note: :limit consumes N memory because we have to deduplicate object IDs discovered along multiple permission paths in the graph. ▪︎ Return order is undefined, but stable; like any cursor-based pagination, we cannot sort N of M results because it requires materializing M entities = expensive. Also applies to SpiceDB. ◦ Subject enumeration via (eacl/lookup-subjects client filters) works like like SpiceDB's LookupSubjects. ▪︎ Returns {:keys [data cursor]} where data is a coll of {:keys [type id]}. Takes limit & offset, pending cursor-based pagination impl. ◦ (eacl/count-resources client filters) is impl. in EACL but not SpiceDB, becauase it materializes the full index, so use sparingly. ◦ (eacl/read-relationships client filters) maps to ReadRelationships in Spice. ◦ (eacl/write-relationships client filters) maps to WriteRelationships in Spice ◦ (eacl/write-schema client schema) is not currently implemented because EACL schema lives in Datomic (see Relation & Permission). EACL aims to support the Spice schema DSL eventually. • Goal: EACL is aimed at Clojure applications with <10M resources and offers a clean migration path to SpiceDB once you hit scale or need consistency semantics, which requires complex graph caching via ZedTokens (ala Zookies). EACL is especially suited to Electric Clojure, which benefits from performance "what can I?" queries for real-time UI updates. • Project State: Alpha. We use EACL at my employer, https://cloudafrica.net/, which generously funded this open-source work. • Performance: EACL is fast, esp. eacl/lookup-resources for populating UI menus. ◦ There is an example https://github.com/theronic/eacl-electric-starter-app for Electric Clojure v3 if you want to test it locally against ~300k–1M permissioned Datomic entities. ◦ Without any application-caching mechanisms, based on my benchmarks, you can expect: ▪︎ 1k of 100k matching results in ~6ms, ▪︎ Two sequential pages of 600 & 400 results in ~4ms (smaller pages are faster because less deduplication via multiple permission graph paths) ▪︎ All 100k of 100k results in ~1s, but faster when paginated. ◦ Performance will depend on the complexity of your permission graph. • *Deficiencies vs. Spice: EACL is fully consistent, so no SpiceDB consistency semantics. No Caveats. No exclusion permissions (only sum types). expand-permission-tree is not impl yet. subject.relation is not supported yet. Minor Permission hack to support Spice arrow permissions (see README). • Licence: currently AGPL but there is an open issue to change the licence to something more permissive, which will hapapen soon.

🎉 9
braai engineer 2025-12-03T22:59:12.566449Z

🦅 https://github.com/theronic/eacl v6.1 now yields sub-millisecond performance when enumerating 1k of 800k permissioned entities in pages of 50 results, all backed by Datomic: • EACL is a https://en.wikipedia.org/wiki/Relationship-based_access_control authorization library based on https://authzed.com/spicedb, built in Clojure and backed by Datomic. • Here is a https://x.com/PetrusTheron/status/1996344248925294773 of EACL used from an https://electric.hyperfiddle.net/ v3 application with real-time enumeration of permissioned resources via eacl/lookup-resources. • There is still plenty of room for improvement: I expect expect another 2x improvement when v7 lands, which has a tighter data model backed by heterogenous tuples, but has breaking schema changes. • This v6.1 update introduces no breaking changes API or schema changes and will soon land in main. • You can read the rationale behind EACL on http://eacl.dev.

2
🥳 6
xlfe 2025-08-28T23:51:18.341359Z

Very nice - just reading through your examples - Thank you (and to your employer) for making this open source 🎉

👍 1
robert-stuttaford 2025-12-04T14:39:38.766359Z

I love Datomic a lot but what makes me love it the most is tuples. The ability to elevate performance with composite keys and not lose anything else I already have still routinely blows my mind 😄

1