gitolite/doc/rules.mkd

4.9 KiB

#rules access rules

This is arguably the most complex part of day-to-day gitolite. There are several interconnected ideas that make this hard to lay out easily if you're totally new to this, so read carefully.

We will use this as a running example:

@staff          =   dilbert alice wally bob

repo foo
    RW+         =   dilbert     # line 1
    RW+ dev     =   alice       # line 2
    -           =   wally       # line 3
    RW  temp/   =   @staff      # line 4
    R           =   ashok       # line 5

what does a rule look like?

A rule line has the structure

<permission> <zero or more refexes> = <one or more users/user groups>

The most common permissions used are:

  • R, for read only
  • RW, for push existing ref or create new ref
  • RW+, for "push -f" or ref deletion allowed (i.e., destroy information)
  • - (the minus sign), to deny access.

There are also other, less commonly used, [types of permissions][write-types].

A refex is an expression that matches the ref (i.e., branch or tag) being pushed. See [this][refex] for more info.

when are the rules checked?

There are 2 places where access rules are checked.

The "pre-git" check is before git is invoked. Gitolite knows the repo name, user name, and attempted access (R or W), but no ref name.

The "update" check is only for write operations, and it is just before git updates a ref. This time gitolite knows the refname also.

how are the rules matched?

For the pre-git check, any permission that contains "R" matches a read operation, and any permission that contains "W" matches a write operation. This is because we simply don't know enough to make finer distinctions at this point.

In addition, gitolite ignores deny rules during the pre-git check. (You can [change this][deny-rules] if you wish, though it's rarely needed). This means line 3 is ignored, and so Wally in our example will pass the pre-git check.

For the update check, git gives us all the information we need. Then:

  • All the rules for a repo are [accumulated][rule-accum].

  • The rules pertaining to this repo and this user (or to a group to which they belong, respectively) are kept; the rest are ignored.

  • These rules are examined in the sequence they appeared in the conf file. For each rule:

    • If the ref does not match the [refex][], the rule is skipped.
    • If it's a deny rule (the permissions field is a -), access is rejected and the matching stops.
    • If the permission field matches the specific [type of write][write-types] operation, access is allowed and the matching stops.
  • If no rule ends with a decision, ("fallthru"), access is rejected.

Now you need to understand how [refex][] matching happens and how the permissions match the various [types of write operations][write-types].

Using these, you can see, in our example, that:

  • Everyone, even wally, can read the repo.
  • Dilbert can push, rewind, or delete any ref.
  • Alice can push, rewind, or delete any ref whose name starts with 'dev'; see [refex][] for details.
  • Alice can also push (but not rewind or delete) any ref whose name starts with 'temp/'. This applies to bob also.
  • If it weren't for line 3, the previous statement would apply to wally also.

Interestingly, wally can get past the pre-git check because gitolite ignores deny rules for pre-git, but having got past it, he can't actually do anything. That's by design, and as I said if you don't like it you can ask gitolite to [deny at pre-git][deny-rules].

#permsum summary of permissions

The full set of permissions, in regex syntax: -|R|RW+?C?D?M?. This expands to one of -, R, RW, RW+, RWC, RW+C, RWD, RW+D, RWCD, or RW+CD, all but the first two optionally followed by an M. And by now you know what they all mean.

additional topics

#rule-accum rule accumulation

Gitolite was meant to collect rules from multiple places and apply them all. For example, this:

repo foo
    RW  =   u1

@gr1 = foo bar

repo @gr1
    RW  =   u2
    R   =   u3

repo @all
    R   =   gitweb

is effectively the same as this, for repo foo:

repo foo
    RW  =   u1
    RW  =   u2
    R   =   u3
    R   =   gitweb

This extends to patterns also, but I'll leave an example for later.

#deny-rules applying deny rules during the pre-git check

The access rules section above describes the problem in one scenario. Here's another. Let's say you have this at the end of your gitolite.conf file:

repo @all
    R   =   gitweb daemon

but you don't want the gitolite-admin repo showing up on gitweb. How do you do that? Here's how:

repo gitolite-admin
    -   =   gitweb daemon
    option deny-rules = 1

repo @all
    R   =   gitweb daemon

Note that the order matters; the - rule must come before the R rule.