Monday, July 28, 2008

Permissions best practices

As I happen to write quite a lot about permissions lately, I thought I’d round it off with yet another post.

All permissions available in TFS (I do not take SharePoint or Reporting Services) fall in four categories

  • Server global permissions
  • Project global permissions
  • Source control permissions
  • Areas permissions

Certain principles apply to all categories, viz.

  1. Try to assign all permissions to TFS groups. That is, use TFS groups (server- or project-level) as containers to one or more Windows (AD domain or local) groups. That way the dependence on IT department is minimal, and it is easy to change the group membership while retaining overall permission structure
  2. Minimize permission assignments to users; try to use groups as much as possible. Only situations that are justified (in my opinion) are server/project administrators groups assignments. All other case should be groups. In this manner, you can maintain permissions on higher level (without figuring out how certain user is different from the rest)
  3. Use Deny sparingly, since if the user is not admin and you deny access in one of his groups, it will not be easy to find which one
  4. Allow some time for permission assignment to get synchronized to the TFS database. Frequently, the users will want the permission to become effective there and then. But TFS has certain latency in updating the effective permissions, and if you plan permissions changes in advance you will avoid lots of time and prevent users frustration. 

And now I would like to touch some version control specific permission issues (since this is by far most complicated topic, not in the least because inheritance is allowed in version control)

  1. Set as few permissions as possible. Ideally, you would set permissions on server, project and immediate project subfolders at most (and set server/project permissions by assignment to appropriate pre-defined groups). That way you will be able to immediately know where to look for the “root” of any permission problem.
  2. Never set permission on files (that can be viewed as more of the same topic as in previous paragraph, but I cannot say that enough).
  3. Use inheritance as much as possible; start with most permissive set-up and partition by using Deny.
  4. If you find yourself setting certain permissions more than once, script them using tf permissions (use tfssecurity for global and area permissions). In this way potential for human error is minimized.

And to conclude, I would highly recommend not just set permissions ad hoc as you go along, but create some permission model (I know it sounds big, but Excel table that clearly delineates the common groups and permissions set may well be sufficient). If you are not sure – start with default groups and permissions, and assign your users appropriately to default groups. Believe me, that would be way better than creating complex permissions soup that your users swim in (and hate you all the while – and they will let you know their feelings). 

By the way, you might want to watch Sidekicks blog for the soon-to-happen new release announcement (that will include Permission Sidekick). Stay tuned!

Related posts
When permission inheritance is a godsend
When permission inheritance is evil
Deny or allow – who wins? A sequel
Deny or allow – who wins?

Thursday, July 24, 2008

When (permission) inheritance is a godsend

In a previous post I talked about some issues you might encounter when transitioning from inherited to explicit permissions in TFS source control.

However, if you do not wish to completely disable permissions inheritance, there are some nice surprises in TFS permission management for you.

Let’s consider the same folder structure as in previous post

$/Project
   Source
       Common
       Proprietary

The settings for group “Contributors” on Proprietary folder are inherited from the project, and include “Check In” set to Allow.

Suppose we want to deny the “Check Out” permissions on that folder for “Contributors”, but unlike the scenario previously discussed, that is the only thing we want to change. The rest of the inherited settings should be retained. To do that you need to do three steps:

1. Uncheck “Inherit security settings” checkbox (note how all permissions are unset)

2. Deny check out for “Contributors”

3. And lastly one step that is not obvious at all – check “Inherit security settings” checkbox again

Voila! Now you have all permissions inherited from the parent folder intact, but one specific permission denied.

It is worth noting, that you cannot explicitly allow permissions, denied in the parent folder (since explicit Deny on parent will override any permissions set to Allow).

Now that you have read this post, you have officially joined the secret sect of TFS permissions administrators :).

Friday, July 18, 2008

Deny or Allow – who wins? A sequel

In a previous post, I have explored the details of effective permission evaluation in TFS.

