Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Whole domain authorisation #85

merged 9 commits into from
Jan 7, 2022

Whole domain authorisation #85

merged 9 commits into from
Jan 7, 2022


Copy link

@gsvarovsky gsvarovsky commented Dec 31, 2021

Whole domain authorisation

It will be possible for an app to register the current user identity with the clone, and have the clone allow or prevent write access to the whole domain based on some hard-coded information.

This feature has been developed as a partial implementation of the Symmetric Unilateral Access Control (SUAC) specification.

A m-ld Access Control List (m-ld ACL) extension has been created, for a new "transport security" extension point. If installed for a clone, the extension controls access to the domain based on security principals (users) registered in the domain data. (This goes beyond the original milestone description which only required hard-coded metadata; see italicised, above). The available control is "whole domain" read/write access permission.


The m-ld ACL extension implements the following features of the SUAC protocol.

  • Application authentication (however implemented) must provide the ACL extension with a security principal object representing the local user. This principal must have an IRI identifier, and must be capable of signing binary data using RSASSA-PKCS1-v1_5. This approach is consistent with WebID-TLS authentication, but can also be used with other PKI-based authentication models.
  • A domain 'secret' can be registered in the data. If present, this is used to encrypt operation messages sent and received by the chosen remotes implementation using AES-CBC encryption. (This is slightly at variance with the protocol specification, which called for the security to be applied by native 'channel' security. By using encryption in the layer above the remotes, we have made it possible to secure the channel for all remotes implementations homogeneously. Note that it would still be possible to use channel-level security by deriving a subclass of the m-ld ACL extension.)
  • Users are registered in the domain by including their RSA public key in the domain data.

These features are sufficient to prevent unregistered users from:

  1. Joining the domain by snapshot request – because snapshot requests must be signed by a registered user.
  2. Intercepting operation messages – because operations are encrypted using a secret only known to users that have already joined the domain.

Module Structure

The feature has been included in the main engine project primarily as an optional extension module, src/security/MeldAccessControlList.ts. This is consistent with other optional modules such as Remotes and Constraints. It would be possible to separate the extension to another project if required.

The extension uses a new extension point which has been wired into the existing clone bootstrapping code, accommodated by various refactorings. In particular:

  • Extensions are now packaged in MeldExtensions (in src/api.ts), which includes the pre-existing constraints extension point and the new MeldTransportSecurity extension point.
  • The AppPrincipal and bootstrap extensions are provided as part of the MeldApp object which is given to the main m-ld entry point method, clone (in src/index.ts).

Note that one technical hurdle required for this feature was making a consistent immutable domain state available to the new transport security extension point, which is applied from the remotes implementation. This required refactoring of the remotes base class in src/engine/remotes/PubsubRemotes.ts.


Besides various test refactorings required for the changes to the core project, verification of the new extension point feature is based on:

  1. A unit test specification in test/AccessControlList.test.ts. This uses a bare-bones dataset to animate the ACL extension class, to check that it encrypts operations and signs requests as required. Unit tests are currently run as part of the vercel build.
  2. A compliance test specification in compliance/test/1-acl.spec.js. This uses a full clone, deployed with LevelDB persistence, MQTT remotes and a REST endpoint for animation, as per other compliance tests. Since this security feature is not yet part of the m-ld specification, its compliance test is found in this project rather than the m-ld-spec project. Compliance tests are now run using CircleCI; see the results for this branch.

Next Steps

The next part of the project involves extending this prototype to implement SUAC agreements. These are necessary for robust registration of users and the domain secret. They will also support changing the transport security extension during the lifetime of the domain, by also including the extension registration in the domain data (unlike here, where it is set during clone initialisation). And of course, they will also support fine-grained write access controls as described in the SUAC specification.

Further Information

The source code is well-documented with comments. In particular, the compliance test specification in compliance/test/1-acl.spec.js comprises a readable walk-through.

Fixes for NodeJS 16+ (Flowable test & Future)
Subject property casting convenience function
Get-with-property shorthand state method
Wiring extensions into engine as single manager object
Module refactoring to remove circular dependencies
Deps update
Copy link

vercel bot commented Dec 31, 2021

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect:
✅ Preview:

@gsvarovsky gsvarovsky changed the title Whole domain read authorisation Whole domain authorisation Jan 2, 2022
Various fallout: fixing clone & remotes close() bugs that were hidden by process death
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet

Successfully merging this pull request may close these issues.

None yet

1 participant