Closed Bug 1273092 Opened 8 years ago Closed 1 year ago

Use Auth0 LDAP-derived claim groups to set internal Treeherder permissions (eg for sheriffs)

Categories

(Tree Management :: Treeherder, defect, P3)

defect

Tracking

(Not tracked)

RESOLVED WONTFIX

People

(Reporter: emorley, Unassigned)

References

Details

Currently Treeherder-specific permissions such as being able to modify the hidden jobs list require that a user has an is_staff permissions bit set. This is done by hand in the Django admin control panel.

Another way to do this (post bug 1273034)would be to use LDAP groups and login.taskcluster.net's mapping of LDAP groups to Taskcluster scopes:
https://github.com/taskcluster/taskcluster-login#taskcluster-user-login-service

"""
For both LDAP and Mozillians there is a list of allowed groups. An LDAP user is given a role mozilla-user:<email>. For each allowed LDAP group the user is given the role mozilla-group:<group>. 

...

We restrict LDAP and Mozillians groups under consideration to a fixed set of groups, configured with environment variables so new ones are easy to add. We do this as temporary credentials can't cover an infinite list of scopes. Additionally this allows us to ensure that groups are indeed intended to be used for issuing taskcluster scopes.

If there is a demand, we can look at making this more dynamic, so it's easier to allow new groups. Maybe by issuing scopes for any group that has a role.
"""

See also the docs on scopes:
https://docs.taskcluster.net/manual/apis/scopes

We would then use these scopes as part of login to set relevant permissions - each time they login we'd create/update the Django user, setting the correct permissions. See the example here:
https://docs.djangoproject.com/en/1.9/topics/auth/customizing/#writing-an-authentication-backend

We should also probably switch from the in-built Django "is_staff" permissions group to custom ones we create for each role:
https://docs.djangoproject.com/en/1.9/topics/auth/customizing/#custom-permissions

One consideration is how we deal with users being deactivated. ie: their LDAP account may have been disabled (or groups removed), however we'll cache their current permissions until the next time they need to log in. We could use the auth Pulse exchange to keep track of groups, but it may not be worth the hassle, given the login.taskcluster.net session only last 3 days anyway (albeit the Django session cookie may end up having a longer expiry, depending on decisions in bug 1273034):
https://docs.taskcluster.net/reference/platform/auth/exchanges

Example scopes list (from my account):
  "scopes": [
    "assume:mozilla-user:emorley@mozilla.com",
    "assume:mozilla-group:scm_level_1",
    "assume:mozilla-group:scm_level_3",
    "assume:mozilla-group:scm_level_2",
    "assume:mozilla-group:ateam",
    "assume:mozilla-group:team_moco",
    "assume:mozillians-user:emorley",
    "auth:create-client:mozilla-ldap/emorley@mozilla.com/*",
    "auth:delete-client:mozilla-ldap/emorley@mozilla.com/*",
    "auth:update-client:mozilla-ldap/emorley@mozilla.com/*",
    "auth:reset-access-token:mozilla-ldap/emorley@mozilla.com/*"
  ],
Summary: Use login.taskcluster.net's LDAP-derived scopes to set Treeherder permissions → Use login.taskcluster.net's LDAP-derived scopes to set internal Treeherder permissions
Priority: -- → P4
Continuing the discussion from bug 1311493:

(In reply to Dustin J. Mitchell [:dustin] from bug 1311493 comment #9)
>   https://tools.taskcluster.net/auth/roles/#mozilla-group:vpn_sheriff
> 
> is using vpn_sheriff to give sheriff permissions.

vpn_sheriffs gives VPN and buildbot master access, so needs to be a smaller group of people than those who require sheriff permissions on treeherder.

As such, we'll still need to create another LDAP group (eg "treeherder_sheriffs"), so that we can just hand out treeherder permissions and not everything. (Though hopefully we can use inheritance to make it include all vpn_sheriffs members automatically - presuming that's possible?).

(In reply to Dustin J. Mitchell [:dustin] from bug 1311493 comment #9)
> Like I said, those are both
> really flexible so set up the LDAP groups in whatever fashion makes sense to
> you, and I can make the necessary TC role adjustments.

Many thanks! :-)

Some notes on things we'll need to do as part of this bug:
* Create a "treeherder_admins" LDAP group and vet membership somewhere documented (or re-purpose vpn_treeherder, depending on the outcome of bug 1311493)
* Create a "treeherder_sheriffs" group and vet membership somewhere documented
* Get the relevant TC scopes derived from those LDAP groups whitelisted/set up
* Add a new Django user group for sheriffs, to replace the current behaviour of giving sheriffs superuser (is_staff) access too
* Add Treeherder auth backend code for setting is_staff and is_sheriff from the TC scopes
* Switch API endpoints/UI code to use the new Django sheriff group and not is_staff to determine permissions
* Create read the docs entries for how to request Treeherder permissions via LDAP group changes (with file bug links etc)
* Appropriate mailing list notification of change in authorisation process
* Security review of all of the above
* Confirm that is_staff has been revoked from non-treeherder devs (perhaps also need to revoke existing sessions etc)
Priority: P4 → P3
See Also: → 1056052
Depends on: 1395356

Since comment 1 we now use Auth0 SSO, which exposes LDAP groups via the https://sso.mozilla.com/claim/groups key in the ID token payload:
https://github.com/mozilla/treeherder/blob/e234d507774c083c279cf59af4280c378fd9f829/treeherder/auth/backends.py#L108-L113

In addition, we no longer use the Django admin, so that use case can be ignored.

As such the rough steps would now be:

  1. Audit the cases where Treeherder still uses is_staff (grepping for is_staff, isStaff and IsStaffOrReadOnly gives: perfherder sheriffing use cases, plus auto-classify tab functionality - though the later is ~disabled anyway)
  2. Find existing LDAP groups that cover those users/use-cases, or else create new ones.
  3. Ensure all users who currently have is_staff are members of those LDAP groups if still needed
  4. Decide whether to track group membership via Django session data, or else via standard django user groups (pros and cons of each), and set them accordingly in the auth backend here:
    https://github.com/mozilla/treeherder/blob/e234d507774c083c279cf59af4280c378fd9f829/treeherder/auth/backends.py#L184-L193
  5. Add new permission classes here that use those new groups (likely more than one group, eg one for perf sheriffs, one for ...):
    https://github.com/mozilla/treeherder/blob/e234d507774c083c279cf59af4280c378fd9f829/treeherder/webapp/api/permissions.py
  6. Update the APIs that use IsStaffOrReadOnly to use the new permission classes instead
  7. Create read the docs entries for how to request Treeherder permissions via LDAP group changes (with file bug links etc) and email affected users (eg sheriffs)
  8. Once deployed and working, revoke is_staff from users that don't need it (pretty much all of them)
Summary: Use login.taskcluster.net's LDAP-derived scopes to set internal Treeherder permissions → Use Auth0 LDAP-derived claim groups to set internal Treeherder permissions (eg for sheriffs)

cleaning up old bugs we haven't fixed

Status: NEW → RESOLVED
Closed: 1 year ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.