README
author Paul Crowley <paul@ciphergoth.org>
Thu Apr 24 08:27:30 2008 +0100 (7 months ago)
changeset 28 583ed103e021
parent 262c4f499ea12f
permissions -rw-r--r--
update README to reflect new scripted installer
     1 hg-admin-tools
     2 
     3 A set of tools for managing authorization and access control for
     4 ssh-based Mercurial repositories
     5 
     6 Paul Crowley, paul@lshift.net, 2008
     7 
     8 This software may be used and distributed according to the terms
     9 of the GNU General Public License, incorporated herein by reference.
    10 
    11 WHAT IT GIVES YOU
    12 
    13 These tools make it easier to provide a centralized repository host
    14 with read/write access to many repositories for many developers.
    15 Access control is managed with a special repository on the server
    16 called "hgadmin"; pushes to this repository immediately change the
    17 rules that are in effect.
    18 
    19 Inside "hgadmin" is a "keys" directory containing the SSH keys of all
    20 developers who have access, and a file "hg-ssh-access.conf" which
    21 gives a set of rules defining who can do what to what.
    22 
    23 All of the repositories controlled by these tools are owned by a
    24 single user (the "hg" user in what follows), but many remote users can
    25 act on them.  We don't use file permissions to achieve that - instead,
    26 developers log in as the "hg" user when they connect to the repository
    27 host using ssh, using ssh URLs of the form
    28 "ssh://hg@repository-host/repository-name".  A restricted shell
    29 prevents them from using this access for unauthorized purposes.
    30 Developers are authenticated only using SSH keys; no other form of
    31 authentication is supported.
    32 
    33 QUICK START
    34 
    35 You will need 
    36 
    37 - "sudo" installed
    38 - "sudo" root privileges
    39 - an ssh-key set up with ssh-agent
    40 
    41 Ensure there is no user called "hg" on the repository host, and run
    42 "./install" to create them. You are now the sole user able to change
    43 and create repositories on this repository host.  To give access to
    44 others, check out hgadmin - as yourself, and on whichever host is most
    45 convenient, but using the ssh-key with which you set up the
    46 repository:
    47 
    48    mkdir ~/hg
    49    cd ~/hg
    50    hg clone ssh://hg@repository-host/hgadmin
    51    cd hgadmin
    52 
    53 You can now add other users by putting their keys in an appropriate
    54 subdirectory of the "keys" directory, and control their access by
    55 editing hg-ssh-access.conf.  Changes will take effect as soon as you
    56 push them to "ssh://hg@repository-host/hgadmin".
    57 
    58 Users authorized to do so can now also create new repositories on this
    59 host with "clone":
    60 
    61   hg clone . ssh://hg@repository-host/my-project-name
    62 
    63 HG-SSH-ACCESS.CONF
    64 
    65 Each line of hg-ssh-access.conf has the following syntax:
    66 
    67 <rule> <condition> <condition> ...
    68 
    69 Rule is one of
    70 
    71 init - allow any operation, including the creation of new repositories
    72 write - allow reads and writes to this file in this repository
    73 read - allow the repo to be read but reject matching writes
    74 deny - deny all requests
    75 
    76 A condition is a globpattern matched against a relative path, one of:
    77 
    78 user=<globpattern> - user's key
    79 repo=<globpattern> - repo (as the user supplies it)
    80 file=<globpattern> - file in the repo
    81 branch=<globpattern> - name of the branch
    82 
    83 The first rule in the file which has all its conditions satisfied is
    84 used to determine whether an action is allowed.
    85 
    86 Paths cannot contain any special characters except "/"; glob patterns
    87 cannot contain any special characters except "/" and "*".  "*" matches
    88 zero or more characters not including "/" while "**" matches zero or
    89 more characters including "/".
    90 
    91 Blank lines and lines that start with "#" are ignored.
    92 
    93 FILE CONDITIONS
    94 
    95 The rules file is used to make four decisions:
    96 
    97 - Whether to allow a repository to be created
    98 - Whether to allow access to a repository
    99 - Whether to allow a changeset on a particular branch at all
   100 - Whether to allow a changeset to change a particular file
   101 
   102 When the first two of these decisions are being made, nothing is known
   103 about what files might be changed, and so all file conditions
   104 automatically succeed for the purpose of such decisions.  This means
   105 that doing tricky things with file conditions can have
   106 counterintuitive consequences:
   107 
   108 - You cannot limit read access to a subset of a repository with a
   109 "read" rule and a file condition: any user who has access to a
   110 repository can read all of it and its full history.  Such a rule can
   111 only have the effect of masking a later "write" rule, as in this
   112 example:
   113 
   114    read repo=specialrepo file=dontwritethis
   115    write repo=specialrepo
   116 
   117 allows all users to read specialrepo, and to write to all files
   118 *except* that any changeset which writes to "dontwritethis" will be
   119 rejected.
   120 
   121 - For similar reasons, don't give "init" rules file conditions.
   122 
   123 - Don't try to deny write access to a particular file on a particular
   124 branch - a developer can write to the file on another branch and then
   125 merge it in.  Either deny all writes to the branch from that user, or
   126 allow them to write to all the files they can write to on any branch.
   127 In other words, something like this will have the intended effect
   128 
   129   write user=docs/* branch=docs file=docs/*
   130 
   131 But something like this will not have the intended effect; it will
   132 effectively allow these users to write to any file on any branch, by
   133 writing it to "docs" first:
   134 
   135   write user=docs/* branch=docs
   136   write user=docs/* file=docs/*
   137   read user=docs/*
   138 
   139 HOW IT WORKS
   140 
   141 When a developer attempts to connect to a repository via ssh, the SSH
   142 daemon searches for a match for that user's key in
   143 ~hg/.ssh/authorized_keys.  If the developer is authorised to connect
   144 to the repository they will have an entry in this file.  The entry
   145 includes a "command" prefix which specifies that the restricted shell
   146 should be used; this shell is passed an argument identifying the
   147 developer.  The shell parses the command the developer is trying to
   148 execute, and consults a rules file to see if that developer is allowed
   149 to perform that action on that repository.  The bulk of the work of
   150 the restricted shell is done by the Python program "hg-ssh", but the
   151 shell script "hg-ssh-wrapper" sets up some configuration so that you
   152 can change it to suit your local installation.
   153 
   154 The file ~hg/.ssh/authorized_keys is generated by "refresh-auth",
   155 which recurses through a directory of files containing SSH keys and
   156 generates an entry in authorized_keys for each one, using the name of
   157 the key file as the identifier for the developer.  These keys will
   158 live in the "keys" subdirectory of a repository called "hgadmin".  A
   159 hook in this repository re-runs "refresh-auth" on the most recent
   160 version after every push.
   161 
   162 Finally, a hook in an extension is run for each changeset that is
   163 remotely committed, which uses the rules file to determine whether to
   164 allow the changeset.
   165 
   166 LOCKING YOURSELF OUT
   167 
   168 If you find yourself "locked out" - that is, that you no longer have
   169 the permissions needed in hgadmin - you can break back in again if
   170 you're able to become the "hg" user on the repository host.  Once you
   171 are that user, delete ~hg/.ssh/authorized_keys (to stop any user who
   172 might have access but shouldn't from using the repository while you
   173 fix things).  Then go into ~hg/repos/hgadmin, do an "hg update", edit
   174 things to your satisfaction, and commit the change.  Finally, run
   175 ~/admin/hg-admin-tools/refresh-auth to regenerate
   176 ~hg/.ssh/authorized_keys. 
   177 
   178 THANKS
   179 
   180 Thanks for reading this far.  If you use hg-admin-tools, please tell
   181 me about it.
   182 
   183 Paul Crowley, 2008