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://email@example.com/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.
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
# firstname.lastname@example.org, email@example.com, etc, alongside this config
@devs = alice bob
@qa = greg
# rules for @devs-repos, which may be a single repository,
# or some grouping of repositories
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.
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
/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
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.