How does code access security in the Windows .NET Framework affect or interoperate with user access permissions? Which one has the higher priority?

Software written and compiled for the Framework is called managed code. Classic applications, or unmanaged code, are subject only to the user's authority. Before Windows permits an application executable, such as Microsoft Word, to open a file, the Security Reference Monitor compares the file's ACL with the user's identity and with groups to which the user belongs, then grants or denies access accordingly. With unmanaged applications, which are called assemblies instead of executables, access control depends strictly on the user's authority and has nothing to do with the assembly.

The Framework lets you exert very granular control over what assemblies can do based on various criteria about them. For example, you can control whether managed code can display windows; print; and access files, the network, and the registry; as well as whether the code can perform many other operations. You implement this control through code access permissions. You can grant or deny code access permissions based on a variety of criteria, including the assembly's name, the Web site from which it was downloaded, the publisher, whether the assembly originated on the local computer, and the Microsoft Internet Explorer (IE) or intranet security zone to which the code's hosting server belongs.

When an assembly tries to perform an operation or access a resource, the Framework's Common Language Runtime (CLR) makes sure that the security policy allows the action. If the assembly passes muster with the CLR, execution continues as with any other Windows application. And, as with other Windows applications, the Security Reference Monitor checks whether the user's permissions, rights assignments, and group memberships permit the operation. Therefore, neither user access control nor code access control has precedence—they are equal. To complete an operation or access an object, managed code must pass code access control checks performed by the CLR, and the user must pass the same user access control checks that the Security Reference Monitor performs for unmanaged code.

For example, say Bob has read access to FileA, read and write access to FileB, and no access to FileC. Suppose further that he can use one of two programs to open these files: Notepad, an unmanaged application; or FileEditor, an imaginary text file editor written in a Microsoft .NET language. Let's assume that FileEditor is published by a company we'll call Acme and has a corresponding Authenticode signature from Acme. The CLR on Bob's computer has a security policy that grants assemblies published by Acme no access to FileA and FileB and modify access to FileC. If Bob uses Notepad, he'll be able to open FileA or FileB, but he won't be able to modify FileA. Bob won't be able to open FileC through Notepad because his user account and the groups he belongs to have no access to FileC.

If Bob tries to use FileEditor to open FileA for read access, he'll fail. FileEditor has no access to FileA, even though Bob does. He'll be able to open FileB through FileEditor, but only for read access; although FileEditor has read and write access, Bob has only read access. And if Bob tries to use FileEditor to open FileC, he'll fail. Thus, for managed code to execute, both Windows' traditional user-level security and the Framework's CLR must allow the code to run.