As a supplement for this post (and generally as a reference for everyone managing TFS permissions), I highly recommend a recent “TFS Roles and Security” reference poster from Willy-Peter Schaub, Team System MVP from SA. The poster details available permissions, default TFS server and projects groups and their assigned permissions and how effective permissions are determined.

And while we are at the topic, check out additional reference posters available from Willy-Peter. These posters are different from boring bunch of tables that you might expect from your previous experiences; take a look for yourself how information presented in graphical way becomes more accessible. For example, compare “Roles and Security” poster with MSDN article providing essentially same information.

Monday, July 14, 2008

When (permission) inheritance is evil

One of the areas of Team Foundation Server that I constantly wish would become better is management of permissions inheritance. To illustrate, let’s assume that you have the following structure:

$/Project
   Source
       Common
       Proprietary

Now, let’s say that you have “Check In” permissions (and bunch of other permissions) set to Allow on Project level for group “Contributors”. Since by default inheritance is enabled, the same permissions apply to all subfolders.

But now you need to disable “Check In” and “Check Out”  for "Contributors" on Proprietary folder; and you do not want to Deny the permissions (since if the user belongs to other authorized group he still may modify the files). Thus you want to disable the inheritance altogether and unset Check In/Check Out, while retaining the rest of permissions.

So you right-click on Properties in Source Control Explorer, un-check "Inherit Security Settings" checkbox, previously disabled (since the permissions were inherited) authorization settings checkboxes become enabled (as expected) and ... simultaneously cleared. What? How am I supposed to remember all previously set checkboxes? [If you think it is innocent, remember that un-checking Security Settings checkbox will clear settings for all groups!]  

So what is the solution of this usability problem? I hate to tell you, but I do not have one real good solution. The one I have been using is to become close friends with tf permission command-line client. Once you become friends, make sure that you script reusable permissions sets as a batch file. While not perfect this approach may still help you to retain your sanity on a bad day.

Update: the above applies only to situations where you disable inheritance completely.

Monday, July 07, 2008

Deny or allow - who wins?

If you ever tried using permissions in TFS, you know that there are four kinds of permission settings that can be set for the user or group(Explicit/Implicit Allow and Explicit/Implicit Deny). Specific effective permission is defined as combination of permission settings set for user and all groups the user belongs to; the settings are combined according to the following order of precedence (from more potent to less potent setting)

  • Implicit Allow is defined when user is a member of Team Foundation Administrators group or [Project]/Project Administrators group
  • Explicit Deny is defined when Deny is explicitly set for user/group
  • Explicit Allow is defined when Allow is explicitly set for user/group
  • Implicit Deny (None) is in effect when no setting is specified

Two most important rules out of four (that are frequently forgotten and lead to “unexplained” effective permissions) are “Implicit Allow” (if the user is in admin group, the effective permissions are “everything is allowed” no matter what) and “Explicit Deny” (if Deny is set somewhere and user is not an admin, you better find that somewhere; no amount of additional “Allow” set will help).

Let’s illustrate the above with the example. Assume that there are four groups defined: Team Foundation Administrators, Contractors, Developers and Testers; and the permission settings for “Read” permission on $/Project folder are defined as following:

Group Allow Deny
Team Foundation Administrators    
Contractors   Set
Developers Set  
Testers    

In the example below, the users effective Read access will depend on the combined group membership (as an exercise, the last column is made invisible – select it to see the answer):

User name Team Foundation
Administrators
Contractors Developers Testers Can read?
User 1 X       Yes
User 2   X X   No
User 3 X X     Yes
User 4     X X Yes
User 5   X   X No
User 6       X No

Since current version of TFS does not provide effective permission indication in UI, the exercise above is something you will have to perform now and again.

This piece of wisdom (together with lots of additional pieces) can be found on MSDN; if you are planning permissions rollout or find yourself in a tight place staring at permissions set and not understanding why the things do not work as desired this is where you go.

Thanks to Brian Randell and Sam Heald for this post idea.