Skip to content

Commit

Permalink
#3: Data-driven authorisation prototype ongoing
Browse files Browse the repository at this point in the history
Refinements to design
  • Loading branch information
gsvarovsky committed Mar 4, 2022
1 parent 4ecfa0e commit d3021ba
Show file tree
Hide file tree
Showing 10 changed files with 6,879 additions and 7,855 deletions.
12 changes: 5 additions & 7 deletions design/1-genesis-alice.seq.puml
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,15 @@ rnote left
"mld:certificate": "1234",
"mld:hasPermission": [{
"@type": "mld:Authority",
"mld:appliesToPattern": { "@id": "?" }
}, {
"@id": "mld:readPermission"
"mld:controlledShape": {
"@id": "AllSubjects",
"@type": "sh:NodeShape"
}
}]
}, {
"@id": "Bob",
"@type": "mld:Principal",
"mld:certificate": "5678",
"mld:hasPermission": {
"@id": "mld:readPermission"
}
"mld:certificate": "5678"
}, {
"@id": "mld:accessControlStatute",
"mld:sufficientCondition": {
Expand Down
19 changes: 8 additions & 11 deletions design/agreement.class.puml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ package mld {
class AgreementCondition <<statutory>> <<extension point>>

abstract class Principal <<extension point>>
note right
gives access
to the domain
end note
class PkiPrincipal {
certificate : String
}
Expand All @@ -21,30 +25,23 @@ note left
Authority is permission
to unilaterally agree.
---
A "lock" is just
temporary authority.
A "lock" is just temporary
exclusive authority.
end note
object hasAuthority
hasAuthority --> AgreementCondition : rdf:type
hasAuthority ..> Authority : <<require>>
Permission "*" <--o Principal : hasPermission

abstract class Permission
abstract class Permission <<statutory>>
Permission --|> AccessControl

class WritePermission {
appliesToPattern : json-rql
controlledShape : sh:NodeShape
}
Authority --|> WritePermission
WritePermission --|> Permission

object readPermission
note right
gives access
to the domain
end note
readPermission --> Permission : rdf:type

class RaftConsensus {
mtbf : float
electionTimeout : float
Expand Down
26 changes: 11 additions & 15 deletions design/img/1-genesis-alice.seq.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
81 changes: 37 additions & 44 deletions design/img/agreement.class.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14,302 changes: 6,592 additions & 7,710 deletions design/img/security design.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 9 additions & 7 deletions design/img/statute.class.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
219 changes: 185 additions & 34 deletions design/security design.mm

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion design/statute.class.puml
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ end note
rdfsStatute --> Statute : rdf:type

object accessControlStatute {
statutoryClass = AccessControl
statutoryProperty = access
statutoryClass = AccessControl
statutoryClass = Permission
}
note top
Choice of access control
Expand Down
8 changes: 5 additions & 3 deletions design/suac.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ Note the two operation data checks involved – checking for a statute (meaning
Verifying authority is the same as for any other permission, as follows. For an operation it is necessary to identify:

- The security principal who enacted it. Here we give the example of using Public Key Infrastructure (PKI), in which a user has a certificate that can be used to sign operation messages (see below). A permission is assigned to a `Principal` in the data, having a certificate property. (We explore identity and authentication further in the [traceability](./traceability.md) design.)
- Whether the principal had a permission which _applies to_ the changed data. Here we choose to support application of permissions to any **json-rql** [Pattern](https://json-rql.org/interfaces/pattern.html). This supports any data selector e.g. (informally) "all data belonging to this group". (We note that in this scheme, permission checking could become an unbounded query optimisation problem – we intend to explore this in the prototype.)
- Whether the principal had a permission which _controls_ the changed data. Here we choose to support application of permissions to [SHACL node shapes](https://www.w3.org/TR/shacl/#node-shapes). This supports a data selector e.g. (informally) "all subjects having this Class", or "all data belonging to this group". Note that in the prototype, the available SHACL features will be the minimal necessary for demonstration of the principle.<sup>1</sup>

Since access control by "whitelist" permissions may not suit all use-cases, the choice of approach is made through the `access` property of the domain itself. (Note that this requires the domain to be represented as a subject in the data; this is an open [topic of discussion](https://github.com/m-ld/m-ld-spec/discussions/75).)

Expand Down Expand Up @@ -169,7 +169,7 @@ Next, we consider the steps required for Bob to join the domain with his device.

Again, Bob must authenticate to the app, and then the clone may initialise and connect to the message service (but not yet to the domain channel, which is further protected by the domain secret). As a new but non-genesis clone, it must receive the domain data using a snapshot request from any available clone (Alice's clone being the only one; note that this may be technically routed through the message service, but it is characteristically a request/response). This request is signed (by Bob's private key, if PKI certificates are in use).

On receipt of the snapshot request, Alice's clone is able to inspect the signature and determine if a security principal exists in the data having `readPermission` and the corresponding identity. In this case, this is so, and therefore Alice's clone responds successfully to the snapshot request.
On receipt of the snapshot request, Alice's clone is able to inspect the signature and determine if a security principal exists in the data having the corresponding identity. In this case, this is so, and therefore Alice's clone responds successfully to the snapshot request.

Having the data, Bob's clone is now able to read the domain secret, and so connect to the domain channel on the message service.

Expand All @@ -191,7 +191,7 @@ Let us consider the case in which an engine is actually malware, and permits una

![4-ivan-malware-clone-reject.seq](./img/4-ivan-malware-clone-reject.seq.svg)

(Note that this case assumes Ivan has `readPermission`; we have omitted the setup for brevity.)
(Note that this case assumes Ivan is a Principal; we have omitted the setup for brevity.)

The clone on Ivan's device does not correctly apply access control: in this case, it has allowed a transaction for which Ivan does not have a `WritePermission`. When this operation arrives at Alice's clone, the (normally symmetrical) application of access control will reject it. Alice's clone thereby retains its data integrity; but also, it knows that it has diverged ("forked") irretrievably from Ivan's clone. It must therefore ignore any further operations from Ivan's clone.

Expand Down Expand Up @@ -250,3 +250,5 @@ This scheme is probabilistic (trust is non-binary) and eventual (detection is no
---

_For bibliographic references, see the [project references file](../references.bib)._

1. In a previous version we suggested that write permissions could apply to an arbitrary **json-rql** pattern. In this scheme, permission checking could become an unbounded query optimisation problem. Use of a SHACL shape offers similar ultimate flexibility (informally, SHACL was [influenced by SPIN](https://spinrdf.org/spin-shacl.html), which represents "SPARQL rules and constraints"; **json-rql** being a serialisation of SPARQL), but is more straightforward to author, and to restrict to features suitable for the prototype.
48 changes: 25 additions & 23 deletions prototype/security prototype.mm
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@
<node TEXT="recovery request signature" ID="ID_762810241" CREATED="1639383996046" MODIFIED="1639561037719">
<node TEXT="sign" ID="ID_1300253912" CREATED="1639560964914" MODIFIED="1639560968279"/>
<node TEXT="verify" ID="ID_413421205" CREATED="1639498847534" MODIFIED="1639560971441"/>
<node TEXT="check readPermission" ID="ID_1620562995" CREATED="1639498876514" MODIFIED="1639498882073"/>
<node TEXT="needs sigs before data" ID="ID_1340012247" CREATED="1639561043512" MODIFIED="1639570250519">
<icon BUILTIN="messagebox_warning"/>
<node TEXT="negotiate" ID="ID_73944874" CREATED="1639561116755" MODIFIED="1639569325977">
Expand Down Expand Up @@ -250,15 +249,16 @@
<icon BUILTIN="button_ok"/>
</node>
<node TEXT="Agreements" ID="ID_1680785379" CREATED="1642613582376" MODIFIED="1642613588081">
<node TEXT="Explicit agreements" ID="ID_1420228138" CREATED="1642934668099" MODIFIED="1642940102790">
<node TEXT="Explicit agreements" ID="ID_1420228138" CREATED="1642934668099" MODIFIED="1644422758536">
<icon BUILTIN="button_ok"/>
<node TEXT="isolate agreement feature for testing" ID="ID_1913906653" CREATED="1642934678394" MODIFIED="1642935582687"/>
<node TEXT="any use-cases?" ID="ID_1330663583" CREATED="1642934682241" MODIFIED="1642934687214"/>
<node TEXT="&apos;= disallow concurrent" ID="ID_369652070" CREATED="1642935229090" MODIFIED="1642935256632"/>
<node TEXT="(must have Authority, if ACL in place)" ID="ID_28590412" CREATED="1642935377852" MODIFIED="1642940089517">
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#000000" WIDTH="2" TRANSPARENCY="200" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_681639962" STARTINCLINATION="345;0;" ENDINCLINATION="345;0;" STARTARROW="NONE" ENDARROW="DEFAULT"/>
<node TEXT="(must have Authority, if ACL in place)" ID="ID_28590412" CREATED="1642935377852" MODIFIED="1644480709169"/>
</node>
<node TEXT="≪agree≫ MeldOperation" ID="ID_588356156" CREATED="1642614246264" MODIFIED="1644422768875">
<icon BUILTIN="button_ok"/>
</node>
<node TEXT="≪agree≫ MeldOperation" ID="ID_588356156" CREATED="1642614246264" MODIFIED="1642614423713"/>
<node TEXT="Constraints can upgrade to agreement" ID="ID_539406319" CREATED="1642614150591" MODIFIED="1642936409299"/>
<node TEXT="process before constraints" ID="ID_1175581090" CREATED="1642773312551" MODIFIED="1642936775580" LINK="#ID_1890482937"/>
<node TEXT="Fork/Void MeldApp cb" ID="ID_1051377186" CREATED="1642614609973" MODIFIED="1644419529942">
Expand All @@ -271,10 +271,21 @@
</node>
</node>
</node>
<node TEXT="ACL Constraint" ID="ID_1599749441" CREATED="1642613572982" MODIFIED="1642936221099">
<node TEXT="Data extension installation" ID="ID_187588822" CREATED="1642612873834" MODIFIED="1642612897719">
<node TEXT="Transport Security" ID="ID_915455374" CREATED="1642612898595" MODIFIED="1642760761589"/>
<node TEXT="Constraints" ID="ID_1579989132" CREATED="1642612907382" MODIFIED="1642760686101">
<node TEXT="schema" ID="ID_1739805795" CREATED="1642854143519" MODIFIED="1642937232478" LINK="https://github.com/m-ld/m-ld-spec/issues/73"/>
</node>
<node TEXT="Agreement conditions" ID="ID_1355897688" CREATED="1644480542793" MODIFIED="1644480546113"/>
</node>
<node TEXT="ACL extensions" ID="ID_1599749441" CREATED="1642613572982" MODIFIED="1644505691315">
<node TEXT="" ID="ID_331427747" CREATED="1642767468354" MODIFIED="1642767468354">
<hook NAME="FirstGroupNode"/>
</node>
<node TEXT="agreement condition" ID="ID_1710650399" CREATED="1644434469776" MODIFIED="1644434475033">
<node TEXT="hasAuthority" ID="ID_681639962" CREATED="1642935442102" MODIFIED="1644480853030"/>
</node>
<node TEXT="constraints" ID="ID_78745856" CREATED="1644434447050" MODIFIED="1644434453793">
<node TEXT="writable-if-class-subject-property" ID="ID_1622635240" CREATED="1642761664865" MODIFIED="1642761707301">
<node TEXT="" ID="ID_1441424994" CREATED="1642766979575" MODIFIED="1642766979575">
<hook NAME="FirstGroupNode"/>
Expand All @@ -296,14 +307,6 @@
</node>
</node>
<node TEXT="writable-if-class-principal" ID="ID_1410857108" CREATED="1642760282257" MODIFIED="1642760300651"/>
<node TEXT="agree-if-class-principal" ID="ID_681639962" CREATED="1642935442102" MODIFIED="1642938884580">
<node TEXT="means &quot;Authority&quot;" ID="ID_496293689" CREATED="1642938804073" MODIFIED="1642938817023"/>
</node>
<node TEXT="" ID="ID_781159735" CREATED="1642767468353" MODIFIED="1642767468354">
<hook NAME="SummaryNode"/>
<hook NAME="AlwaysUnfoldedNode"/>
<node TEXT="require ASK" ID="ID_111008046" CREATED="1642767468354" MODIFIED="1642767495264" LINK="#ID_1894193859"/>
</node>
<node TEXT="add-only-property" ID="ID_1281234769" CREATED="1642759271969" MODIFIED="1642776170233">
<icon BUILTIN="button_cancel"/>
<node TEXT="esoteric" ID="ID_524540008" CREATED="1642760475004" MODIFIED="1642774768894"/>
Expand Down Expand Up @@ -335,18 +338,23 @@
</node>
</node>
</node>
<node TEXT="" ID="ID_781159735" CREATED="1642767468353" MODIFIED="1642767468354">
<hook NAME="SummaryNode"/>
<hook NAME="AlwaysUnfoldedNode"/>
<node TEXT="require ASK" ID="ID_111008046" CREATED="1642767468354" MODIFIED="1642767495264" LINK="#ID_1894193859"/>
</node>
</node>
<node TEXT="Statutes Constraint" ID="ID_694549622" CREATED="1642776463447" MODIFIED="1642934573655">
<node TEXT="upgrades Update to Agreement" ID="ID_1600788097" CREATED="1642934602489" MODIFIED="1644434578500" LINK="#ID_539406319"/>
<node TEXT="vocab" ID="ID_443571171" CREATED="1642936259032" MODIFIED="1642936261778">
<node TEXT="Statute + AgreementCondition" ID="ID_1853010739" CREATED="1642936262317" MODIFIED="1642936338475" LINK="https://github.com/m-ld/m-ld-security-spec/blob/main/design/statute.class.puml"/>
<node TEXT="appliesTo: [DELETE | INSERT]" ID="ID_608107520" CREATED="1642776474416" MODIFIED="1642776511273"/>
</node>
<node TEXT="upgrades Update to Agreement" ID="ID_1600788097" CREATED="1642934602489" MODIFIED="1642936413737">
<arrowlink SHAPE="CUBIC_CURVE" COLOR="#000000" WIDTH="2" TRANSPARENCY="200" FONT_SIZE="9" FONT_FAMILY="SansSerif" DESTINATION="ID_539406319" STARTINCLINATION="262;0;" ENDINCLINATION="262;0;" STARTARROW="NONE" ENDARROW="DEFAULT"/>
</node>
</node>
<node TEXT="Constraint apply rejection" ID="ID_1101291117" CREATED="1642767146292" MODIFIED="1642767200924">
<node TEXT="if reason = unauthorised" ID="ID_519734221" CREATED="1642767653870" MODIFIED="1642767662365">
<node TEXT="with statutes, can only arise from a malicious clone" ID="ID_1890482937" CREATED="1642768099943" MODIFIED="1642772885415"/>
<node TEXT="(if has not reached agreement, op would be ignored)" ID="ID_1457085052" CREATED="1644565568480" MODIFIED="1644565586686"/>
<node TEXT="remove principal" ID="ID_1361507994" CREATED="1642772932980" MODIFIED="1642773122265">
<icon BUILTIN="button_cancel"/>
<node TEXT="can&apos;t if no permission" ID="ID_691992525" CREATED="1642772945468" MODIFIED="1642772968305">
Expand All @@ -370,12 +378,6 @@
</node>
</node>
</node>
<node TEXT="Data extension installation" ID="ID_187588822" CREATED="1642612873834" MODIFIED="1642612897719">
<node TEXT="Transport Security" ID="ID_915455374" CREATED="1642612898595" MODIFIED="1642760761589"/>
<node TEXT="Constraints" ID="ID_1579989132" CREATED="1642612907382" MODIFIED="1642760686101">
<node TEXT="schema" ID="ID_1739805795" CREATED="1642854143519" MODIFIED="1642937232478" LINK="https://github.com/m-ld/m-ld-spec/issues/73"/>
</node>
</node>
<node TEXT="json-rql literals" ID="ID_1481867948" CREATED="1642612964084" MODIFIED="1642760737096">
<icon BUILTIN="button_cancel"/>
<node TEXT="or Graph Literals" ID="ID_1141968767" CREATED="1642613652151" MODIFIED="1642614109618" LINK="https://www.w3.org/2009/07/NamedGraph.html">
Expand Down

0 comments on commit d3021ba

Please sign in to comment.