I've heard a few questions and comments about our permission model recently. For example, some folks have asked why user in two groups, one granted a permission and one denied the same permission, is denied the permission rather than granted it. The answer lies in our permissioning model.
Lets first define a few terms to get us all on the same page. Note that these are not necessarily official terms, they're just the terms I've used when discussing permissions with folks on the team here:
Overall, we follow the same permissioning scheme as the Windows OS. A permission may be allowed, denied, or unset. Unless a permission is allowed (explicitly or implicitly, through inheritence or immediately on the securable object), the permission is denied. The only exception is for Administrator users who are always granted permissions (for Version Control, admin users are users who are Machine Administrators on the AT). Hence, if you don't want users to be able to be able to perform a given action, simply don't grant them permission to do so and don't add them to a group that's been granted that permission.
From that notion comes the title of this post- keep your permission set as minimal as possible, and you won't run into situations where a user is a member of 27 groups, half of which are granted some set of permissions, half of which are denied some overlapping set, and all of which cause your head to spin.
Now, that's not to say that you shouldn't set permissions on objects. Certain permissions are necessary to use the system in a reasonable way. Just remember that as soon as a user is denied a permision, whether explicitly or implicitly and whether the permission is inherited or immediate, no amount of grants at any level to any group will override the deny setting. Denied permissions are the trump card and should be used to specifically lock resources and components. Since all denies trump all allows aside from administrator status, users may be unable to perform actions if they're in two groups that have different permission settings.
Let's walk through a simple example. Suppose you have four different groups- developers, testers, contractor developers, and contractor testers. Due to corporate policy, contractor developers may be disallowed from directly checking in changes and locking files, while contractor testers may be disallowed from viewing the developer source code. Lets also suppose that the two contractor groups have been added to the other two groups (contractor developers to developers and contractor testers to testers). If your product code resides under the Version Control path $/AcmeCode/Product/, you could set permissions on the folder as follows:
All other permissions (e.g. "Undo other users changes") are unset for all four of these groups, so are treated as denied permissions unless the users are members of other groups. This permission set will completely lock out the "contract testers" group from that version control path, while the "contract developers" can read, label, and pend changes which they will then shelve to have a full developer check in.
An alternate method would be to make the developers group a member of the contractor developers group (and not vice versa, only granting the "contractor developers" read, label, and pendchange permission while adding the lock and checkin permissions to the developer group. Of course, this seems a little weird from the perspective of someone looking at group containment and could therefore get confusing.
So, that's a little long winded, but I hope it gets the point across and helps you make informed decisions about what our permissions mean.