I blog about development using .net, C#, SQL, Windows RT, and other Microsoft technologies.
Disclaimer: All posts are provided "AS IS" with no warranties, confering no rights, and expressing only my personal opinion, not Microsoft's.
In a previous post, I talked about the deny option and how it’s evaluated. The documentation on MSDN is talking about conflicting permissions on the same level, however, in TFS2008 SP1, permissions are evaluated bottom up and the first match wins. If a user, Eve, is denied read on $/ but is a member of [Proj]\Readers (which has Read access), the read permission will be the first match and Eve will be to read $/Proj recursively. If you need to deny users read permission, you have to make sure to remove them from all groups that has read access. The reason behind this design is that administrators usually want to allow permissions for certain projects to certain users and the rest should be denied, consider the following tree structure:
$/ Proj A Proj B Proj C
You may want to grant Eve read permission on Proj B and only Proj B. To do so, you should deny Eve all permissions on $/ then allow Eve read permission on Proj B. Since permissions are evaluated bottom-up on first-match basis, Eve has read access to proj B, while the denied permissions are effective on both existing projects and future projects D, E, F, ..etc.
Ping back from the MSDN document: http://msdn.microsoft.com/en-us/library/ms252587.aspx
This is then directly defeating "the principle of least privilege" security methodology.
A simple example being that I have a group "mydomain\guests" which I set deny permission to all roles at the TFS and Source Control $ root level.
I also have a "Guests" project that I then allow the group access to in TFS and SC.
The "mydomain\guests" group now must be in the "Team Foundation Server Valid Users" group as well as it's own.
If I give read permissions to the "Team Foundation Server Valid Users" group to any object in source control, the "mydomain\guests" group now also has read access, even though read access has been set to deny on the "mydomain\guests" group at the same level via inheritence, or even without inheritence.
While this can be worked around by defining additional project level groups for the read permission desired, it is counter-intuitive to most security administrators who are used to "the principle of least privilege" security methodology.
We tried out this approach (denying at the $/ level ) but it has the side effect that the project users then can't see or apply labels. Is there a solution for that?