Wednesday, April 25, 2012

Run Away from Item Level Security!

I have been involved in some discussions regarding Item Level Security and its impact on the performance of a SharePoint farm. Interesting topic. Microsoft has a thorough article on this, download it here:

Here is the what Microsoft has to say about it, from a boundaries/limits perspective (also here):

"Security scope - 1,000 per list - Threshold
The maximum number of unique security scopes set for a list should not exceed 1,000.
A scope is the security boundary for a securable object and any of its children that do not have a separate security boundary defined. A scope contains an Access Control List (ACL), but unlike NTFS ACLs, a scope can include security principals that are specific to SharePoint Server. The members of an ACL for a scope can include Windows users, user accounts other than Windows users (such as forms-based accounts), Active Directory groups, or SharePoint groups."

This means that if you believe your list will have more than a thousand items, now or in the future, Item Level Security is not recommended. Beware that once you follow that path, it will be tough to re-design your solution.
Also, a major pain point is governance. How manageable is a solution with Item Level Security? Not much.
You would need some automation: probably workflows/event receivers and some custom coded framework to help power users managing security. This means more complexity, and we still have the threshold to handle.

An important factor on this threshold is that having more than 1,000 ACL's in a list/library impacts the whole farm, not just that list (check a very interesting post about this here).

All in all, my opinion on this topic is that you should run away from Item Level Security as much as you can.
Design the Information Architecture in a way that allows you to set the security boundaries only in site collections, sites and lists/libraries. It will make everyone's lives easier. My motto has always been the simpler, the better. Over-engineering is certainly one of the most common problems a team with good developers/consultants can get.

But, if you still need some sort of Item Level Security, there are other paths you can take. I see 3 possibilities.

First option: Folder Level Security

The way folders work has been enhanced in SharePoint 2010, with things like default metadata values based on folders. It was an improvement that allowed folders to be back on the game, in my opinion.
In terms of security boundaries, it may be a perfect fit. If, inside a library, you have a reasonable amount of separate security boundaries, you may use folders to manage the security. This away, the amount of ACL's in the list would be restricted to the number of folders.
You could make it transparent to the end user, from a viewing perspective, by not using folders on views. From an upload perspective, the end user would learn that when uploading a document, choosing a folder would actually mean choosing a security boundary. Since most users do have a file share background, most will easily understand and accept that putting documents into different folders, will mean those documents  are visible to different users.

Second option: Custom components

Another option is making the list and all items super-secure, with all items inheriting security. Only super-user accounts would have read/write access. All others users would have no permissions.
We would then build custom components to view, upload and edit documents/metadata, that would be run using elevated privileges and would have its own logic.
This is not a trivial solution, there are several limitations, as well as a lot of custom development. Think about what would happen trying to save a document from the Word client, or using Explorer View. This would need to be carefully PoC'ed, planed, agreed with the customer, implemented and tested. It would largely depend on the specific requirements. My advice would be against this path.

Third option: Folder Based and Exception Based Security

A third option I can envisage is more complex. We can have a mixture of Folder Level Security with a number of exceptional behaviours. This can be used in more complex scenarios, but it always falls into the assumption that from a business perspective it is imperative to have all these documents in the same location and that having a predefined number of folders with their security and a restricted set of unique permissions on some of the documents, would solve the problem. We would need some sort of mechanism to monitor the number of exceptions + folders, to keep it within a reasonable amount. Again, my advice would be against this path.

Important factors to consider

The most important thing to have in mind is whether you are able to re-engineer or re-design your customer's process or what they believe should be implemented, in terms of security.
Sometimes, business users mistake visibility with security. Or some sort of responsibility with security. It is important to make concepts clear to them. Security could be seen as a block. Are we setting security only because we want to control what end users see by default? Or do we really need these documents blocked to these end users? I have seen a lot of cases when it is the first option. If that's the case, you can forget security and use other alternatives, like customized views based on metadata or even custom coded components for viewing. It will be much easier, cleaner and manageable to code viewing components based on any sort of logic, than pursuing a solution where you use Item Level Security.
If you do have security boundaries to respect, and these documents must be blocked, then the first option is a clear winner. It might be tough to convince your customer, but the "Software boundaries and limits" page from Microsoft is there to help you. And if they end up choosing to pursue other strategies, you have clearly made your point here, if they have problems in the future.

Visual Studio Tip #2: Run 64-bit version of PowerShell in Post-Build

Whether you are trying to achieve Continuous Integration, Automated Unit Testing or any other scenarios, it might be very beneficial to run PowerShell scripts automatically from Visual Studio after certain actions (such as Deploy or Build).

One problem I had was with the version of PowerShell that would be called from Visual Studio 2010: 32-bit or 64-bit. If you need to use SharePoint DLL's, you need to run the 64-bit version of PowerShell.

It won't work using "%WINDIR%\system32\ WindowsPowerShell \v1.0\powershell.exe", you'll get an error using the 64-bit DLLs, because the PowerShell console that is opened is the 32-bit version.

In order to call the 64-bit version of PowerShell, you must use this path: %WINDIR%\sysNative\WindowsPowerShell\v1.0\powershell.exe.