Code Access Security in .NET

Code Access Security is one of the powerful features of .NET but at the same time some confusion exists about its terminology and its usage. With this, I would like to make an attempt to explain some of the terminology with diagrams. This document does not explain all the details related to CAS, as lot of information already exists on the internet and only gives a jump start to Code Access Security.

The basics thing is whenever any code is being executed in managed world the .NET runtime verifies whether that code is allowed or not based on evidence and set of permissions.


Where from the code came?


What permissions are allowed for the code?

Basics Details

With the above basics let us explore Evidence and Permissions and other Code Access Security terminology.


Evidence of an assembly is about its identity who it is and where it came from.

  • From where the assembly is being loaded?
  • If the assembly is downloaded from the web, what is the URL of the source directory?
  • What is Strong Name (if any)?
  • Who is the publisher (if digitally signed)?

How does System find out about this?
Codebase property of an assembly determines about its location which will result in either local directory, intranet/internet.One can get strong name and publisher details from the assembly manifest.
Once the Evidence of the assembly is gathered, the system grants some permission to this assembly.

How does System find out what permissions an assembly can have?
Time to explain some more terms. Let’s try to understand the following.

Policy Levels

.NET runtime security has 4 policy levels viz., Enterprise, Machine, User, and AppDomain. (which can be done programmatically).

Each policy has multiple code groups and multiple permission sets.

Code groups

Code group is a group of assemblies which satisfies the same condition. A code group will have one member condition which decides about particular assembly can be a member of this (group) or not.

Permissions and Permission Sets

Permission is what the code can do with a particular resource like File, Registry etc., and Permission Set is collection of permission.

.NET Default Policies will be

Now, we understood Policy Levels, Code Groups and their Permissions. It is time to find out how the system assigns the permissions to the loaded assembly.

Below is pseudo code how .NET Security system grants the permission to the assembly (Assumes no programmatic security)

public PermissionSet GetPermission(Assembly asm )


foreach( PolicyLevel pl in System.Security.Configuration.PolicyLevels )


foreach( CodeGroup cg in pl.CodeGroups )


if( cg.MembershipCondition exists in asm.Evidence )


// In given level it is the UNION of permissions across code groups

permissionSet[pl] = permissionSet[pl] Union cg.PermissionSet;




// Across levels it is intersecion of permissions

finalPermissionSet = permissionSet[“Enterprise”] Intersecion permissionSet[“Machine”]  Intersecion permissionSet[“User”];

return finalPermissionSet;

// Assume Exclusive and LevelFinal are not set


From above the .NET Security system assigns the permission set to the assembly.

At this point system has assigned the permission to the assembly

How does it get enforced?

The .NET classes ( System.IO.File , Microsoft.Win32.Registry classes will do the rest ) will enforce this by calling to appropriate security class.

Lets’ see how the File.OpenText code does this.

Pseudo code for OpenText()


string[] pathList = new string[1];

pathList[0] = pathToOpenFile;

new FileIOPermission( FileIOPermissionAccess.Read,pathList).Demand();


The call to .Demand will check the permission and throw an exception if it is not permitted to open the file.

If you have call to unmanaged dll where you open the text file the .NET will not be able to check whether you have permission to open or not.


Each code group in a policy consists of one property called Exclusive which means don’t consider any other permissions in that policy.

Lets’ walk through this…

Suppose your assembly belongs to Code group A, Code Group B and Code group C in Machine Policy.

Machine Policy

Code Group A

Permission Set A

Code Group B

Permission Set B

Code Group C

Permission Set C

And ‘Assembly Z’ falls in all code groups. Then permission set in this policy will be

Machine Level Policy for Assembly Z = (Permission Set A)   U (Permission Set B)  U (Permission Set C)  

But if set Exclusive property True in Code Group B then permission set in Machine Policy will be

MacineLevel Policy for Assembly Z =  ( Permission Set B )

Note: Still the final permission set will be intersection of Enterprise, Machine and User.

The exclusive property in .NET Configuration tool will be having check mark as

Level Final

There is another property called Level Final when checked, On Code Group, the policy in the next level will not considered.

Lets’ walk through this…

Enterprise Policy

Code Group


Permission E

Machine Policy

Code Group


Code Group A

Permission Set_A

Code Group B

Permission Set_B

Code Group C

Permission Set_C

User Policy

Code Group

Code Group 1

Permission Set_1

Code Group 2

Permission Set_2

Code Group 3

Permission Set_3

Suppose if an assembly belongs to All_Code in Enterprise, Code Group A,B,C in Machine and Code Group 1,2,3 in User then

Final Permission set = (Permision E) Intersection (Permision_A U Permission_B U Permission_C) Intersection (PermissionSet_1 U PermissionSet_2 U PermissionSet_3)

With Final Property set on Code Group B in Machine Policy then User Policy will not be evaluated and hence.

Final Permission set = (Permision E) Intersection ( Permision_A U Permission_B U Permission_C )

In .Net Security Configuration tool the Level Final property will be shown like below

With Exclusive and Level Final property one can precisely control the permission set applied to an assembly.