Demystifying access controls
Shawn Pearce, Google
Global Capabilities
Global Capabilities
- Configured in All-Projects
- Impacts the entire installation
Administrate Server
Edit any access control. Create any account, group or project.
Does not imply Read, Push, Create Reference, Submit, etc.
Create {Account, Group, Project}
Create an entity. No restrictions on specifics (e.g. name).
Create Project allows selecting the project rights inherit from.
Create Project does not grant permission to manage the created project.
Global Capabilities
Query Limit
Maximum number of rows the user can be returned in a /changes/ API call.
Limit is the largest of all groups the user is a member of.
Anonymous users can read up to 500 changes per call.
Authenticated users not in Non-Interactive Users group can read up to 700 per call.
Authenticated users in the Non-Interactive Users group can read up to 8,000 per call.
Cannot limit a user by placing them into a "Bad User" group. Largest max wins. ☹
Limit has almost no relationship to execution cost. ☹
Global Capabilities
Priority
INTERACTIVE is default. Requests are processed on the main thread pool, in first-in order.
BATCH if user is a member of BATCH group and NOT a member of INTERACTIVE group.
Above if a user is a member of both groups, they use INTERACTIVE.
Anonymous Users and Registered Users are special and do not grant INTERACTIVE.
BATCH requests are processed on a dedicated thread pool, in first-in order.
Batch thread pool size is controlled by sshd.batchThreads in gerrit.config.
Global Capabilities
Email Reviewers
Permits comments to be mailed to all reviewers (and not just change owner).
Default is ALLOW.
Common usage is to grant DENY to a group such as CI Server
DENY allows CI Server to only email the change owner.
Prevents spamming reviewers with (mostly) uninteresting emails.
Owner in All-Projects
Owner permission not allowed on refs/*
Owning refs/* also means the group can edit any access control.
In All-Projects this also means being able to edit Global Capabilities.
Editing Global Capabilities permits granting Administrate Server, Create Account, etc.
To prevent privilege escalation, Owner cannot be granted in All-Projects.
References
Reference Names
refs/heads/ branches
Git stores branches under the refs/heads/ prefix.
master is actually refs/heads/master
refs/tags/ tags
Git stores tags under the refs/tags/ prefix.
v1.0 is actually refs/tags/v1.0
refs/changes/ storage for code review
Gerrit tracks each patch set under this space.
Not valid in an access control. Gerrit will ignore you.
Tag Refs
Read permissions on refs/tags/*
Ignored by Gerrit.
Tags are readable if they point at a commit on a branch the user can read.
Automatically makes tags readable if placed on history the user can read.
Automatically makes tags readable when code merges to a readable branch.
Automatically hides tags if a branch is hidden / deleted / rewound.
Reference Patterns
refs/heads/master exact match
Applies only to the name written.
refs/heads/* glob match
Applies to all references that begin with refs/heads/
Glob match can only appear at the end as /*
The pattern refs/*/master matches nothing (/* not at end)
^refs/heads/[a-z]+ regular expression match
Applies to all references that match the expression.
Gerrit relies on the ^ prefix to activate regex matching.
The ^ prefix is also part of the pattern, and therefore always anchors to the start.
Limit usage only to when the above forms are insufficient.
Most Specific Match Wins
For refs/heads/QA/master Gerrit tries rules in the following order, until it has a decision:
1) refs/heads/QA/master exact match, wins
2) refs/heads/QA/* glob wildcard, longest common prefix
3) refs/heads/* glob wildcard, common prefix
4) refs/* glob wildcard, common prefix
For regular expressions "most specific" is more complicated to evaluate.
^refs/heads/QA/.*
^refs/heads/QA/stable-[0-9.]+
The 2nd rule is more specific, as it matches fewer possible strings.
Inheritance
Inheritance Configuration
Parent project specified by access.inheritFrom in project.config:
$ git show refs/meta/config:project.config
[access]
inheritFrom = Public
[project]
state = active
description = My source code
Re-resolved on each access attempt.
If not specified, defaults to All-Projects.
If named project does not exist, defaults to All-Projects.
Inheritance Merges
All-Projects
Child
Result is merged:
-1..+1 Registered Users
-2..+2 Administrators
Inheritance Overrides
All-Projects:
Child
Result is merged with overrides:
-1..+1 Administrators
-1..+1 Registered Users
+0..+2 CI Server
Most Specific First
Result for refs/heads/master
-2..+2 Administrators
+0..+2 CI Server refs/heads/* rule also matches!
Result for refs/heads/next
-1..+1 Administrators
+0..+2 CI Server
Inheritance Processing
refs/heads/master
refs/*
Child
All-Projects
Most Specific First
All-Projects
Child
Result for refs/heads/master
-2..+2 Administrators refs/heads/master rule matches in All-Projects
+0..+2 CI Server refs/heads/* rule matches in Child!
-1..+1 Registered Users
Result for refs/heads/next
-1..+1 Administrators
+0..+2 CI Server
-1..+1 Registered Users
Most Specific First
All-Projects
Child
Result for refs/heads/master
-2..+2 Administrators refs/heads/master rule matches in All-Projects
+0..+2 CI Server refs/heads/* rule matches in Child!
-1..+1 Registered Users
Result for refs/heads/next
-1..+1 Administrators
+0..+2 CI Server
-1..+1 Registered Users
Overrides!
Exclusive Checkbox
refs/heads/master
refs/*
Child
All-Projects
Exclusive Checkbox
refs/heads/master
refs/*
Child
All-Projects
Exclusive Checkbox
refs/heads/master
refs/*
Child
All-Projects
Exclusive (Off)
All-Projects
Child
Result for refs/heads/master
-2..+2 Administrators refs/heads/master rule matches in All-Projects
+0..+2 CI Server refs/heads/* rule matches in Child!
-1..+1 Registered Users
Result for refs/heads/next
-1..+1 Administrators
+0..+2 CI Server
-1..+1 Registered Users
Exclusive (Case 1)
All-Projects
Child
Result for refs/heads/master
-2..+2 Administrators refs/heads/master rule matches in All-Projects
Result for refs/heads/next
-1..+1 Administrators
+0..+2 CI Server
-1..+1 Registered Users
Exclusive (Case 2)
All-Projects
Child
Result for refs/heads/master
-2..+2 Administrators refs/heads/master rule matches in All-Projects
+0..+2 CI Server refs/heads/* rule matches in Child!
Result for refs/heads/next
-1..+1 Administrators
+0..+2 CI Server
Push Merge
Long standing bug
Push Merge Commit
Must be on refs/for/refs/heads/...
Does not work on refs/heads/...