Permissions Sets, Code Groups, and Code Access Policies
Code groups are the building blocks of security
policies. A Code Group is made of an association between an evidence value,
also known in this case as a membership condition, and a permission set
(that gathers together a set of permissions).
For instance, a fictitious code group could be the WindowsUpdate code group
URL=http://www.microsoft.com (evidence membership
condition) / Everything (permission set).
A hierarchical structure of Code Groups defines a security
policy. The .NET framework comes with three different security policies:
Enterprise, Machine, User. Additionally an host can define application
domain-level policy by calling the AppDomain.SetAppDomainPolicy method on
the System.AppDomain class. The first three policies are typically set by
administrator while the latter is eventually defined by developers.
The .NET framework comes with a number of built-in permission sets as shown
You can define additional custom permission sets if
necessary gathering together the desired code access permissions listed in the
previous paragraph. Note that you cannot assign directly a list of permission to
a membership condition to define a Code Group.
Custom permission sets are defined in XML files and then loaded in the desired
The code permissions an assembly is granted is made of the
intersection of the permissions each policy assign to the assembly (unless the -Levelfinal
attribute is specified). The order of policy level evaluation for the
LevelFinal attribute is enterprise, machine, and then user. The application
domain policy level, if present, is always intersected with other levels even if
the LevelFinal attribute is in effect for one of those levels.
Now there is just thing left to explain: How a policy is
applied to a given assembly, that is, how each policy, separately, builds up the
list of permissions sets an assembly is granted. The procedure is as follows:
- CAS checks if the assembly can be granted membership to
the root Code Group (this check always succeeds in a default configuration
since the root Code Group is defined as membership: All Code Permission set:
- CAS then evaluates if the assembly can be granted
membership to the root’s child Code Groups (matching the assembly evidence
with the Code Group membership condition). For any granted membership the
corresponding permissions sets are added.
- CAS proceeds evaluating the membership of the assembly
against the Code Groups that are child of a Code Group the assembly has been
granted membership in the previous step. CAS ignores Code Groups sub-trees
that are child of Code Groups that have not been granted membership in the
- Back to step 3 till all paths have been covered.
This logic is described graphically in the picture below,
where green blocks represent granted membership; red blocks represent denied
membership and yellow ones are code groups that are not evaluated.
Code groups, permission sets and policy
structures can be queried and modified using the caspol.exe command line tool or
using a much more friendly tool called the Microsoft .NET Framework
Configuration Management Console snap-in.
Here I’ve included a snapshot of the CAS entities as shown by the snap-in
Code Access Permission Requests
CAS let’s you declare via a set of attributes at assembly level what permissions
(or permissions sets) your code
needs at minimum
thus interacting/modifying the permissions assigned by the evidence vs. security
policy mechanism described in the previous chapters.
In this code snippet a VB.NET assembly refuses the permissions associated with
the FullTrust permission set and requires the File I/O permission.
<assembly: FileIOPermission(SecurityAction.RequestMinimum, Unrestricted :=
<assembly: PermissionSetAttribute(SecurityAction.RequestRefuse, Name :=
When the CLR loads the assembly it evaluates the assembly permission requests
against the permissions that have been assigned to it by CAS policies. If the
assembly has not been granted the RequestMinimum permissions the assembly won’t
load and an exception will be thrown, additionally the CLR will, eventually,
remove permissions that have been granted to the assembly due its evidence but
that have been explicitly refused by RequestRefuse declarations.
CAS Requests are not compulsory, still there are number of reason why you would
won’t to evaluate to use them: the main reason is to avoid having to assembly
loaded if the permissions restrictions would make its functionalities
Moreover, when declaring CAS requests your code is not required to gracefully
handle any and all situations where not being granted some permission might
prevent it from executing properly.
One last advantage is that putting permissions requests into the assembly
metadata let administrators easily explore the assembly requirements with the
Permission View tool (Permview.exe) to adjust, eventually, security