(minor) sts app 4 add another common scenario
[gitolite-doc.git] / how.mkd
blob320d24bdf04c59632fe69de6000ffc9ace054b6b
1 <!-- to: slidy-2 -->
3 % authentication and authorization in gitolite
5 # (viewing this slideshow)
7 This presentation uses [HTML
8 Slidy](http://www.w3.org/Talks/Tools/Slidy2/Overview.html), a simple
9 presentation software from the W3C. Although there's a help button in the
10 footer of each presentation, it's missing some important stuff, so here's a
11 smaller but more complete summary of the keyboard controls.
13 .#d
15 @@blue(**Navigation**)@@
17 |   **Next slide**: right arrow, page down, space
18 |   **Prev slide**: left arrow, page up
20 |   **Down within slide**: down arrow
21 |   **Up within slide**: up arrow
23 |   **First slide**: home
24 |   **Last slide**: end
26 .#d
28 @@blue(**Display**)@@
30 |   **Smaller font**: "S" or "<" key
31 |   **Larger font**: "B" or ">" key
33 |   **Toggle Current versus *All* slides**: "A" key
34 |   **Toggle Table of Contents popup**: "C" key
35 |   **Toggle footer**: "F" key
37 .#t
39 @@blue(**To search**)@@ for stuff in the full document using your browser's
40 Ctrl-F, first view all slides (press the "A" key).
42 <!-- end slidy help -->
44 # authentication versus authorisation
46 Before we start, we need to be clear about the difference between
47 *authentication* and *authorisation*.
49 .#d width=50% bgcolor=FFF0F0
51 **Authentication**
53 *   checks user's identity ("who are you?")
54 *   is **NOT** done by gitolite!
55     *   although gitolite does help to set it up if you're using ssh
56 *   is done by ssh server (or perhaps by http server if you are running
57     gitolite in http mode)
59 .#d bgcolor=#F0F0FF
61 **Authorisation**
63 *   check's user's access ("now I know who you are, are you allowed to do what
64     you want to do?")
65 *   **This** is what gitolite does
67 .#t
69 # git over plain ssh
71 First, we'll recap how git works over plain ssh.
73 ![](f0.png)
75 .aa f0.png
77 User Workstation            |                                       Git Server
78                             |
79 ----------------------------+-------------------------------------------------
80                             |
81                             |
82       git clone ---> ssh ---+---> sshd ------> git‐upload‐pack
83                             |
84       git fetch ---> ssh ---+---> sshd ------> git‐upload‐pack
85                             |
86                             |
87       git push  ---> ssh ---+---> sshd ------> git‐receive‐pack
88                             |
89                             |
91 .end
93 The client user *authenticates* herself to the server using any method
94 supported by ssh -- password or ssh public key. It does not matter to either
95 the git client or the git server how that happens; that's entirely between ssh
96 and sshd (the ssh daemon or server).
98 There is no *authorisation* in this mode, other than any file system
99 permissions that the OS may enforce.
101 # how does gitolite work?
103 Gitolite adds an extra layer in between the sshd and the git-receive-pack (or
104 git-upload-pack, for read operations), to check if the access is allowed and
105 abort if needed.  Gitolite also installs its own update hook (see `man
106 githooks`) in every repository to check branches being pushed.
108 This means gitolite does **two** authorisation checks, as you will see.
110 Gitolite also requires that the authentication **must** happen using an ssh
111 public key.  We'll see why as we go along.
113 Here's a series of pictures that show how gitolite works. We're using a "git
114 push" example; the only difference for a fetch or clone is that instead of
115 `git-receive-pack` it'd call `git-upload-pack`, and the last check (update
116 hook) does not apply.
118 @@blue(**Terminology reminder**: "ref" in git parlance means "branch or tag".
119 At least in this page that's what we mean :-))@@
121 ----
123 ## the diagrams...
125 The diagrams were originally drawn to be self-contained.  On a first pass you
126 can simply ignore the text on each page, and come back to it later for the
127 finer points.
129 Experts: yes, I know I simplified the ssh part a lot.  If you can find fault
130 with these pictures, you're not the target audience :-)
132 ----
134 .aa f1.png
136 User Workstation            |                                  Gitolite Server
137                             |
138 ----------------------------+-------------------------------------------------
139                             |
140                             |
141                             |
142                             |
143                             |
144                             |
145                             |
146     Git client              |
147         |                   |
148         |                   |
149         |                   |
150         | calls             |
151         | ssh               |
152         |                   |
153         |                   |
154         |                   |
155         v                   |
156     ssh client              |
157                             |
158                             |
159                             |
160                             |
161                             |
162                             |
163                             |
165 .end
167 ![](f1.png)
169 When the user runs a "git push" command, the git client calls ssh, passing it
170 a command like
172     git-receive-pack 'reponame'
174 ----
176 .aa f2.png
178 User Workstation            |                                  Gitolite Server
179                             |
180 ----------------------------+-------------------------------------------------
181                             |
182                             |
183                             |
184                             |
185                             |
186                             |
187                             |
188     Git client              |
189         |                   |
190         |                   |
191         |                   |
192         |                   |
193         |                   |
194         |                   |
195         |                   |
196         |                   |
197         v                   |
198     ssh client              |
199                             |
200         | reads             |
201         | ssh keypair       |
202         |                   |
203         v                   |
204    ~/.ssh/id_rsa            |
205  ~/.ssh/id_rsa.pub          |
207 .end
209 ![](f2.png)
211 The git client, before it starts talking to the server, looks for the user's
212 ssh keys so it can use public key authentication (and not ask for a password).
214 As you know, for gitolite to work, the user must already have an ssh key pair
215 and the pub key already sent to the gitolite administrator who should have
216 added it to gitolite (which in turn means it's part of
217 `~/.ssh/authorized_keys` on the server).
219 ----
221 .aa f3.png
223 User Workstation            |                                  Gitolite Server
224                             |
225 ----------------------------+-------------------------------------------------
226                             |
227                             |
228                             |
229                             |
230                             |
231                             |
232                             |
233     Git client              |
234         |                   |
235         |                   |
236         |                   |
237         |                   |
238         |                   |
239         |                   |
240         |                   |
241         |         calls     |
242         v         server    |
243     ssh client -------------+--------> ssh server
244                   sends     |
245         |         pubkey    |
246         |                   |
247         |                   |
248         v                   |
249    ~/.ssh/id_rsa            |
250  ~/.ssh/id_rsa.pub          |
252 .end
254 ![](f3.png)
256 The ssh client sends the public key to the server to identify itself.
258 ----
260 .aa f4.png
262 User Workstation            |                                  Gitolite Server
263                             |
264 ----------------------------+-------------------------------------------------
265                             |
266                             |
267                             |
268                             |
269                             |
270                             |
271                             |
272     Git client              |
273         |                   |
274         |                   |
275         |                   |
276         |                   |
277         |                   |
278         |                   |
279         |                   |
280         |                   |
281         v                   |
282     ssh client -------------+--------> ssh server
283                             |
284         |                   |               | matches pubkey in
285         |                   |               | authorized keys file
286         |                   |               |
287         v                   |               v
288    ~/.ssh/id_rsa            |     ~/.ssh/authorized_keys
289  ~/.ssh/id_rsa.pub          |
291 .end
293 ![](f4.png)
295 The server looks for the public key in its "list of people who're allowed in"
296 (`~/.ssh/authorized_keys`).  If it finds it, things are good.
298 @@red(If it doesn't find it, it tells the client and the client asks the user
299 for a password.  Which is BAD, because Gitolite doesn't work with
300 passwords!)@@
302 ----
304 .aa f5.png
306 User Workstation            |                                  Gitolite Server
307                             |
308 ----------------------------+-------------------------------------------------
309                             |
310                             |
311                             |
312                             |
313                             |
314                             |
315                             |
316     Git client              |
317         |                   |
318         |                   |
319         |                   |
320         |                   |
321         |                   |        gitolite‐shell
322         |                   |               ^
323         |                   |               | (if found) calls gitolite with
324         |                   |               | username found in authkeys file
325         v                   |               |
326     ssh client -------------+--------> ssh server
327                             |
328         |                   |               |
329         |                   |               |
330         |                   |               |
331         v                   |               v
332    ~/.ssh/id_rsa            |     ~/.ssh/authorized_keys
333  ~/.ssh/id_rsa.pub          |
335 .end
337 ![](f5.png)
339 If authentication succeeds, the ssh server calls gitolite-shell, with the
340 username as the first argument. Here's how that happens.
342 When the administrator adds Alice's pubkey to gitolite, he names it
343 "alice.pub", puts it in the "keydir" directory of a clone of the
344 gitolite-admin repository, and pushes the new file to the server.
346 When the Gitolite server receives that push, one of the things it does is add
347 this key to `~/.ssh/authorized_keys` file, but prefixed with a bunch of
348 options, one of which is a "command" option that looks like this:
350     command="/home/git/bin/gitolite-shell alice"
352 It is this "command" that the ssh daemon executes when the offered public key
353 matches the public key in this line.  For a different public key, from a
354 different user, the command will have *that* user's name instead of "alice".
356 This is how Gitolite distinguishes users from each other, even though they're
357 all accessing the same (`git@host`) account.
359 This is also why passwords won't work.  When a user supplies a password,
360 there's no additional information to help the ssh server distinguish one user
361 from another.
363 ----
365 .aa f6.png
367 User Workstation            |                                  Gitolite Server
368                             |
369 ----------------------------+-------------------------------------------------
370                             |
371                             |
372                             |
373                             |
374                             |
375                             |
376                             |
377     Git client              |       git‐receive‐pack
378         |                   |               ^
379         |                   |               | calls git if
380         |                   |               | access allowed
381         |                   |               |
382         |                   |        gitolite‐shell
383         |                   |               ^
384         |                   |               |
385         |                   |               |
386         v                   |               |
387     ssh client -------------+--------> ssh server
388                             |
389         |                   |               |
390         |                   |               |
391         |                   |               |
392         v                   |               v
393    ~/.ssh/id_rsa            |     ~/.ssh/authorized_keys
394  ~/.ssh/id_rsa.pub          |
396 .end
398 ![](f6.png)
400 When the ssh daemon decided to execute `/home/git/bin/gitolite-shell alice`
401 instead of the `git-receive-pack 'reponame'` command that the user's git
402 client sent to the user's ssh client, it didn't simply discard the
403 git-receive-pack command.  It put it in an environment variable called
404 `SSH_ORIGINAL_COMMAND`.
406 Since that variable contains the repository name, and the username is the
407 first argument passed to it, gitolite-shell now has enough information to
408 decide "is this user allowed to write to this repo" (or "read", if the command
409 was git-upload-pack).
411 Assuming access is allowed, gitolite-shell then calls git-receive-pack (or
412 git-upload-pack, as the case may be).
414 This is the **first authorisation check** that gitolite does.
416 Notice that git-receive-pack and git-upload-pack have NO idea that someone
417 snuck in between them and the client calling them.  Neither does the git
418 client know.  Gitolite is **totally** transparent to git clients unless access
419 is denied for some reason.
421 ----
423 .aa f7.png
425 User Workstation            |                                  Gitolite Server
426                             |
427 ----------------------------+-------------------------------------------------
428                             |
429                             |
430                             |   gitolite-installed update hook
431                             |               ^
432                             |               : each ref pushed is checked
433                             |               | by the update hook
434                             |               |
435     Git client              |       git‐receive‐pack
436         |                   |               ^
437         |                   |               |
438         |                   |               |
439         |                   |               |
440         |                   |        gitolite‐shell
441         |                   |               ^
442         |                   |               |
443         |                   |               |
444         v                   |               |
445     ssh client -------------+--------> ssh server
446                             |
447         |                   |               |
448         |                   |               |
449         |                   |               |
450         v                   |               v
451    ~/.ssh/id_rsa            |     ~/.ssh/authorized_keys
452  ~/.ssh/id_rsa.pub          |
454 .end
456 ![](f7.png)
458 For a read (git-upload-pack), that is the end of the story.
460 For a write, git will invoke the update hook for each branch or tag pushed.
461 (See `man githooks` for details).
463 This update hook, of course, has been installed by gitolite, and it proceeds
464 to check if
466 |   -   this user (alice, bob, ...)
467 |   -   is allowed to do this (create, fast-forward push, non-fast-forward push, or delete)
468 |   -   to this branch or tag (master, refs/tags/v1.0, ...)
469 |   -   in this repo.
471 This is the **second authorisation check** that gitolite does.
473 If it is not allowed, the update hooks exits with an error, and git will abort
474 the push (for that ref; other refs sent in the same push may be OK).