From fa5567f22cba52ff8d98a0010c508f18bf073c4f Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Sun, 4 Oct 2009 09:25:20 +0530 Subject: [PATCH] doc/5-delegation added, doc/4 (PTA) enhanced This is complete user documentation for delegation --- doc/3-faq-tips-etc.mkd | 8 +++ doc/4-push-to-admin.mkd | 77 +++++++++++++---------- doc/5-delegation.mkd | 135 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 186 insertions(+), 34 deletions(-) create mode 100644 doc/5-delegation.mkd diff --git a/doc/3-faq-tips-etc.mkd b/doc/3-faq-tips-etc.mkd index b28c54823..66ab95631 100644 --- a/doc/3-faq-tips-etc.mkd +++ b/doc/3-faq-tips-etc.mkd @@ -9,6 +9,7 @@ In this document: * simpler syntax * two levels of access rights checking * error checking the config file + * delegating parts of the config file * easier to specify gitweb/daemon access * built-in logging * one user, many keys @@ -179,6 +180,13 @@ In gitolite, you have to "compile" the config file first (this step takes the place of the commit+push in gitosis), and keyword typos *are* caught so you know right away. +#### delegating parts of the config file + +You can now split up the config file and delegate the authority to specify +access control for their own pieces. See +[doc/5-delegation.mkd](http://github.com/sitaramc/gitolite/blob/pu/doc/5-delegation.mkd) +for details. + #### easier to specify gitweb/daemon access Specifying gitweb and/or daemon access for a repo is simple: give "read" diff --git a/doc/4-push-to-admin.mkd b/doc/4-push-to-admin.mkd index 4b208a9dd..48d1baad2 100644 --- a/doc/4-push-to-admin.mkd +++ b/doc/4-push-to-admin.mkd @@ -41,51 +41,60 @@ make the same changes below. ---- -First, on the server, log on to the `git` userid, add a new repo called -`gitolite-admin` to the config file, give yourself `RW` or `RW+` rights to it, -and "compile": +#### server side setup - cd ~/.gitolite - vim conf/gitolite.conf # add gitolite-admin repo, etc - src/gl-compile-conf +1. First, on the server, log on to the `git` userid, add a new repo called + `gitolite-admin` to the config file, give yourself `RW` or `RW+` rights to it, + and "compile": -Now, if you look at the "compile" script, it has an *automatic* local commit -inside, just for safety, which kicks in every time you compile. This only -works if it finds a ".git" directory, and it was designed as an "automatic -backup/safety net" type of thing, in case I accidentally deleted the whole -config file or something. + cd ~/.gitolite + vim conf/gitolite.conf # add gitolite-admin repo, etc + src/gl-compile-conf -We need to disable this, because now we have a *better* repo, one that is -manually pushed, and presumably has proper commit messages! +2. Now, if you look at the "compile" script, it has an *automatic* local commit + inside, just for safety, which kicks in every time you compile. This only + works if it finds a ".git" directory, and it was designed as an "automatic + backup/safety net" type of thing, in case I accidentally deleted the whole + config file or something. - mv .git .disable.git # yeah it's a hack, sue me + We need to disable this, because now we have a *better* repo, one that is + manually pushed, and presumably has proper commit messages! -Now the compile command created an empty, bare, "gitolite-admin" repo, so we -seed it with the current contents of the config and keys. (A note on the -`GIT_WORK_TREE` variable: I avoid setting these variables in the normal way -because I always forget to unset them later, and then when I `cd` to other -repos they play havoc with my git commands, so this is how I do it) + mv .git .disable.git # yeah it's a hack, sue me - cd ~/repositories/gitolite-admin.git - GIT_WORK_TREE=/home/git/.gitolite git add conf/gitolite.conf keydir - GIT_WORK_TREE=/home/git/.gitolite git commit -am start +3. Now the compile command created an empty, bare, "gitolite-admin" repo, so we + seed it with the current contents of the config and keys. (A note on the + `GIT_WORK_TREE` variable: I avoid setting these variables in the normal way + because I always forget to unset them later, and then when I `cd` to other + repos they play havoc with my git commands, so this is how I do it) -Now we have to setup the post-update hook for push-to-admin to work. The hook -should (1) make a forced checkout in the "live" config directory (which is -`~/.gitolite`), and (2) run the compile script. + cd ~/repositories/gitolite-admin.git + GIT_WORK_TREE=/home/git/.gitolite git add conf/gitolite.conf keydir + GIT_WORK_TREE=/home/git/.gitolite git commit -am start -`src/pta-hook.sh` has the code you need; just copy it to the right place with -the right name and make sure it is executable: +4. Now we have to setup the post-update hook for push-to-admin to work. The hook + should (1) make a forced checkout in the "live" config directory (which is + `~/.gitolite`), and (2) run the compile script. - # (assuming pwd is still ~/repositories/gitolite-admin.git) - cp ~/.gitolite/src/pta-hook.sh hooks/post-update - chmod +x hooks/post-update + `src/pta-hook.sh` has the code you need; just copy it to the right place with + the right name, change the first line if needed, and make it executable: + + # (assuming pwd is still ~/repositories/gitolite-admin.git) + cp ~/.gitolite/src/pta-hook.sh hooks/post-update + + # if you changed $GL_ADMINDIR in ~/.gitolite.conf, then edit the hooks + # and change the first line: + vim hooks/post-update + + chmod +x hooks/post-update ---- -Now get to your workstation, and +#### client side setup + +1. Now get to your workstation, and - git clone git@server:gitolite-admin.git + git clone git@server:gitolite-admin.git -That's it, we're done. You're in gitosis land as far as this is concerned -now. So knock yourself out. Or lock yourself out... :-) + That's it, we're done. You're in gitosis land as far as this is concerned + now. So knock yourself out. Or lock yourself out... :-) diff --git a/doc/5-delegation.mkd b/doc/5-delegation.mkd new file mode 100644 index 000000000..7592e835e --- /dev/null +++ b/doc/5-delegation.mkd @@ -0,0 +1,135 @@ +# delegating access control responsibilities + +[Thanks to jeromeag for forcing me to think through this...] + +### lots of repos, lots of users + +Gitolite tries to make it easy to manage access to lots of users and repos, +exploiting commonalities wherever possible. (The example under "simpler, more +powerful syntax" [here][ml] should give you an idea). As you can see, it lets +you specify bits and pieces of the access control separately -- i.e., *all* +the access specs for a certain repo need not be together; they can be +scattered, which makes it easier to manage the sort of slice and dice needed +in that example. + +[ml]: http://github.com/sitaramc/gitolite/blob/ml/update.mkd + +But eventually the config file will become too big. If you let only one +person have control, he could become a bottleneck. If you give it to multiple +people, they might make mistakes or stomp on each others' work accidentally. + +The best way is to divide up the config file and give parts of it to different +people. Ideally, we would delegate authority for *groups* of repos, not +individual repos, otherwise it doesn't scale. + +It would also be nice if we could specify what repos can be delegated to a +particular admin, and prevent him/her from specifying access control for any +other repos. This would be a nice "security" feature. + +### splitting up the config file into fragments + +To start with, recall that gitolite allows you to specify **groups** (of users +or repos, same syntax). So the basic idea is that the main config file +(`~/.gitolite/conf/gitolite.conf` by default) will specify some repo groups: + + # group your projects/repos however you want + @webbrowser_repos = firefox lynx + @webserver_repos = apache nginx + @malware_repos = conficker storm + + # any other config as usual, including access control lines for any of the + # above projects or groups + +Now just create these files (assuming default `$GL_ADMINDIR` location): + + ~/.gitolite/conf/fragments/webbrowser_repos.conf + ~/.gitolite/conf/fragments/webserver_repos.conf + ~/.gitolite/conf/fragments/malware_repos.conf + +Within each of those files put in whatever access control rules you want for +the repos that are members of that group. Notice that the basenames of the +files must be exactly the same as the name of the corresponding repo group in +the main config file. + +For instance, `~/.gitolite/conf/fragments/webbrowser_repos.conf` would only +contain access control for firefox and lynx. If it referenced any other repo +(say "storm") those lines would be ignored (and a warning message generated). + +When you run the compile script (`src/gl-compile-conf`), the **net effect is +as if you appended the contents of all the "fragment" files, in alphabetical +order, to the bottom of the main file**. + +(Except of course, while processing a fragment, it will ignore attempts to set +permissions for repos that are not members of the same-named "repo group"). + +And that's basically it, in the simplest usage. + +["But WAIT, there's MORE!"][bwtm] + +[bwtm]: http://en.wikipedia.org/wiki/Ed_Valenti#But_Wait.21_There.27s_More + +### delegating ownership of fragments + +Splitting up the file does help, but there's also that little security issue +-- anyone can make any change to any "fragment", unless you (once again) go +back to Unix permissions to keep them separate. + +Fixing that requires using "push-to-admin". + +The page on [push-to-admin][ptd] explains clearly how to set it up. Unlike +gitosis, I refuse to make it the default because it's a support nightmare. +Don't get me wrong -- it's a great feature, and I use it myself, but the +learning curve is too steep to make it *required*. + +[ptd]: http://github.com/sitaramc/gitolite/blob/pu/doc/4-push-to-admin.mkd + +So, having setup push-to-admin, you add these lines to the main config file, +assuming Alice is in charge of all web browser development projects, Bob takes +care of web servers, and Mallory, as [tradition][abe] dictates, is in charge +of malware ;-) + +[abe]: http://en.wikipedia.org/wiki/Alice_and_Bob#List_of_characters + + # you probably added these two lines while setting up push-to-admin + repo gitolite-admin + RW+ = sitaram + # now add these 3 lines + RW webbrowser_repos = alice + RW webserver_repos = bob + RW malware_repos = mallory + +As you can see, for each repo group you want to delegate authority over, +there's a **branch** in the `gitolite-admin` repo with the same name. Whoever +has write access to that branch, is allowed to define rules for repos in the +corresponding "repo group". + +In other words, **we use gitolite's per-branch permissions to "enforce" the +separation between the delegated configs!** + +Here's how to use this in practice: + + * Alice clones the `gitolite-admin` repo, creates (if not already created) and + checks out a new branch called `webbrowser_repos`, and adds a file called + `conf/fragments/webbrowser_repos.conf` in that branch + + * (the rest of the contents of that branch do not matter; she can keep + all the other files or delete all of them -- it doesn't make any + difference. Only that one specific file is used). + + * she writes in this file any access control rules for the "firefox" and + "lynx" repos. She should not write access rules for any other project -- + they will be ignored + + * Alice then commits and pushes this branch to the `gitolite-admin` repo + +Naturally, a successful push invokes the post-update hook that you installed +(while setting up [push-to-admin][ptd]). Here's what it does: + + * for each branch, say `br`, of the `gitolite-admin` repo, it checks if + there is a file called `conf/fragments/br.conf` + + * if there is, it extracts it and copies it with the exact same name and + path, into the `$GL_ADMINDIR` directory (`~/.gitolite` by default) + +After that, it runs the compile script, and things work the same as described +in the previous section.