fold rebel into master :) [please read]
Well, something even more outrageous than deny rules and path-based limits came along, so I decided that "rebel" was actually quite "conformist" in comparision ;-) Jokes apart, the fact is that the access control rules, even when using deny rules and path-limits, are still *auditable*. Which means it is good enough for "corporate use". [The stuff that I'm working on now takes away the auditability aspect -- individual users can "own" repos, create rules for themselves, etc. So let's just say that is the basis of distinguishing "master" now.]
This commit is contained in:
parent
498e62c2f3
commit
d71720d050
26
README.mkd
26
README.mkd
|
@ -3,28 +3,7 @@
|
||||||
> [Update 2009-10-28: apart from all the nifty new features, there's now an
|
> [Update 2009-10-28: apart from all the nifty new features, there's now an
|
||||||
> "easy install" script in the src directory. This script can be used to
|
> "easy install" script in the src directory. This script can be used to
|
||||||
> install as well as upgrade a gitolite install. Please see the INSTALL
|
> install as well as upgrade a gitolite install. Please see the INSTALL
|
||||||
|
> document for details]
|
||||||
> ----
|
|
||||||
|
|
||||||
> ***REBEL FORK WARNING***
|
|
||||||
|
|
||||||
> The paranoid half of Sitaram's brain would like to warn you that the other
|
|
||||||
> half rebelled and created this fork.
|
|
||||||
|
|
||||||
> 1. please read the "design choices" section in the [faqs, tips, etc]
|
|
||||||
> [fted] document for background
|
|
||||||
> 2. please read the comments in the example.conf file carefully before
|
|
||||||
> creating your own config file
|
|
||||||
> 3. please test your configuration carefully
|
|
||||||
> 4. if you still have problems and contact me, please mention right up
|
|
||||||
> front that you're using the ***rebel edition***; makes it easier to
|
|
||||||
> troubleshoot
|
|
||||||
|
|
||||||
[fted]: http://github.com/sitaramc/gitolite/blob/rebel/doc/3-faq-tips-etc.mkd
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
> document in the doc directory for details]
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
|
@ -100,8 +79,7 @@ detail [here][gsdiff].
|
||||||
a synonym for "annotate" :-)]
|
a synonym for "annotate" :-)]
|
||||||
* "personal namespace" prefix for each dev
|
* "personal namespace" prefix for each dev
|
||||||
* migration guide and simple converter for gitosis conf file
|
* migration guide and simple converter for gitosis conf file
|
||||||
* "exclude" (or "deny") rights in the config file -- this is the "rebel"
|
* "exclude" (or "deny") rights at the branch/tag level
|
||||||
branch in the repository, and always will be ;-)
|
|
||||||
|
|
||||||
### security
|
### security
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,10 @@ repo @oss_repos
|
||||||
# ADVANCED PERMISSIONS USING REFEXES
|
# ADVANCED PERMISSIONS USING REFEXES
|
||||||
|
|
||||||
# - refexes are specified in perl regex syntax
|
# - refexes are specified in perl regex syntax
|
||||||
|
# - refexes are matched without any anchoring, which means a refex like
|
||||||
|
# "refs/tags/v[0-9]" matches anything *containing* that pattern. There
|
||||||
|
# may be text before and after it (example: refs/tags/v4-r3p7), and it
|
||||||
|
# will still match
|
||||||
# - if no refex appears, the rule applies to all refs in that repo
|
# - if no refex appears, the rule applies to all refs in that repo
|
||||||
# - a refex is automatically prefixed by "refs/heads/" if it doesn't start
|
# - a refex is automatically prefixed by "refs/heads/" if it doesn't start
|
||||||
# with "refs/" (so tags have to be explicitly named as
|
# with "refs/" (so tags have to be explicitly named as
|
||||||
|
@ -123,9 +127,11 @@ repo git
|
||||||
RW tmp/ = @all
|
RW tmp/ = @all
|
||||||
RW refs/tags/v[0-9] = junio
|
RW refs/tags/v[0-9] = junio
|
||||||
|
|
||||||
# REBEL BRANCH -- DENY/EXCLUDE RULES
|
# DENY/EXCLUDE RULES
|
||||||
|
|
||||||
# please see the "faq, tips, etc" document for details on the "rebel" edition.
|
# ***IMPORTANT NOTE: if you use deny rules, the order of the rules also makes
|
||||||
|
# a difference, where earlier it did not. Please review your ruleset
|
||||||
|
# carefully or test it***. Or ask me.
|
||||||
|
|
||||||
# in the example above, you cannot easily say "anyone can write any tag,
|
# in the example above, you cannot easily say "anyone can write any tag,
|
||||||
# except version tags can only be written by junio". The following might look
|
# except version tags can only be written by junio". The following might look
|
||||||
|
@ -134,7 +140,8 @@ repo git
|
||||||
# RW refs/tags/v[0-9] = junio
|
# RW refs/tags/v[0-9] = junio
|
||||||
# RW refs/tags/ = junio linus pasky @others
|
# RW refs/tags/ = junio linus pasky @others
|
||||||
|
|
||||||
# in the "rebel" branch, however, you can do this:
|
# if you use "deny" rules, however, you can do this (a "deny" rule just uses
|
||||||
|
# "-" instead of "R" or "RW" or "RW+" in the permission field)
|
||||||
|
|
||||||
RW refs/tags/v[0-9] = junio
|
RW refs/tags/v[0-9] = junio
|
||||||
- refs/tags/v[0-9] = linus pasky @others
|
- refs/tags/v[0-9] = linus pasky @others
|
||||||
|
|
|
@ -17,12 +17,10 @@ In this document:
|
||||||
* one user, many keys
|
* one user, many keys
|
||||||
* support for git installed outside default PATH
|
* support for git installed outside default PATH
|
||||||
* what repos do I have access to?
|
* what repos do I have access to?
|
||||||
* other cool things
|
* "exclude" (or "deny") rules
|
||||||
* "personal" branches
|
* "personal" branches
|
||||||
* design choices
|
* design choices
|
||||||
* keeping the parser and the access control separate
|
* keeping the parser and the access control separate
|
||||||
* why we don't do "excludes"
|
|
||||||
* how the rebel edition does it anyway :)
|
|
||||||
|
|
||||||
### common errors and mistakes
|
### common errors and mistakes
|
||||||
|
|
||||||
|
@ -179,8 +177,8 @@ Each refex that allows `W` access (or `+` if this is a rewind) for *this*
|
||||||
user, on *this* repo, is matched against the actual refname being updated. If
|
user, on *this* repo, is matched against the actual refname being updated. If
|
||||||
any of the refexes match, the push succeeds. If none of them match, it fails.
|
any of the refexes match, the push succeeds. If none of them match, it fails.
|
||||||
|
|
||||||
The normal gitolite does not allow "exclude" or "deny" rules. But see the
|
Gitolite also allows "exclude" or "deny" rules. See later in this document
|
||||||
"how the rebel edition does it anyway" below.
|
for details.
|
||||||
|
|
||||||
#### error checking the config file
|
#### error checking the config file
|
||||||
|
|
||||||
|
@ -404,7 +402,54 @@ Note that until this version, we used to put out an ugly `need
|
||||||
SSH_ORIGINAL_COMMAND` error, just like gitosis used to. All we did is put
|
SSH_ORIGINAL_COMMAND` error, just like gitosis used to. All we did is put
|
||||||
that code path to better use :-)
|
that code path to better use :-)
|
||||||
|
|
||||||
### other cool things
|
#### "exclude" (or "deny") rules
|
||||||
|
|
||||||
|
Take a look at the following snippet, which *seems* to say that "bruce" can
|
||||||
|
write versioned tags (anything containing `refs/tags/v[0-9]`), but the other
|
||||||
|
staffers can't:
|
||||||
|
|
||||||
|
@staff = bruce whitfield martin
|
||||||
|
[... and later ...]
|
||||||
|
RW refs/tags/v[0-9] = bruce
|
||||||
|
RW refs/tags = @staff
|
||||||
|
|
||||||
|
But that's not how the matching works. As long as any refex matches the
|
||||||
|
refname being updated, it's a "yes". Since the second refex (which says
|
||||||
|
"anything containing `refs/tags`") is a superset of the first one, it lets
|
||||||
|
anyone on `@staff` create versioned tags, not just Bruce.
|
||||||
|
|
||||||
|
One way to fix this is to allow "excludes" -- some changes in syntax, combined
|
||||||
|
with a rigorous, ordered, interpretation would do it.
|
||||||
|
|
||||||
|
Let's recap the **existing semantics**:
|
||||||
|
|
||||||
|
> the first matching refex that has the permission you're looking for (`W`
|
||||||
|
> or `+`), results in success. A fallthrough results in failure
|
||||||
|
|
||||||
|
Here are the **new semantics**, with changes from the "main" one in bold:
|
||||||
|
|
||||||
|
> the first matching refex that has the permission you're looking for (`W`
|
||||||
|
> or `+`) **or a minus (`-`)**, results in success **or failure,
|
||||||
|
> respectively**. A fallthrough **also** results in failure
|
||||||
|
|
||||||
|
So the example we started with becomes, if you use "deny" rules:
|
||||||
|
|
||||||
|
RW refs/tags/v[0-9] = bruce
|
||||||
|
- refs/tags/v[0-9] = @staff
|
||||||
|
RW refs/tags = @staff
|
||||||
|
|
||||||
|
And here's how it works:
|
||||||
|
|
||||||
|
* for non-version tags, only the 3rd rule matches, so anyone on staff can
|
||||||
|
push them
|
||||||
|
* for version tags by bruce, the first rule matches so he can push them
|
||||||
|
* for version tags by staffers *other than bruce*, the second rule matches
|
||||||
|
before the third one, and it has a `-` as the permission, so the push
|
||||||
|
fails
|
||||||
|
|
||||||
|
***IMPORTANT NOTE: if you use deny rules, the order of the rules also makes a
|
||||||
|
difference, where earlier it did not. Please review your ruleset carefully or
|
||||||
|
test it***. Or ask me.
|
||||||
|
|
||||||
#### "personal" branches
|
#### "personal" branches
|
||||||
|
|
||||||
|
@ -481,102 +526,3 @@ have to be first "compiled", and the access control programs use this
|
||||||
If you choose the "easy install" method, all this is quite transparent to you
|
If you choose the "easy install" method, all this is quite transparent to you
|
||||||
anyway. If you cannot use the easy install and must install manually, I have
|
anyway. If you cannot use the easy install and must install manually, I have
|
||||||
clear instructions on how to set it up.
|
clear instructions on how to set it up.
|
||||||
|
|
||||||
#### why we don't do "excludes"
|
|
||||||
|
|
||||||
[umm... having said all this, I implemented it anyway; see the "rebel"
|
|
||||||
branch!]
|
|
||||||
|
|
||||||
I found an error in the example conf file. This snippet *seems* to say that
|
|
||||||
"bruce" can write versioned tags (`refs/tags/v[0-9].*`), but the other
|
|
||||||
staffers can't:
|
|
||||||
|
|
||||||
@staff = bruce whitfield martin
|
|
||||||
[... and later ...]
|
|
||||||
RW refs/tags/v[0-9].* = bruce
|
|
||||||
RW refs/tags = @staff
|
|
||||||
|
|
||||||
But that's not how the matching works. As long as any refex matches the
|
|
||||||
refname being updated, it's a "yes". So the second refex lets anyone on
|
|
||||||
`@staff` create versioned tags, not just Bruce.
|
|
||||||
|
|
||||||
One way to fix this is to allow "excludes" -- some changes in syntax, combined
|
|
||||||
with a rigorous, ordered, interpretation would do it.
|
|
||||||
|
|
||||||
But if you're ever played with squid ACLs, or the include/exclude rules for
|
|
||||||
rsync, or rdiff-backup, or even git's own ignore mechanism, you'll see why I
|
|
||||||
won't do this. It bloats the code and the docs, and, despite all the docs,
|
|
||||||
*still* confuses people, which may then *reduce* security!
|
|
||||||
|
|
||||||
Squid, rsync, gitignore, and all *need* the feature and so tolerate all this;
|
|
||||||
but we don't need it. All we need to do is make the refexes *disjoint* in
|
|
||||||
what they match (i.e., ensure that no refname can be matched by more than one
|
|
||||||
refex):
|
|
||||||
|
|
||||||
RW refs/tags/v[0-9].* = bruce
|
|
||||||
RW refs/tags/staff/ = @staff
|
|
||||||
|
|
||||||
In general, you probably want to control the refnames writable by devs anyway,
|
|
||||||
if at least to maintain some sanity, so being forced to make the refexes
|
|
||||||
disjoint is not a big problem. Here's an example: only the `project_lead` can
|
|
||||||
make arbitrarily named refs, while the rest have to stay within their assigned
|
|
||||||
namespaces:
|
|
||||||
|
|
||||||
RW+ = project_lead
|
|
||||||
RW refs/tags/qa/ = @qa_team
|
|
||||||
RW bugID/ = @dev_team
|
|
||||||
RW trac/ = @dev_team
|
|
||||||
|
|
||||||
The lack of overlap between refexes ensures ***no confusion*** in specifying,
|
|
||||||
understanding, and ***auditing***, what is allowed and what is not.
|
|
||||||
|
|
||||||
And in security, "no confusion" is a good thing :-)
|
|
||||||
|
|
||||||
#### how the rebel edition does it anyway :)
|
|
||||||
|
|
||||||
Well, reuss on #git asked, I pointed him to the discussion above and said
|
|
||||||
"no", and he was nice enough to agree. But then I started thinking that maybe
|
|
||||||
not everyone needs such "safe" environments. And so, as the README says:
|
|
||||||
|
|
||||||
> The paranoid half of Sitaram's brain would like to warn you that the other
|
|
||||||
> half rebelled and created this fork.
|
|
||||||
|
|
||||||
Let's recap the **existing semantics**:
|
|
||||||
|
|
||||||
> the first matching refex that has the permission you're looking for (`W`
|
|
||||||
> or `+`), results in success. A fallthrough results in failure
|
|
||||||
|
|
||||||
First I changed the format of the compiled config file (an internal file that
|
|
||||||
the user doesn't have to worry about, as long as he remembers to run the
|
|
||||||
compile script on every upgrade). The format change kept the existing syntax
|
|
||||||
and semantics of the config file, but it laid the ground work for allowing
|
|
||||||
"excludes" using **just one extra line of code** (and a very slight change to
|
|
||||||
another)!
|
|
||||||
|
|
||||||
This extremely small delta between the rebel edition and the main one will
|
|
||||||
make it trivial to maintain it as a separate branch, regardless of what other
|
|
||||||
changes happen in the mainline, because I honestly don't see rebel merging
|
|
||||||
into the mainline.
|
|
||||||
|
|
||||||
Yet ;-)
|
|
||||||
|
|
||||||
Here are the **rebel semantics**, with changes from the "main" one in bold:
|
|
||||||
|
|
||||||
> the first matching refex that has the permission you're looking for (`W`
|
|
||||||
> or `+`) **or a minus (`-`)**, results in success **or failure,
|
|
||||||
> respectively**. A fallthrough **also** results in failure
|
|
||||||
|
|
||||||
So the example we started with becomes, in the rebel edition:
|
|
||||||
|
|
||||||
RW refs/tags/v[0-9].* = bruce
|
|
||||||
- refs/tags/v[0-9].* = @staff
|
|
||||||
RW refs/tags = @staff
|
|
||||||
|
|
||||||
And here's how it works:
|
|
||||||
|
|
||||||
* for non-version tags, only the 3rd rule matches, so anyone on staff can
|
|
||||||
push them
|
|
||||||
* for version tags by bruce, the first rule matches so he can push them
|
|
||||||
* for version tags by staffers *other than bruce*, the second rule matches
|
|
||||||
before the third one, and it has a `-` as the permission, so the push
|
|
||||||
fails
|
|
||||||
|
|
Loading…
Reference in a new issue