The implementation of the example security server for SELinux required that a concrete security model be selected. A combination of Identity-based Access Control (IBAC), Role-based Access Control (RBAC), and Type Enforcement (TE) was chosen. As previously mentioned, SElinux does not depend on this model; it is straightforward to replace it with some other choice. It was chosen as the example because it is sufficiently general to support many security objectives found in real-world security.
The SELinux security server maintains security contexts with three relevant security attributes, an identity, a role, and a type. It determines which combinations of values for these attributes can be combined into security contexts. It uses each component of the security context to compute a portion of the access decisions.
There is an identity associated with every process on the system. Changes to it are rigorously controlled and the policy configuration only allows certain programs to change the identity (currently login and crond). When a user logs on and presents his credentials, the identity portion of the security context related to his login shell will reflect the user's real identity. SELinux identities are orthogonal to Linux UIDs. Except when specified in the policy, whenever the UID of a process is changed, its SELinux identity remains unchanged; when a new program is executed, the identity component will be preserved. In this way, all access control decisions can be based the correct identity.
The actions of any particular user are restricted by the RBAC policy. Users are assigned a set of roles that they may assume. The transition between roles is controlled by the policy. Although not strictly necessary, the security policy has been configured to limit role transitions to occur only as a result of running programs that require user authentication. This was done to ensure that roles changes can only occur with explicit user consent and not from executing some malicious program.
Roles are used to express allowable user actions. The RBAC policy used in SELinux differs from that described in  in that it defines allowable user actions for a particular role using the TE policy. Whereas a typical RBAC policy would directly specify permissions granted to roles, the SElinux RBAC policy specifies domains that can be entered by roles, and defers the assignment of permissions to the TE configuration. Although this form of RBAC does not offer additional security over a strict TE policy, it does allow the TE policy to be more easily managed using the higher-level concept of roles.
The TE policy is used to express the fine-grained access controls. Each object in the system is assigned a type. An access matrix is defined where each element of the matrix determines the allowable accesses between a pair of types. In SELinux, the accesses are expressed in terms of permissions granted for each subject and object class that were defined for the kernel control points. All permissions must be explicitly granted.
This form of TE differs from that defined in  in that there is no distinction made between types and domains. Domains are treated just as any other type. Domains are simply types assigned to processes. Because of this, types used as domains can also be used as a type of a related object, e.g. the type of its procfs entries. The term domain is often still used for convenience even though the security server does not internally distinguish them from types. By reducing domains and types to a single type abstraction, a single table can be used to express the TE policy based on type pairs rather than separate tables for subject interactions and object accesses. This also allows inter-object relationships to be defined in the policy.
This form of TE is also distinct in that the permissions are grouped by object class to facilitate expressing a matrix where so many more permissions are defined than typically is the case. The class concept allows permissions to be defined for each kind of object based on the services for that object, and it allows the policy to distinguish different kinds of objects, e.g. granting different permissions to a device file than to a regular file or to a raw socket than to a TCP socket. This enables SELinux to provide finer-grained permissions than what is typically expected when using TE.
TE offers many benefits over the traditional approach to MAC. The TE access matrix provides a clean separation of the policy and enforcement mechanisms. It is capable of supporting many policies. It is useful for expressing integrity, separation, containment, and invocation policies. No trusted subjects that can violate the policy are necessary. Because every process can be assigned a domain, every process can be controlled using exactly the same mechanism. Fine-grained permissions can be assigned to programs limiting privileged programs to the minimal permissions required to complete their task. Lastly, TE allows the relationship between a subject and its executable to be tightly controlled, enabling protection based on the function and trustworthiness of code and offering protection against the execution of malicious code.