I'm currently investigating whether it is possible to serve bzr in a setup similar to what gitolite does for git. This means a single unix account, with different users managed via their ssh public keys. I'd be happy to integrate this with gitolite, in which case the user management and creation of a suitable ~/.ssh/authorized_keys could be delegated. That would take care of authentication.

What has me worried is authorization. As far as I see it, bzr serve out of the box has only the --directory flag to provide access control. That works well with providing every user his or her own set of repositories, or for assigning users to groups and giving each group a single fixed set of repositories. With a bit more work, one can use one directory per user but use symlinks to allow shared access to repositories for multiple users.

Nevertheless, this is still far less than what gitolite can do. Using this approach, it is not possible to grant individual users read-only access to some but read-write access to other repositories. Neither is it possible to prevent overwriting pushes, or creation of new repositories in the user's directories.

It might be that these features haven't been implemented yet. In a related Stack Overflow question I'm asking about ways to implement this myself. Here on Server Fault I'm concentrating on existing solutions. Are there any ready-to-use solutions which endow bzr serve with more fine-grained access control than a simple --directory restriction? A completely integrated solution like gitolite would be most interesting, but even some extension which might be configured to address one of the issues I mentioned would be nice to know.


Solution 1:

If you're not hard-set on just one user, you might consider the following setup:

  • Each user has their own UID.
  • umask for all bzr users is 002.
  • Each repository has an owner UID and a unique write-permissions group.
  • Each repository has a directory based within the owner UID's tree.
  • Each repository directory is sgid (chmod g+s <repo>).
  • Each repository directory has the default fileacl owner rwX (setfacl -R -m d:u:UID:rwX <repo>; setfacl -R -m u:UID:rwX <repo>). This ensures the owner can always delete.
  • Each directory has mode 775 and each file 664.
  • When sharing a repository, it is symlinked into the UID directory like you mentioned using the directory restriction.
  • When granting write access to a repository, the user is added to the write-permissions group associated with that repository.

Thus you can control read access by "symlink exists" and write access by "user in group". If you wanted to implement multiple master-users for a repository, you could add an additional d:u:UID:rwX,u:UID:rwX, one for each additional master.