EACL: Enterprise Access Control. Spice-compatible authorization system in Datomic.
EACL: Enterprise Access Control. Spice-compatible authorization system in Datomic.
(affected-relation-ids tx-data)Returns every relation eid named by relationship endpoint mutations.
Returns every relation eid named by relationship endpoint mutations.
(can! db subject permission resource)Like can?, but throws :eacl/unauthorized instead of returning false.
Like can?, but throws :eacl/unauthorized instead of returning false.
(can? db {:keys [subject permission resource]})(can? db subject permission resource)(count-resources db query)(count-subjects db query)(find-one-relationship-id db relationship)Returns the resolved identity for a supported complete pair, or nil.
Returns the resolved identity for a supported complete pair, or nil.
(guard-schema-version db ops)Appends one schema-generation CAS guard to ops, when the db is stamped.
Appends one schema-generation CAS guard to `ops`, when the db is stamped.
(lookup-resources db query)(lookup-resources db query lookup-opts)(lookup-subjects db query)(lookup-subjects db query lookup-opts)(optimistic-relationship-tx-data db ops)Turns ordinary idempotent relation stamps into commit-time CAS stamps.
Public relationship writes use this to serialize competing mutations of the same relation. A CAS loser rebuilds from a fresh db: duplicate :create then observes the winner and throws :eacl/relationship-conflict, while unrelated writes simply retry. The schema guard is deduplicated at the same boundary.
Turns ordinary idempotent relation stamps into commit-time CAS stamps. Public relationship writes use this to serialize competing mutations of the same relation. A CAS loser rebuilds from a fresh db: duplicate :create then observes the winner and throws :eacl/relationship-conflict, while unrelated writes simply retry. The schema guard is deduplicated at the same boundary.
(orphaned-relationship-halves db)Offline exact-peer diagnostics, including malformed and mismatched qualifiers.
Offline exact-peer diagnostics, including malformed and mismatched qualifiers.
(read-relationships db filters)(read-relationships db filters decision-kernel)(read-relationships db filters decision-kernel window-options)(Relationship subject relation resource)Constructs relationship data for the public/internal API boundary. Persistence is handled by tuple-specific write helpers below.
Constructs relationship data for the public/internal API boundary. Persistence is handled by tuple-specific write helpers below.
(relationship-publication-input db relationship)Resolves the same endpoint identities and commit guards as ordinary writes.
Resolves the same endpoint identities and commit guards as ordinary writes.
(relationship-relation-id db relationship)Returns the schema relation eid named by one resolved relationship.
Returns the schema relation eid named by one resolved relationship.
(stamp-relation-versions ops)Ensures ops carries a version stamp for every relation it retracts.
tx-delete-object deduplicates its output, which keeps only the first stamp per relation. That is correct for a single transaction and WRONG for a batched one: a batch holding the second half of a relation's retractions would change relationship data while publishing nothing, and a reader would keep serving a cached answer that the retraction had already invalidated.
Idempotent — stamping an already-stamped batch adds nothing, because the stamp is the same [e a v] triple either way.
Ensures `ops` carries a version stamp for every relation it retracts. tx-delete-object deduplicates its output, which keeps only the first stamp per relation. That is correct for a single transaction and WRONG for a batched one: a batch holding the second half of a relation's retractions would change relationship data while publishing nothing, and a reader would keep serving a cached answer that the retraction had already invalidated. Idempotent — stamping an already-stamped batch adds nothing, because the stamp is the same [e a v] triple either way.
(tx-delete-object db object-id)Materialized transaction data removing every EACL relationship touching
object-id, in both directions, without retracting the object itself.
This compatibility helper returns one vector suitable for ONE transaction.
delete-object! uses tx-delete-object-stream instead, partitions it before
realization, and stamps every batch, so a high-degree object does not require
retaining its complete retraction vector in heap.
Large results are transacted in batches by delete-object!, so use
stamp-relation-versions on any slice of this output before transacting it
separately — the deduplication below keeps only the FIRST stamp for each
relation, which would otherwise leave later batches retracting relationships
without publishing that they changed.
Materialized transaction data removing every EACL relationship touching `object-id`, in both directions, without retracting the object itself. This compatibility helper returns one vector suitable for ONE transaction. `delete-object!` uses `tx-delete-object-stream` instead, partitions it before realization, and stamps every batch, so a high-degree object does not require retaining its complete retraction vector in heap. Large results are transacted in batches by delete-object!, so use `stamp-relation-versions` on any slice of this output before transacting it separately — the deduplication below keeps only the FIRST stamp for each relation, which would otherwise leave later batches retracting relationships without publishing that they changed.
(tx-delete-object-stream db object-id)Lazy retraction ops removing every EACL relationship touching object-id.
object-id is resolved the same way reads resolve object ids (string ->
[:eacl/id ...], anything else -> d/entid), so it also accepts the raw eid of
an entity already retracted the bare Datomic way. Returns an empty sequence
for an id that does not resolve.
Healthy relationships are emitted from the peer halves that NAME this
object. The object's own halves are emitted only when their peer is absent,
preserving cleanup of corrupt/orphan data without emitting every healthy
relationship twice. A self-relationship is emitted once from its forward
half. The resulting stream therefore needs no whole-result distinct set.
This low-level stream intentionally contains only tuple retractions. Every
transaction-sized slice MUST pass through stamp-relation-versions; the
public delete-object! does this automatically. Keeping stamps batch-local is
what makes discovery and heap use bounded by the batch size.
Lazy retraction ops removing every EACL relationship touching `object-id`. `object-id` is resolved the same way reads resolve object ids (string -> [:eacl/id ...], anything else -> d/entid), so it also accepts the raw eid of an entity already retracted the bare Datomic way. Returns an empty sequence for an id that does not resolve. Healthy relationships are emitted from the peer halves that NAME this object. The object's own halves are emitted only when their peer is absent, preserving cleanup of corrupt/orphan data without emitting every healthy relationship twice. A self-relationship is emitted once from its forward half. The resulting stream therefore needs no whole-result `distinct` set. This low-level stream intentionally contains only tuple retractions. Every transaction-sized slice MUST pass through `stamp-relation-versions`; the public delete-object! does this automatically. Keeping stamps batch-local is what makes discovery and heap use bounded by the batch size.
(tx-relation-version-stamp relation-eid)Stamps the relation with the transaction that is changing it.
This is how a writer publishes WHAT changed rather than merely THAT something changed: the stamp lands atomically with the relationship datoms, so no db value can show one without the other. Readers take the max stamp over the relations a permission depends on, so churn on an unrelated relation leaves cached answers alone.
The value is the transaction entity rather than a fresh id, which makes the assertion idempotent — the same [e a v] however many times it is emitted in one transaction. That is what lets every relationship-producing helper append its own stamp unconditionally, and lets callers concat several helpers' output into a single transaction without provoking :db.error/datoms-conflict.
Stamps the relation with the transaction that is changing it. This is how a writer publishes WHAT changed rather than merely THAT something changed: the stamp lands atomically with the relationship datoms, so no db value can show one without the other. Readers take the max stamp over the relations a permission depends on, so churn on an unrelated relation leaves cached answers alone. The value is the transaction entity rather than a fresh id, which makes the assertion idempotent — the same [e a v] however many times it is emitted in one transaction. That is what lets every relationship-producing helper append its own stamp unconditionally, and lets callers concat several helpers' output into a single transaction without provoking :db.error/datoms-conflict.
(tx-relationship db relationship)(tx-relationship db relationship opts)(tx-relationship db subject relation resource)Translate relationship data into v7 tuple writes.
Strict by default: endpoints must resolve to existing entities or this throws :eacl/unknown-object. Pass {:allow-tempids? true} to let unresolvable string ids / tempids pass through for same-transaction entity+relationship creation (fixtures-style).
Translate relationship data into v7 tuple writes.
Strict by default: endpoints must resolve to existing entities or this
throws :eacl/unknown-object. Pass {:allow-tempids? true} to let unresolvable
string ids / tempids pass through for same-transaction entity+relationship
creation (fixtures-style).(tx-retract-orphaned-relationships db)Retraction tx-data for orphaned-relationship-halves. Fails closed: an orphan means one endpoint is gone, so the survivor should stop granting. Returns a lazy sequence; transact in batches on large databases.
Stays lazy: the relation stamps are emitted inline rather than deduplicated up front, which is safe because they are idempotent within a transaction.
Retraction tx-data for orphaned-relationship-halves. Fails closed: an orphan means one endpoint is gone, so the survivor should stop granting. Returns a lazy sequence; transact in batches on large databases. Stays lazy: the relation stamps are emitted inline rather than deduplicated up front, which is safe because they are idempotent within a transaction.
(tx-schema-version-guard db)Commit-time assertion that relationship tx-data is applied under the same schema generation it was resolved against.
This prevents a delayed relationship transaction from resurrecting a
relation entity after a concurrent write-schema! removed it. A database
whose schema generation has never been published (definitions installed as
data, or a pre-v8 database that has not run write-schema! yet) is the
supported unstamped v7-compatibility regime: reads recompute their paths
instead of latching, the cache is exact-snapshot only, and writes commit
without this guard — run write-schema! once (a zero delta still stamps)
to publish the generation and arm the guard.
Commit-time assertion that relationship tx-data is applied under the same schema generation it was resolved against. This prevents a delayed relationship transaction from resurrecting a relation entity after a concurrent write-schema! removed it. A database whose schema generation has never been published (definitions installed as data, or a pre-v8 database that has not run `write-schema!` yet) is the supported unstamped v7-compatibility regime: reads recompute their paths instead of latching, the cache is exact-snapshot only, and writes commit without this guard — run `write-schema!` once (a zero delta still stamps) to publish the generation and arm the guard.
(tx-update-relationship db {:keys [operation relationship]})Relationship writes use the storage 8 forward/reverse tuple indexes. :touch is idempotent. Endpoints must resolve to existing entities.
Relationship writes use the storage 8 forward/reverse tuple indexes. :touch is idempotent. Endpoints must resolve to existing entities.
(validate-relationship-operation! operation)Validates an update operation before any relationship endpoint work.
Validates an update operation before any relationship endpoint work.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |