Role Playing

When it comes to security in .NET’s Web services world, it’s going to be vital to know how each application plays its part.

In my town, they meet at the Historical Society. Across the world, there are millions of them. Some are flaunting their colors. Others, dressed in blend-in-anywhere-casuals, are quietly standing around chatting like churchgoers after Sunday morning services. They’re not street people—oh, no. They could be anybody, even you or me. But at night, the fangs, snouts, cloaks and magic come out. As a group, while not exactly moving along a pre-determined path, they travel. Sometimes with supporting cards, dice or other props and other times strictly with verbal tales they become one organism. How is that possible? Everyone has a role and everyone plays it. This has always been a successful model for co-existence among peers. It’s even been a successful model for the implementation of access controls on trusted computing systems.

This model, role-based access control, is part of the security model that will be available to users of .NET. (At last! A security model that even programmers can understand.) Like my interesting friends, .NET uses other forms of security as well, including Evidence (players recognize each other or submit to some questioning or other methods of identification) and Permissions (each player comes with a strict set of rules that defines what she can do).

Next-Generation Authentication
To understand how this works, twist your thoughts from the traditional models of user-based authentication and authorization you’re comfortable with and focus on the concept of application authentication and authorization. In a .NET world, applications will span companies and countries. Each time the application runs, it’ll branch off and connect to Web services (small pieces of code that perform some function or service).

Instead of tightly controlled processes owned and managed by a single company; instead of occasional and highly managed links between applications that span corporate borders; instead of the deep involvement of the end-consumer in coordinating the results of multiple enquiries, .NET’s vision is one of a highly distributed network that consists of three things. First, some Web services will perform a function (query a database, check your bank account, validate your credit card, accept an order, transfer money, issue a certificate and so on). Second, other Web services will be consumers of these services; they’ll transparently connect with and use services, then disengage. Finally, to find the services they need, the consumers will locate services by using directory services. Think of it like fireflies during the mating season. The female firefly sits on vegetation somewhere and flashes her abdomen. The fickle male firefly flits about madly looking for these quick flashes of yellow-green light. The female is offering a service, and the male becomes the consumer. If fireflies were part of a .NET design, they could consult a directory that would point them to the location for the fulfillment of their desire.

Fireflies can depend on the laws of nature to assure the strongest survive, but no such protection will be in place for .NET. In .NET, indeed, in the use of any Web services-based model, we have to find a way to manage the security implications of these diverse couplings. How will your Web services authenticate? How will they know that the Web services they’re talking to are really the Web services they claim to be? Because Web services will allow external agents to manipulate, query and modify data, how will they authorize that access or that action? When information flows between millions of diverse Web services across the Internet, how can we guarantee the integrity of the data? How can we be sure that the information sent is the information received? Furthermore, can the use of Web services provide non-repudiation—can they reliably show, beyond legal deniability, that two Web services did connect and do business?

There are various proposals for the management of security in the Web services world. Before we all get there, many will be more clearly defined. Current proposals include signed and encrypted XML; XMLDSig (digitally signed XML); Security Assertion Markup Language (SAML), the proposed Internet standard for exchanging user and authorization and services over the Internet; XML Key Management Services (XKMS), which defines the XML messages used by applications to work with PKI; and S2ML (www.s2ml.org), the Security Services Markup Language, a proposed standard for secure e-commerce transactions via XML. We don’t know which of these proposals, or others yet defined, will become part of our vocabulary. What we do know is that any model that seeks to work between different Web services developed via different vendor specifications will have to follow a standard.

However, within each vendor Web service model there may be a wide range of functional processes to accommodate access to legacy systems or to enforce their customers’ perceptions of the proper controls. You might compare this to the processes we’ve used as travelers for many years. When you travel internationally, your passport serves as identification that’s recognized by most nations. For domestic travel, a state driver’s license suffices; in your hometown, authorities may recognize you personally without formal introduction or official paperwork. Microsoft .NET’s security process will follow this same model, using standards where they exist and are relevant and following its own model when working within its own space.

This month I’d like to talk to you about one of the security mechanisms defined for .NET: code authorization. Authorization (what you can do once you’ve proved your identity) in .NET is accomplished via Roles, Permissions, Permission Sets and Evidence. My description below defines .NET’s implementation as described in public documents at Microsoft.com and in its two-day .NET developer training tour. You should keep in mind that, at the time of this writing, the .NET framework, Windows .NET Server and other paraphernalia are still in beta. Note that the information has been greatly simplified in order to provide an overview. The SDK has more information.

.NET Framework Role-Based Security
.NET applications use role-based authorization based on a principal’s Windows account or custom identity. In the lingo of .NET, we use the term “principal” to represent an identity that can be authorized to perform a function or access some resource. Generic principals exist outside the traditional user and role (group) models of Windows NT and Windows 2000. Windows principals are the traditional user and role (group) models of Windows NT and Win2K. Custom principals are defined by an application. They may exist only for that application.

