bzr serve and access control?

Andrew Bennetts andrew.bennetts at canonical.com
Fri Feb 5 00:14:02 GMT 2010


First, thanks very much for taking the time to make your requirements so clear.

Josef Wolf wrote:
> On Thu, Feb 04, 2010 at 12:38:32PM +1100, Andrew Bennetts wrote:
> 
> > If I were to implement this, it would look like this:
> > 
> >   * set command="bzr acl-serve /path/to/acl-config" in your authorized_keys,
> >   * have that config file define read/write permissions for various combinations
> >     of paths and users,
> >   * and write (and install system-wide) a plugin that implements 'bzr acl-serve'.
> > 
> > The plugin would:
> > 
> >   * register the 'acl-serve' command, which would:
> >     * parse the config file determine the SSH user,
> >     * using that info register an 'aclbzr' server in
> >       bzrlib.transport.transport_server_registry, then
> >     * run 'bzr serve --inet --protocol=aclbzr --directory=something'
> 
> So again, the directory is pretty much hardwired for a given user. Again,
> flexibility is very limited here. For example, you can not specify multiple
> directory hierarchies for a given user while excluding sub hierarchies.

Sorry, I was unclear.  The --directory argument there is actually unimportant, I
should have said “ignored” rather than “something”.  The custom transport
configured by the previous step makes it redundant; the logic that would pay
attention to it has been overridden by the 'aclbzr' registration.  (This is
another reason why not having an explicit sshserve command is unclear.)

> For example, to serve my git repositories, I have configured a hierarchy
> like this:
> 
>  # note: C==create, R==read, W==write, D==delete
>  #
>  /srv/repos/public/everybody  everybody can CRW here
>  /srv/repos/public/<user>     user <user> can CRWD, everybody can R
>  /srv/repos/private/<user>    user <user> can CRWD
>  /srv/repos/some_repo         Some users can R, some can W, some can CD
>  /srv/repos/other_repo        Some users can R, some can W, some can CD
>  /srv/repos/one_more_repo     Some users can R, some can W, some can CD
>  /srv/repos/repo              Some users can R, some can W, some can CD
>  /srv/repos/repo/hierarchy    Some users can R, some can W, some can CD

Right.  This sort of thing is exactly what my proposal is intended to support.

[...]
> Well, it sounds pretty complicated to me. And you have to touch bzr internals,
> so really good knowledge about bazaar internals are needed to implement this
> properly. And it is not backwards compatible.

It is a bit complicated, I agree, but it would only have to be written once, and
then there'd be standard plugin that people could either a) configure and use,
or b) hack and adapt for really esoteric needs.  In terms of lines of code, I
think you'd find it's about half glue and about half the actual core.  I'd to
love write it myself to save someone else the trouble, but currently I have more
urgent priorities.

This is also totally backwards compatible.  I offer as proof Launchpad: regular,
unmodified bzr clients, with no plugins enabled, will happily interact with
Launchpad's code hosting, which not only implements access controls like the
above, but also enforces rules like “second directory element must be a project
name in Launchpad” and mapping the public directory names to internal names
based on database ID so that renaming branches doesn't affect the referential
integrity of Launchpad's database.  It's a shame that Launchpad's code for this
isn't more readily adaptable for other uses, but that's just the way it's worked
out.

> Look, I have implemented the thing described above for git in less than 50
> (trivial) lines of perl. Without knowing about git internals and without
> touching git at all. Just a matter of getting directory and access method
> from the command line and act according the config file. Not a big deal.
> Took me less than two hours and I can be 100% sure I have not broken anything
> in git. And since the code is trivial, it is easy to check for correctness.

There's a fundamental difference in the way that bzr operates that prevents
this, namely the way we deal with branches and repositories over an arbitrary
number of directory levels, whereas git you can point at single filesystem
location and know that all the heads and revision data can be found inside it.
For this task, it places bzr at a disadvantage, but one that can be readily
fixed by writing a server-side plugin to configure bzr accordingly.

(On the other hand, bzr's layout also means that you can apply regular
filesystem ACLs to individual branches, so it's not all disadvantage.)

> Implementing your proposal would take me at least a month and would
> have a big risk to break something. And it would still not give me the
> flexibility that I already have with the damn 50 lines of trivial perl for
> git.

Fair enough, I appreciate it's not worth the effort for you (although I disagree
about the degree of flexibility you'd get).  Thanks for taking the time to give
me feedback anyway!

If anyone else is interested in working on this, the offer still stands: I'd
love to help you with guidance, code reviews, and probably even some code.

-Andrew.




More information about the bazaar mailing list