What must an adapter and a mediated repo satisfy? For someone who writes an adapter or binds a repo.

A law is one test in Mediate.Conformance.AdapterCase, named by a law id and one sentence. An adapter is conformant when every law passes against its real engine over a population it did not write. A law an adapter cannot run prints its reason and never skips in silence. Mediate.Conformance.Law.all/0 holds the table below as data, and the freeze test in mediate_conformance holds it to this document row for row.

The laws

IdSentenceControls
ac2-01A single-row write of an account through the seam emits one change event with the actor, the target, and the clearance before and afterAC-2, AC-2(4)
ac2-02By the configured clock and not the database's, a grant that expires one second later allows and one that expired one second earlier deniesAC-2(2), AC-2(3)
ac2-03When an account fact no longer satisfies the rule, the next check denies the subject with no other changeAC-2(3), PS-5
ac2-04Review answers every subject with exactly the objects check allows, and emits one decision per subject and one for the reviewer under one operation idAC-2(7), AC-6(7)
ac2-05After a revocation the next check denies, and the test prints the latency from revocation to denial and never asserts itAC-2(13), PS-4
ac3-01check agrees with the world's own rule for every subject, operation, and object drawnAC-3
ac3-02The seam denies an ungranted object, an unknown operation, and an unknown subject, and denies an unknown subject kind before it calls the adapterAC-3
ac3-03scope returns exactly the rows check allows for every protected schema, and a denied scope admits no rowAC-3
ac3-04scope over a thousand rows is one decision and one query beyond setupAC-3
ac3-05An unreachable engine denies every call and emits one decision event per call that carries the exceptionAC-3
ac6-01check allows the user that holds a grant and denies the privileged subject of the same account on the same objectAC-6(2)
au2-01Every authorize and check emits exactly one decision event with subject, kind, operation, object, verdict, reason, version, operation id, and timeAU-2, AC-6(9)
au2-02A denial's decision event carries the reason for itAU-2
au2-03scope and review emit decisions with a scoped verdictAU-2
au3-01No decision event carries a value the rule reads from the worldAU-3
au3-02A change event carries operation, kind, target, actor, time, operation id, and the old and new value of every fact column that changedAU-3
au3-03An access event carries object type, ids, decision id, subject, operation id, and timeAU-3
au3-04The decision, change, and access events of one operation each carry its operation id and its decision idAU-3(1)
au12-01A single-row write to an audited schema emits its change event inside the write's transactionAU-12, AC-2(4)
au12-02A bulk write to an audited schema raises and changes nothingAU-12
au12-03A write that goes around the seam emits nothingAU-12
au12-04A write the database refuses leaves no row and no eventAU-12
au12-05The repo refuses an unmediated read or write of a protected schemaAU-12
au12-06Every mediated read of a protected schema emits one access event, and a read under an exemption emits noneAU-12
cm3-01When the adapter publishes a version, it emits its version event, and the version names its author and its approvalCM-3, CM-5
cm3-02A decision reports the version in force when the adapter took it, before and after the adapter publishes a new versionCM-3(2)
cm3-03A tightened rule is a policy version that names its artifact as content or as a pointer, and denies the reader it excludesCM-5(1)
cm3-04After the adapter publishes a tightened rule, check denies the reader it excludes, and the test prints the propagation latency and never asserts itCM-3(2)

Beside the laws, the template defines two more tests: the adapter declares its scope cap, and a single-row fact write is the write alone and one change event. au12-07, every column a rule reads is a declared fact, is one coverage test per adapter package whose rules read columns: Mediate.Rbac.Coverage, Mediate.Postgres.Coverage, and Mediate.Cerbos.Coverage. For OpenFGA the tuple mapping case stands in, because the mapping is the declaration. Each thin application runs its own coverage test too.

ac3-01, ac3-02, and ac3-03 are stream_data properties over populations Mediate.Conformance.Gen draws from the world. ac3-04 and the fact-write shape count queries and events, and the counts are exact in the sandbox. ac2-05 and cm3-04 write on the committed repo, poll until the first denial, and print the latency and its components.

The guarantees

A guarantee is one test in Mediate.Conformance.RepoCase, which every mediated repo passes. The case also holds the repo's exports to the surface the seam classifies, and asserts that every query, write, and raw function refuses a call on a protected schema that carries no decision. Mediate.Conformance.RepoCase.guarantees/0 holds this table as data, and the freeze test holds it to this document row for row.

IdSentence
E1A single-row write to an audited schema emits one change event with every fact field that changed
E2A bulk write to an audited schema raises and emits nothing
E3A write that goes around the seam emits nothing
E4A consumer that writes to the same repository from its handler joins the write transaction
E5A mediated read of a protected schema emits one access event with its rows and its decision, and a read under an exemption emits none

Running the suite against your adapter

An adapter outside this repository supplies its own Mediate.Conformance.World, its own repo, its own Postgres, and the artifacts its mechanism needs. The Mediate.Conformance.AdapterCase moduledoc has the options and what each adapter in this repository passes. The Mediate.Conformance.RepoCase moduledoc has the rows: module a repo supplies. The template reads nothing else.

Words

  • Attribute, fact. A value about a subject or object that a rule can test, declared on a schema with fact/2.
  • Grant. A row that gives a subject a role on an object, declared with relationship/1.
  • Fail closed. No, when the system cannot decide.
  • Scope fidelity. scope returns exactly the rows check allows.
  • Consumer. The handler the deployer attaches to the events, which writes the record.
  • Revocation latency. The time from a revoked fact to the first denial, printed and never asserted.
  • Shape test. A test that counts queries and events, never time.
  • Thin application. The binding of one domain to one adapter.
  • Protected schema. A schema that declares an object type, which the seam refuses to read or write without a decision.