Transparency Models: A Tale of Two Levels
Earlier this week, we looked at how the v4 CLR continued the evolution of the security transparency model that started in v2 and started evolving with Silverlight in order to make it the primary security enforcement mechanism of the .NET 4 runtime.
The result is that the v4 transparency model, while having roots in the v2 transparency model, is also somewhat different in both the rules that it enforces and how it enforces them. These differences are enough that code written for the v2 transparency model will not likely run without some modifications in the v4 model. Since the v4 runtime is compatible with v2 assemblies, the CLR security system needs to provide a way for code written for the older v2 transparency model to continue to run until it is updated to work in the more modern v4 transparency model.
This was done by splitting the transparency models up into two rule sets:
- Level 1 - the security transparency model that shipped in the v2 CLR
- Level 2 - the security transparency model that ships with the v4 CLR
Assemblies built against the v2 .NET framework are automatically considered to be level 1 assemblies - after all, if they were written before the v4 transparency model even shipped how could they possibly be written to use that model? Similarly, assemblies built against the v4 runtime are by default considered to be using the level 2 model. Since level 1 exists largely for compatibility reasons, new code starts out automatically using the modern transparency enforcement system.
What about existing code bases that are simply being recompiled for v4 however? Those assemblies were also not written with the v4 transparency rules in mind, so it doesn't follow that a simple recompile has fixed up the assembly's code to understand the new security rules. In fact, the first step in moving v2 code to v4 is very likely trying to simply getting it to compile with as few source changes as possible.
For assemblies in this bucket, the CLR offers an attribute to lock an assembly (even though it is built for v4) back to the level 1 security transparency rules. In order to do that, all the assembly needs to do is apply the following assembly level attribute:
[assembly: SecurityRules(SecurityRuleSet.Level1)]
(Both the SecurityRulesAttribute and the SecurityRuleSet enumeration live in the System.Security namespace)
Adding this attribute unblocks the assembly being recompiled from being forced to update to the new security transparency model immediately, allowing you more time to make that transition. When the assembly is ready to move forward to the v4 transparency model, the level 1 attribute can simply be replaced with the equivalent attribute stating that the assembly is now going to be using the level 2 rules:
[assembly: SecurityRules(SecurityRuleSet.Level2)]
Although this isn't strictly necessary, as level 2 is the default for all assemblies built against the v4 runtime, I consider it a good practice to explicitly attribute assemblies with the security rule set that they are written to use. Being explicit, rather than relying on defaults, future proofs your code by having it be very clear about the security model that it understands.