1 of 27

Demystifying access controls

Shawn Pearce, Google

2 of 27

Global Capabilities

3 of 27

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.

4 of 27

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. ☹

5 of 27

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.

6 of 27

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.

7 of 27

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.

8 of 27

References

9 of 27

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.

10 of 27

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.

11 of 27

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.

12 of 27

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.

13 of 27

Inheritance

14 of 27

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.

15 of 27

Inheritance Merges

All-Projects

Child

Result is merged:

-1..+1 Registered Users

-2..+2 Administrators

16 of 27

Inheritance Overrides

All-Projects:

Child

Result is merged with overrides:

-1..+1 Administrators

-1..+1 Registered Users

+0..+2 CI Server

17 of 27

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

18 of 27

Inheritance Processing

refs/heads/master

refs/*

Child

All-Projects

19 of 27

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

20 of 27

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!

21 of 27

Exclusive Checkbox

refs/heads/master

refs/*

Child

All-Projects

22 of 27

Exclusive Checkbox

refs/heads/master

refs/*

Child

All-Projects

23 of 27

Exclusive Checkbox

refs/heads/master

refs/*

Child

All-Projects

24 of 27

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

25 of 27

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

26 of 27

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

27 of 27

Push Merge

Long standing bug

Push Merge Commit

Must be on refs/for/refs/heads/...

Does not work on refs/heads/...