gitolite access control
Gitolite is a missing puzzle with git toolset. It was a great discovery because until I found it I had hard time to sort out access privileges to git repositories. It is simple solution with aesthetic interface and privileges. Also well tested in practice because is used by kernel.org. But devil is in the detail. Once a list of my repositories grow, access privileges complicate. And I have recently wasted well over an hour of my time which I had to spend figuring out how its access control system really works.
Permissions
In its principles it is enough to work with just a couple of basic permissions like R (read), RW (R + create/fastforward/push a ref) and RW+ (RW + rewind/delete a ref). The - (minus sign) removes an access.
There are some other other permissions like D/C/M which I was not interested in yet.
Gitolite Access Check Flow
The config file is parsed from top to bottom. But there is one more thing - there are two different flows: Flow #1 for read only operations (R - fetch, clone), and flow #2 for changes (RW+). Normally the read access does not respect deny rules. There is an option to change that but by default read only access discards all
- (deny) rules. Here is an example how it works.
1
2
3
4
5
repo testing
RW+ = jxa
- master = aga
RW+ dev/ = aga
RW = aga
In the example above user jxa
has all access to all branches, including
delete/rewind. User aga
has all possible privileges to do anything with
branches starting with dev/
, for branches not starting with dev/
, aga
may
create and fast forward, but not rewind nor delete. For the master
read
access (clone, pull) shall be granted (because of flow #1), but all other
privileges revoked.
However it did not work with my testing procedures. See below how I test it.
Testing
I found it comfortable to test directly at the server. Gitolite documentation
mentions gitolite access
command. Here is its syntax:
Instead of changing the gitolite.conf
at remote git repository,
commiting and pushing it to the git server - I choose to edit the file
at the server, usually it is $HOME/.gitolite/conf/gitolite.conf
.
It needs to be compiled after any change by gitolite compile
.
Unexpected Results
So I had to spend more time to figure out why it works differently than
what was described above and is written in the documentation. Below we follow
a scenario where user aga
requests fetch/clone access to master
branch.
According to our rules, aga
should be granted fetch/clone to master
,
because flow #1 ignores deny rules and grants access
in line number 5. So gitolite does not behave as described.
Let’s check another scenario, instead of naming a particular branch
we may use word any
to test an access to unspecified brach.
This time access
tool explicitely skips the deny rule of line 3 and
grants access based on the line 4, because as I presume, any
means
any branch, dev
including. This kind of testing with any
does not
look useful at first glance. But it is actually useful, just follow my
path and look what I have found:
Why did they hide it here? Indeed it matches flow #1 definition - it is supposed to ignore all deny rules and all refexes.
Wrap Up
So actually the gitolite access
utility works as designed but we have to
test it twice: once for write access, and another one for read access
using any
as the branch name.
Another motion - the documentation is usually poor, check the source code by yourself.