If a principal has authenticated to the Web service, then, just as in traditional processing of requests for data or the performance of some function, .NET must determine if the principal is authorized to do what it has asked to do. In traditional business processes, policy is often enforced through the use of roles. The size of a transaction may be limited, giving clerks one authorized level, supervisors another, and vice presidents none at all. Some actions, such as the use of color printers by various roles, may be associated with the time of day. In a .NET application, roles such as clerk, supervisor or vice president are associated with the principal and, therefore, are available to the process currently running. Furthermore, in .NET, the concept of role-based access control can be extended to an application, a component of that application, or even some smaller code construct.

Role-based security in .NET is implemented through Role-based security permissions.

Code Permissions
In .NET, just like familiar file, folder, printers, registry keys and directory objects, code can be given permission. Three types of permissions exist: Code Access permissions, Identity permissions and Security permissions. Table 1 defines these permissions.

Permission Types Permission Use
Code Access DNS permission Environment permission
File dialog access
File

Isolated storage


Identity
Reflection

Registry

Security



Socket

UI

Web

Access to DNS.
Read or Write environment variables.
File selected in open dialog box.
Read, Append or Write files or directories.
Access isolated storage (associated with specific user and some code aspect).
Web site, publisher or signature.
Discover information about data type at runtime.
Read, Write, Create or Delete keys and values.
Execute, assert permissions, call unmanaged code, skip verification.
Make or accept connections on transport address.
Access user interface function.
Make or accept connection to Web address.

Identity Class name
Publisher

Site

Strong name


Zone

URL
What identity this is.
Software publisher digital signature.
The Web site of code origination.
A unique cryptographic name assigned to some code component.
Zone where code originated.
URL, including protocol prefix (http, https).
Security Principal Several built-in provided classes and the ability to create custom permission classes.
Table1. In .NET, code may be given permission. Three types of permissions exist: Code Access, Identity and Security.

A Matter of Trust
The traditional server trusts all applications and seeks to protect its resources with the use of object permissions and user rights. All applications are trusted if run by an authorized user. In .NET, all applications are not created equal. The .NET application can be restricted in its actions by associating it to a named permission set or group of permissions. This establishes a policy that defines the code’s permissions. Named permission sets include Nothing, Execution (operation, but no access to protected resources), Internet (default for code from an unknown origin), Local Intranet (default permissions within an enterprise), Everything (all permissions, except permission to skip verification), and Full Trust (full access to resources).

Note the difference here. Instead of defining access permission on files, folders, printers and AD objects, a named permission set spells out what a piece of code can do. This assignment doesn’t mean you should abandon object permissions; it does, however, provide another administrative tool for our side of the security war. Three of the permission sets—Internet, Local Intranet and Everything—can be modified. While developers may assign code permissions, we, the administrators, can spell out defaults for known and unknown code. In addition, we can create custom permission sets to fit specific applications or environments.

Why are we concerned about restricting the access that code can have? Simply put, it’s code running on a system that either does the required job or acts to corrupt and destroy the system. While your efforts may be simply to process information, there are those who write code to corrupt your system’s message queues, event logs, performance counters, Active Directory objects and files. They think nothing of the havoc that might be created by changing priorities of processes and other acts—or perhaps that’s their intent. The code running on your systems is no longer your code but comes from a variety of sources, including e-mail; documents in which it’s embedded; downloaded from the Internet; and brought home from conventions, meetings and classes.

Why Network Administrators Need to Know About .NET Now!
To continue in your role as infrastructure master, you need to prepare for the explosion in Web services that .NET and its competitors will be releasing. You need to be reading about .NET and working with its clients and servers. I know you’re deeply committed to that roll-out of Windows 2000 or XP Professional or patching all servers or… So here are some pressing reasons to convince you to save a little bit of your time for .NET.

  • New security mechanisms permeate the .NET structure. Code authorization is just one.
  • Best practices in .NET suggest that application information reside in regular files, not in the registry. Try troubleshooting new .NET applications without that bit of knowledge.
  • Eight million Visual Basic programmers are just learning this stuff, too. How bulletproof will their apps be? How will you know? Are they implementing the security mechanisms that will allow you to protect your systems properly?
  • A new tool, ILDasm.exe, parses .NET Framework .EXEs and .DLLs and shows the information in a form that you and I can read—as can everyone else. While knowing what the code is won’t matter to most people, if your applications have hard-coded passwords, they’ll be exposed.
  • How are you going to make these entirely new types of applications work on entirely new servers and clients?
  • You’re the one who’ll get to make solutions work between disparate vendors. Do you know what’s standard, what’s proprietary and what solutions there may be for making them all work together?

To counter the impact of all this code of unknown or untrusted origin, we now have methods for establishing trust or in limiting its ability to affect the system if we can’t. Trust, then, must be established not just for the user of the code, but for the code on its own. We can do this via recognition of the code’s author, its origination or some custom-designed evidence. Once identity is established, the policies of the system determine under which Permission set the code will run.

Putting it All Together
So with all these opportunities for controlling what code can do and touch in any environment, what determines what it actually can do? A .NET application is managed by the Common Language Runtime (CLR). The CLR looks at the three levels of security policy (machine policy, user policy and application domain policy) and determines what a code group, or logical collection of code, can do.

In the .NET world, administrators set policy; runtime enforces it.

Featured