Distributed VCS + Central ACL

September 16th, 2007 by Ralf S. Engelschall

In the Version Control System (VCS) area there are currently mainly two camps: the centralized ones like the good old CVS, the successor Subversion, etc and the distributed ones like the modern Monotone, Mercurial, Git, Bazaar, etc.

The interesting point is that the central VCS style of working inherently allows strong access control while in the distributed VCS style of working the “share everything between everybody” is the primary mantra. If one wants to combine both distributed version control and central access control, it becomes between interesting and partly impossible.

The Inherent Conflict

Lots of reasons exist for this, but one of the main reasons is this: in distributed versioning usually everyone can pull revisions of the sources from the master, arbitrarily branch locally, merge with arbitrary branches of foreigners locally, etc. And once he wishes to push the resulting revision back to the master, the problem exists that although he personally is granted access (for the target branch) in the master repository, his revision indirectly has the revisions of the foreigners attached/referenced which in turn do not have access to the repository (or at least its target branch). This scenario especially occurs if contributions to a project are juristically restricted based on a contributor agreement. So, the restriction also has to be enforced technically, of course.

Trying to solve the problem for Monotone…

The Monotone VCS I’m focusing on currently has no support for this scenario, although there exist at least multiple proposals for so-called “policy branches”. These are branches carrying meta information about what is allowed/denied on particular branches or whole branch trees (in case the branches use a hierachical naming scheme). But this is still not implemented and as the name implies seems to be just a policy and not an enforcement. It certainly will help to make sure that people in their local repositories do not merge/propagate revisions from the wrong (foreign) branches, etc. But at least on the master repository IMHO one needs a strong enforcement of such a policy.

Hence I’ve started to implement a solution for Monotone which directly hooks into Monotone’s NETSYNC processing of the mtn serve process at the master site and already rejects receiving data (keys, revisions and certificates) if they as a whole do not strictly comply to the master site access control policy. By linking this even to the database containing the information about acceeded contributor agreements one can (at least on the master site) technically make sure that no foreign code is indirectly smuggled in as all(!) revisions in the whole propagate/merge history (across arbitrary branches) conform to the policy.

The experimental implementation looks like this:

  1. Monotone was extended (in C++) with four additional NETSYNC Lua hooks: one for the receiving and storage of each type of data: epoch, key, revision, cert. The hook for each data can decide whether to accept, ignore or reject it. And for rejecting it can decide whether after aborting the NETSYNC session the already received data is kept (database transaction commit) or thrown away (database transaction rollback).
  2. A generic NETSYNC hooking abstraction layer for Monotone Lua was written which allows arbitrary Lua extensions to easily hook (even in parallel) into the NETSYNC processing.
  3. A first cut for an access control policy Lua extension was written which uses a “basic_io” based ACL file for granting read-only or read-write access on certain branches to certain keys (corresponding to the users). The difference to “read-permission” and “write-permission” files is that is especially allows the control of “write” operations to certain branches (and not just in general to all branches).

With this enabled at the master repository site one can leverage from the distributed versioning concept during working, but the master sources still can have an enforced and clean state which one no longer can be easily circumvented by arbitrary propagates/merges with foreign revisions. If the contributors want to still be able to push their revisions up to the master repository, they are forced to make sure that they propagates/merge only with revisions which stay on particular branches theirself and whose author also have acceeded the contributor agreement (how this check can be done is out of the scope of this article, but a database can be queried).


So, in short: distributed version control inherently is in conflict with central access control, but nevertheless it can be combined. For Monotone an experimental implementation proofed to be the start for a promising solution in practice.

Leave a Reply