Add documentation on the access control lists and rights

Signed-off-by: Shawn O. Pearce <sop@google.com>
diff --git a/Documentation/access-control.txt b/Documentation/access-control.txt
new file mode 100644
index 0000000..f1fd347
--- /dev/null
+++ b/Documentation/access-control.txt
@@ -0,0 +1,483 @@
+Gerrit2 - Access Controls
+=========================
+
+Access controls in Gerrit are group based.  Every user account is a
+member of one or more groups, and access and privileges are granted
+to those groups.  Groups cannot be nested, and access rights cannot
+be granted to individual users.
+
+
+System Groups
+-------------
+
+Gerrit comes with 3 system groups, with special access privileges
+and membership management.  The identity of these groups is set
+in the `system_config` table within the database, so the groups
+can be renamed after installation if desired.
+
+Administrators
+~~~~~~~~~~~~~~
+
+This is the Gerrit "root" identity.
+
+Users in the 'Administrators' group can perform any action under
+the Admin menu, to any group or project, without further validation
+of any other access controls.  In most installations only those
+users who have direct filesystem and database access would be
+placed into this group.
+
+Membership in the 'Administrators' group does not imply any other
+access rights.  Administrators do not automatically get code review
+approval or submit rights in projects.  This is a feature designed
+to permit adminstrative users to otherwise access Gerrit as any
+other normal user would, without needing two different accounts.
+
+Anonymous Users
+~~~~~~~~~~~~~~~
+
+All users are automatically a member of this group.  Users who are
+not signed in are a member of only this group, and no others.
+
+Any access rights assigned to this group are inherited by all users.
+
+Administrators and project owners can grant access rights to this
+group in order to permit anonymous users to view project changes,
+without requiring sign in first.  Currently it is only worthwhile
+to grant `Read Access` to this group as Gerrit requires an account
+identity for all other operations.
+
+Registered Users
+~~~~~~~~~~~~~~~~
+
+All signed-in users are automatically a member of this group (and
+also 'Anonymous Users', see above).
+
+Any access rights assigned to this group are inherited by all
+users as soon as they sign-in to Gerrit.  If OpenID authentication
+is being employed, moving from only 'Anonymous Users' into this
+group is very easy.  Caution should be taken when assigning any
+permissions to this group.
+
+It is typical to assign `Code Review -1..+1` to this group,
+allowing signed-in users to vote on a change, but not actually
+cause it to become approved or rejected.
+
+Registered users are always permitted to make and publish comments
+on any change in any project they have `Read Access` to.
+
+
+Account Groups
+--------------
+
+Account groups contain a list of zero or more user account members,
+added individually by a group owner.  Any user account listed as
+a group member is given any access rights granted to the group.
+
+To keep the schema simple to manage, groups cannot be nested.
+Only individual user accounts can be added as a member.
+
+Every group has one other group designated as its owner.  Users who
+are members of the owner group can:
+
+* Add users to this group
+* Remove users from this group
+* Change the name of this group
+* Change the description of this group
+* Change the owner of this group, to another group
+
+It is permissible for a group to own itself, allowing the group
+members to directly manage who their peers are.
+
+Newly created groups are automatically created as owning themselves,
+with the creating user as the only member.  This permits the group
+creator to add additional members, and change the owner to another
+group if desired.
+
+It is somewhat common to create two groups at the same time,
+for example `Foo` and `Foo-admin`, where the latter group
+`Foo-admin` owns both itself and also group `Foo`.  Users who
+are members of `Foo-admin` can thus control the membership of
+`Foo`, without actually having the access rights granted to `Foo`.
+This configuration can help prevent accidental submits when the
+members of `Foo` have submit rights on a project, and the members of
+`Foo-admin` typically do not need to have such rights.
+
+
+Project Access Control Lists
+----------------------------
+
+A system wide access control list affecting all projects is stored
+in project id 0 (named "`\-- All Projects \--`" in a default
+installation).  Only the id is recognized as special by Gerrit.
+
+Per-project access control lists are also supported.
+
+Users are permitted to use the maximum range granted to any of their
+groups in an approval category.  For example, a user is a member of
+`Foo Leads`, and the following ACLs are granted on a project:
+
+[grid="all"]
+`----------------`-------------`-------
+Group            Category       Range
+---------------------------------------
+Anonymous Users  Code Review     -1..+1
+Registered Users Code Review     -1..+2
+Foo Leads        Code Review     -2..0
+---------------------------------------
+
+Then the effective range permitted to be used by the user is
+`-2..+2`, as the user is a member of all three groups (see above
+about the system groups) and the maximum range is chosen (so the
+lowest value granted to any group, and the highest value granted
+to any group).
+
+All Projects
+~~~~~~~~~~~~
+
+Only members of the group `Administrators` may edit the access
+control list for `\-- All Projects \--`.
+
+Ownership of this project cannot be delegated to another group.
+
+Any access right granted to a group within `\-- All Projects \--`
+is automatically inherited by every other project in the same
+Gerrit instance.  These rights can be seen, but not modified,
+in any other project's `Access` administration tab.
+
+Per-Project
+~~~~~~~~~~~
+
+Every project has a group designated as its owner.  Users who are
+members of the owner group can:
+
+* Change the project description
+* Change the owner of the project to another group
+* Create/delete a branch through the web UI (not SSH)
+* Grant/revoke access rights
+
+Note that project owners implicitly have branch creation or deletion
+through the web UI, but not through SSH.  To get SSH access project
+owners must grant an access right to their own group, just like
+for any other user.
+
+The per-project ACL is evaluated before the global
+`\-- All Projects \--` ACL, permitting some limited override
+capability to project owners.  This behavior is generally only
+useful on the `Read Access` category when granting `-1 No Access`
+within a specific project to deny access to a group.
+
+
+Categories
+----------
+
+Gerrit comes pre-configured with several default categories that
+can be granted to groups within projects, enabling functionality
+for that group's members.
+
+[[category_READ]]
+Read Access
+~~~~~~~~~~~
+
+The `Read Access` category controls visibility to the project's
+changes, comments, code diffs, and Git access over SSH.  A user must
+have `Read Access +1` in order to see a project or any of its data.
+
+This category has a special behavior, where the per-project ACL is
+evaluated before the global all projects ACL.  If the per-project
+ACL has granted `Read Access -1`, and does not otherwise grant
+`Read Access \+1`, then a `Read Access +1` in the all projects ACL
+is ignored.  This behavior is useful to hide a handful of projects
+on an otherwise public server.
+
+For an open source, public Gerrit installation it is common to grant
+`Read Access +1` to `Anonymous Users` in the `\-- All Projects \--`
+ACL, enabling casual browsing of any project's changes, as well as
+fetching any project's repository over SSH.  New projects can be
+temporarily hidden from public view by granting `Read Access -1`
+to `Anonymous Users` and granting `Read Access +1` to the project
+owner's group within the per-project ACL.
+
+For a private Gerrit installation using a trusted HTTP authentication
+source, granting `Read Access +1` to `Registered Users` may be more
+typical, enabling read access only to those users who have been
+able to authenticate through the HTTP access controls.  This may
+be suitable in a corporate deployment if the HTTP access control
+is already restricted to the correct set of users.
+
+[[category_pTAG]]
+Push Annotated Tag
+~~~~~~~~~~~~~~~~~~
+
+This category permits users to push an annotated tag object over
+SSH into the project's repository.  Typically this would be done
+with a command line such as:
+
+====
+  git push ssh://USER@HOST:PORT/PROJECT tag v1.0
+====
+
+Tags must be annotated (created with `git tag -a` or `git tag -s`),
+must exist in the `refs/tags/` namespace, and must be new.  Deleting
+and overwriting existing tags is not permitted.  Lightweight tags
+are not permitted.
+
+This category is intended to be used to publish tags when a project
+reaches a stable release point worth remembering in history.
+
+[[category_pHD]]
+Push Branch
+~~~~~~~~~~~
+
+This category permits users to push directly into a branch over SSH,
+bypassing any code review process that would otherwise be used.
+
+This category has several possible values:
+
+* Update Branch
++
+Any existing branch can be fast-forwarded to a new commit.
+Creation of new branches is rejected.  Deletion of existing branches
+is rejected.  This is the safest mode as commits cannot be discarded.
+
+* Create Branch
++
+Implies 'Update Branch', but also allows the creation of a new branch
+if the name does not not already designate an existing branch name.
+Like update branch, existing commits cannot be discarded.
+
+* Force Push Branch; Delete Branch
++
+Implies both 'Update Branch' and 'Create Branch', but also allows an
+existing branch to be deleted. Since a force push is effectively a
+delete immediately followed by a create, but performed atomically on
+the server and logged, this also level permits forced push updates
+to branches.  This level may allow existing commits to be discarded
+from a project history.
+
+This category is primarily useful for projects that only want to
+take advantage of Gerrit's access control features and do not need
+its code review functionality.  Projects that need to require code
+reviews should not grant this category.
+
+[[category_VRIF]]
+Verified
+~~~~~~~~
+
+The verified category can have any meaning the project desires.
+It was originally invented by the Android Open Source Project to
+mean 'compiles, passes basic unit tests'.
+
+The range of values is:
+
+* -1 Fails
++
+Tried to compile, but got a compile error, or tried to run tests,
+but one or more tests did not pass.
++
+*Any -1 blocks submit.*
+
+* 0 No score
++
+Didn't try to perform the verification tasks.
+
+* +1 Verified
++
+Compiled (and ran tests) successfully.
++
+*Any +1 enables submit.*
+
+In order to submit a change, the change must have a `+1 Verified` in
+this category from at least one authorized user, and no `-1 Fails`
+from an authorized user.  Thus, `-1 Fails` can block a submit,
+while `+1 Verified` enables a submit.
+
+If a Gerrit installation does not wish to use this category in any
+project, it can be deleted from the database:
+
+====
+  DELETE FROM approval_categories      WHERE category_id = 'VRIF';
+  DELETE FROM approval_category_values WHERE category_id = 'VRIF';
+====
+
+If a Gerrit installation wants to modify the description text
+associated with these category values, the text can be updated
+in the `name` column of the `category_id = \'VRIF'` rows in the
+`approval_category_values` table.
+
+Additional values could also be added to this category, to allow it
+to behave more like `Code Review` (below).  Insert -2 and +2 value
+rows into the `approval_category_values` with `category_id` set to
+`VRIF` to get the same behavior.
+
+[NOTE]
+A restart is required after making database changes.
+See <<restart_changes,below>>.
+
+[[category_CVRW]]
+Code Review
+~~~~~~~~~~~
+
+The code review category can have any meaning the project desires.
+It was originally invented by the Android Open Source Project to
+mean 'I read the code and it seems reasonably correct'.
+
+The range of values is:
+
+* -2 Do not submit
++
+The code is so horribly incorrect/buggy/broken that it must not be
+submitted to this project, or to this branch.
++
+*Any -2 blocks submit.*
+
+* -1 I would prefer that you didn't submit this
++
+The code doesn't look right, or could be done differently, but
+the reviewer is willing to live with it as-is if another reviewer
+accepts it, perhaps because it is better than what is currently in
+the project.  Often this is also used by contributors who don't like
+the change, but also aren't responsible for the project long-term
+and thus don't have final say on change submission.
++
+Does not block submit.
+
+* 0 No score
++
+Didn't try to perform the code review task, or glanced over it but
+don't have an informed opinion yet.
+
+* +1 Looks good to me, but someone else must approve
++
+The code looks right to this reviewer, but the reviewer doesn't
+have access to the `+2` value for this category.  Often this is
+used by contributors to a project who were able to review the change
+and like what it is doing, but don't have final approval over what
+gets submitted.
+
+* +2 Looks good to me, approved
++
+Basically the same as `+1`, but for those who have final say over
+how the project will develop.
++
+*Any +2 enables submit.*
+
+In order to submit a change, the change must have a `+2 Looks good to
+me, approved` in this category from at least one authorized user,
+and no `-2 Do not submit` from an authorized user.  Thus `-2`
+can block a submit, while `+2` can enable it.
+
+If a Gerrit installation does not wish to use this category in any
+project, it can be deleted from the database:
+
+====
+  DELETE FROM approval_categories      WHERE category_id = 'CRVW';
+  DELETE FROM approval_category_values WHERE category_id = 'CRVW';
+====
+
+If a Gerrit installation wants to modify the description text
+associated with these category values, the text can be updated
+in the `name` column of the `category_id = \'CRVW'` rows in the
+`approval_category_values` table.
+
+Additional values could be inserted into `approval_category_values`
+to further extend the negative and positive range, but there is
+likely little value in doing so as this only expands the middle
+region.  This category is a `MaxWithBlock` type, which means that
+the lowest negative value if present blocks a submit, while the
+highest positive value is required to enable submit.
+
+[NOTE]
+A restart is required after making database changes.
+See <<restart_changes,below>>.
+
+[[category_SUBM]]
+Submit
+~~~~~~
+
+This category permits users to push the `Submit Patch Set n` button
+on the web UI.
+
+Submitting a change causes it to be merged into the destination
+branch as soon as possible, making it a permanent part of the
+project's history.
+
+In order to submit, all approval categories (such as `Verified` and
+`Code Review`, above) must enable submit, and also must not block it.
+See above for details on each category.
+
+[[category_makeoneup]]
+Your Category Here
+~~~~~~~~~~~~~~~~~~
+
+Gerrit administrators can also make up their own categories.
+
+See above for descriptions of how `Verified` and `Code Review` work,
+and insert your own category with `function_name = \'MaxWithBlock'`
+to get the same behavior over your own range of values, in any
+category you desire.
+
+Ensure `category_id` is unique within your `approval_categories`
+table.  The default values `VRIF` and `CVRF` used for the categories
+described above are simply that, defaults, and have no special
+meaning to Gerrit.  The other standard category_id values like
+`READ`, `SUBM`, `pTAG` and `pHD` have special meaning and should
+not be modified or reused.
+
+The `position` column of `approval_categories` controls which column
+of the 'Approvals' table the category appears in, providing some
+layout control to the administrator.
+
+All `MaxWithBlock` categories must have at least one positive value
+in the `approval_category_values` table, or else submit will never
+be enabled.
+
+To permit blocking submits, ensure a negative value is defined for
+your new category.  If you do not wish to have a blocking submit
+level for your category, do not define values less than 0.
+
+Keep in mind that category definitions are currently global to
+the entire Gerrit instance, and affect all projects hosted on it.
+Any change to a category definition affects everyone.
+
+For example, to define a new 3-valued category that behaves exactly
+like `Verified`, but has different names/labels:
+
+====
+  INSERT INTO approval_categories
+    (name
+    ,position
+    ,function_name
+    ,category_id)
+  VALUES
+    ('Copyright Check'
+    ,3
+    'MaxWithBlock'
+    ,'copy');
+
+  INSERT INTO approval_category_values
+    (category_id,value,name)
+  VALUES
+    ('copy', -1, 'Do not have copyright');
+
+  INSERT INTO approval_category_values
+    (category_id,value,name)
+  VALUES
+    ('copy', 0, 'No score');
+
+  INSERT INTO approval_category_values
+    (category_id,value,name)
+  VALUES
+    ('copy', 1, 'Copyright clear');
+====
+
+The new column will appear at the end of the table (in position 3),
+and `-1 Do not have copyright` will block submit, while `+1 Copyright
+clear` is required to enable submit.
+
+[[restart_changes]]
+[NOTE]
+Restart the Gerrit web application and reload all browsers after
+making any database changes to approval categories.  Category data
+is aggressively cached by every corner of Gerrit, as it does not
+change often.  Browser may need more than 5 minutes to flush the
+old category data out of their local disk caches.