It’s not so much about overflowing unix user IDs, but more about having fine grained access control and centralized management of permissions that’s convenient. In my experience, Gitolite is a lot more robust and convenient than sort of DIY Unix management utilities for user accounts.
There’s also a lot of philosophical principles tied up in these sorts of ideas, so I’ll try not to sound too weird.
One thing that immediately stands out is: the gitolite approach does not require any level of unix permission on the machine to manage repositories, meaning it can be done completely out of band from system administration of user accounts.
When you install gitolite, you give it the initial “administrator” public key. Then, it creates a “configuration” repository with a default config, lets your key have “admin access”, and lets you clone from it. This means the configuration is directly managed by gitolite itself. Again, this is always under a single actual unix account, something like git
. So you clone:
$ git clone ssh://git@hostname.domain/gitolite-admin.git
$ find gitolite-admin -type f | grep -v \.git
gitolite-admin/conf/gitolite.conf # configuration
gitolite-admin/keydir/austin.pub # my pubkey
Now there are a few things here: one, I’m only allowed to clone it because by default, gitolite’s configuration restricts clones of the configuration to people with ‘administrator’ pubkeys only. (During install, you say “Here is the pubkey for austin
who is the default admin”). Two, the pubkeys are managed as direct files in version control, making them much more easily auditable, etc.
So if I want to add any more administrators, all I need to do is simply add a line giving me read/write capability to gitolite-admin
, and they can manage the configuration and their own keys. Git management is completely locked down to a single user account. As a consequence, all the repositories are under that users $HOME
, owned by the git
gid/uid, which is all that’s needed.
As both the system administrator of the box that hosted GHC repositories (with 30 user accounts and some level of automation), and gitolite, I would take gitolite
every day over managing individual accounts directly with some sort of devops/deployment tool for the vast majority of deployments, and it has made management a lot easier.
In the bkd
documentation, one suggestion is to run multiple copies of bkd
if you want to have anonymous read-only repositories depending on your directory layout. But this is a bit weird especially because if you want to make it ‘easily’ transparent, you need a frontend load balancer. Indeed, for many version control systems, the scheme thing clone thing://host.fqdn/thing/repository
is very familiar, almost muscle memory, so hosting on different ports and multiplexing or something is a bit weird of a hosting requirement if it’s not “almost transparent” by the daemon itself.
Instead, you can just put everything in a single directory, run one instance of ssh
, and the login shell keys access control based on A) the rules matched with B) the incoming SSH key. This doesn’t require any sort of fiddling with the overall init system, either - the rules and matching key alone determine access.
gitolite
also allows a level of access control that I don’t think unix permissions can replicate easily, at least not without a weird amount of integration with the underlying machine (which may not be OK).
So for example, in GHC, we don’t let people delete any branches in a repository, unless they have the prefix wip/
. Anyone can collaborate but you can’t delete it if it doesn’t have that prefix, unless you’re an admin.
OK, so in bk
, what you’d do is create a separate user who could just use their own ‘wip’ fork, right? After all, since bitkeeper uses directories as branches, you can form these as a real hierarchy. Then someone else forks them and the original person pulls back, etc etc.
But a lot of times you may have more than a single person working in one repository, even a fork. How do you manage the permissions then? If both Bob and Alice are working on alice/cool-feature
(they might sit next to each other in the office, so it’s easy enough to just work on the same upstream, and alice is leading), and Greg wants to join, how do you add permission? You’d have to have a group for alice/cool-feature
with all the right users; but it still doesn’t model the right level of granularity: maybe greg
and all his keys should be able to clone (because he’s in QA), but can’t push (bob or alice have to, since they’re developers). But he does need to push to other repositories. So having bkd
outright restrict writes for every one of the keys greg
has is wrong. He needs to read some, and write only to a limited subset of those.
All of this is very easily expressible with gitolite as a series of read/write permissions, and it doesn’t require any integration with the overall Unix system. It’s a simple, declarative ruleset that is fairly easy to understand and audit, and version controlled.
Changing group or unix permissions may be actively more difficult to automate depending on the outside system. Such things would be disallowed in a system like NixOS - in NixOS, you write a configuration file, and ‘compile’ your system to a known state. It’s completely reproducible, deterministic, etc. Including group and user management - that’s all in a text file. Automating BitKeeper permissions on top of the unix model when this is in play is much more difficult; you have to actually commit a text file with new code to build a new group, then run ‘the compiler’ to build everything so the user is part of the new groups, etc.
Basically, at least for git, collapsing actual user management into the repository management tool itself gives you a lot of freedom and simplicity that abstracts you away from the underlying host system. It’s much, much easier to use a declarative ruleset to describe things like “the group foo
is only allowed to write to refs foobar/dev*
, interpreted as a regex” than script the unix permission model for these things. At least IME.
EDIT: This also seems to be made more complicated by the fact Bitkeeper permissions and unix permissions don’t align. In the previous example, Greg needs “unix write” permissions for read locks, as indicated earlier by @wscott. But he does NOT need “bitkeeper cset write” capability, i.e. the ability to push csets. So how do you have one directory, with three people who have unix read and write capabilities (again, for read locks), but different permissions at the BitKeeper level? Greg can only read, not write. Alice/bob can read and write. This rules are also per repository, or per groups of repositories. You can sort of square this circle somehow I’m sure, but it all feels very weird.
EDIT TWO: As an example in comparison, in Gitolite you’d say something vaguely like:
# alice, bob and greg can have multiple keys, in the files
# alice@1.pub, alice@2.pub, etc, alongside this config
# file
@devs = alice bob
@qa = greg
# rules for @devs-repos, which may be a single repository,
# or some grouping of repositories
repo @devs-repos
R = @qa # QA has no write ability
RW = @devs # developers have full capability
... other rules here ...
And that’s it: this use case is completely satisfied.
In fact, gitolite
does not go far enough. IMO. I see no reason why gitolite
has to read its database from a flat file; indeed, it could easily query some “oracle” every time it sees a new git push
, and the oracle (a script) might query MySQL, a REST API, etc to assess authorization - is it the right key, can it push here, etc. Indeed, this is exactly how modern self-management UIs mostly work. The login shell (or ssh itself, using AuthorizedKeysCommand
in OpenSSH 6.2+) is what queries for access to SSH keys and rules about who can do what, from some endpoint.
Why wouldn’t the theoretical bk-olite
allow that? For example, it could read a flat file in the basic mode, but there’s no reason an exec
mode couldn’t run some external program. It expects that program to output some information on stdout
to assess authorization. So someone tries to push, theoretical bitkeeper-olite
invokes /usr/bin/test-bkolite-creds.sh
, which might call a script to query MySQL and return a ruleset. I think this would be pretty nice, actually! Wire that database up to an account UI, and boom - you can do things like self-manage SSH keys!
However, all that said, it might be best if bk
itself doesn’t get into this business. It’s somewhat open ended. Note that this all comes from the role of “I help 30+ developers work on this project, we need management/ACL tools to help them and stop us from shooting ourselves”. At the same time, I also deal with the “we need to merge drive by patches, without too much activation energy” problem. But using a tool like gitolite
in spirit, you could definitely build out the core of more flexible user/role control mechanism, on top of which you could build something like bkbits.net
.
Maybe I should write my own bk-olite
as an exercise! 
Indeed, as above comes from experience managing our own project with 30+ developers and needed rulesets, access controls are really useful. BitKeeper actually does several things right here - like let you check in triggers with the code itself (huuuuugely useful for things like precommit hooks to lint your code).
Anyway, I’ll stop talking now before I go in circles and you stop listening. I hope this isn’t too inane sounding. I’m afraid the rti
is something I’d have to think about more, but I do have opinions “Pull request” stuff, too, so I’ll spare you those.