Recall that Lampson's gold standard identifies authorization, authentication, and audit as essential mechanisms for computer security. We begin studying authorization, which controls whether actions of principals are allowed, by considering access control. An access control policy specifies access rights, which regulate whether requests made by principals should be permitted or denied.
In access control, we refine the notion of a principal to be one of a:
Why is that distinction important? Executing programs can be controlled; people can't. People can have different identities that they convey to programs. And the same program can be executed by different users. Determining which user a subject corresponds to is the problem of authentication, which we've already covered.
The basic model we have in mind is that a subject attempts to access an object. The object is protected by a guard called a reference monitor. The principle of Complete Mediation says that reference monitor must check every access.
The primary concerns of an access control system are the following:
A discretionary access control (DAC) policy is a means of assigning access rights based on rules specified by users. The underlying philosophy in DAC is that subjects can determine who has access to their objects.
DAC policies includes the file permissions model implemented by nearly all operating systems. In Unix, for example, a directory listing might yield "... rwxr-xr-x ... file.txt", meaning that the owner of file.txt may read, write, or execute it, and that other users may read or execute the file but not write it. The set of access rights in this example is {read, write, execute}, and the operating system mediates all requests to perform any of these actions. Users may change the permissions on files they own, making this a discretionary policy.
A mechanism implementing a DAC policy must be able to answer the question: "Does subject S have right R for object O?" Abstractly, the information needed to answer this question can be represented as a mathematical relation D on subjects, objects, and rights: if (S,O,R) is in D, then S does have right R for object O; otherwise, S does not. More practically, the same information could also be represented as an access control matrix [Lampson 1971]. Each row of the matrix corresponds to a subject and each column to an object. Each cell of the matrix contains a set of rights. For example:
file1 | file2 | |
Alice | rwx | r-x |
Bob | r-- | rw- |
Real systems typically store the information from this matrix either by columns or by rows.
An implementation that stores by columns is commonly known as an access control list (ACL). File systems in Windows and Unix typically use such an implementation: each file is accompanied by a list of entries (s, rs), containing subjects s and their rights rs to that file. An implementation that stores by rows is commonly known as a privilege list or a capability list. Each subject maintains an unforgeable list of entries (o, rs) containing objects o and rights rs to that object. Android uses a privilege list: each app can be granted the right to access the network, GPS, phone, etc.
Each implementation makes certain auditing concerns easier to address than others:
The discussion of privilege/capability lists above suggested that a trusted access control system manage storage of the lists. In a distributed system, it would instead be possible to have untrusted subjects manage the storage of those lists. Alice could keep track of the capabilities issued to her, Bob of those to him, and so forth. But now the authenticity of those capabilities must be ensured: we would not want subjects to be able to manufacture capabilities never issued to them by the access control system.
Digital signatures provide a mechanism to implement capabilities in this distributed setting. To issue a right r to a subject named S for an object named O, the access control system can construct a capability cap, where cap=(S,O,r), and sign that capability, producing a signature s, where s=Sign(cap; k_AC) and where k_AC is a private signing key for the access control system. The pair (cap,s) can be given by the access control system to the subject. Whenever the subject wishes access, it presents (cap,s) back to the access control system, which verifies the signature and the rights contained in the capability.
This scheme can be modified support delegation:
Revocation, however, now becomes a problem, much like it did for digital certificates. It might not be possible to delete capabilities once they have been issued. So the access control system might need to include validity intervals (so that capabilities expire), or maintain revocation lists (which must be consulted by the reference monitor).
Moreover, these capabilities are expensive. Creating keys and verifying digital signatures both take time, and storing the signature takes space.
The policy enforced by an access control system is rarely static. Commands are issued to change the policy. An access control system might provide commands to create and destroy objects, grant and revoke rights to objects, create and destroy subjects, create trust relationships between subjects, etc. A command can be specified as follows:
command C(args) requires: R ensures: E
C is the name of the command, R is a precondition that must hold for the command to be executed, and E is the effect the command has on the access control system.
For example, the access control system for a file system might include include a right called own that indicates a subject owns an object. And this system might allow the owner of a file to grant the right to read the file to any other subject. That would be realized by the following command:
(* subject s grants read right for file f to subject q *) command grant-read-file(s,f,q) requires: (s,f,own) \in D ensures: D := D \union {(q,f,read)}
As another example, the system might support a command to create files, which grants the creator the own, read, and write commands:
(* subject s creates file f *) command create-file(s,f) requires: f does not already exist as an object in D ensures: D := D \union {(s,f,own), (s,f,read), (s,f,write)}
Some access control systems permit subjects other than the owner to delegate their rights to an object to another subject. For example, Alice might delegate her rights to read file f to Bob. The right to delegate rights to other principals is sometimes called the copy right or the grant right. A fine-grained access control system will associate a distinct copy right with every right. For example, the read right could be associated with the delegate-read right, the execute right could be associated with the delegate-execute right, etc.
Here is a revised command for grant the right to read a file:
(* subject s delegates read right for file f to subject q *) command grant-read-file(s,f,q) requires: (s,f,delegate-read) \in D ensures: D := D \union {(q,f,read)}
Note that q will not be able to further delegate the read right to other principals, because the command does not grant delegate-read to q.
Students get access to a class because they are enrolled in it, not because of their own individual identities. Faculty get access to a fancy dining room on campus [would that were true...] because of their job status, not because of their own individual identities. In both cases, access is determined by being a member of a group.
Group membership changes over time. So it's not wise to assign group-determined rights directly to individuals, because then administrators would need to redetermine rights anytime group memberships change. It's better to assign rights to a new kind of subject, a group, which is a named set of subjects.
In ACLs, we can have a new kind of entry (g, rs), where g is group name. And separately, we can have a group list with entries (g, subjs), where g is the group name and subjs is set of subjects. For capabilities, the implementation becomes a little more complex; we omit details here.
In the real world, security policies are dynamic. Access rights, whether discretionary or mandatory, need to change as the responsibilities of users change. This can make management of rights difficult. When a new user is authorized for a system, the appropriate rights for that user must be established. When a user changes job functions, some rights should be deleted, some maintained, and some added.
Role-based access control (RBAC) addresses this problem by changing the underlying subject–object model. A role is a job function or title—i.e., a set of actions and responsibilities associated with a particular working activity. Now, instead of an access control policy being a relation on subjects, objects, and rights, a policy is a relation on roles, objects, and rights; this is called a right assignment. For example, the role "5430 TA" might be assigned the right to grade 5430 homeworks. Further, subjects are now assigned to roles; this is called a role assignment. Each subject may be assigned to many roles, and each role may be assigned to many subjects. Finally, roles are hierarchical. For example, the role "5430 Professor" should have all the rights that a "5430 TA" does, and more.
Roles are similar to groups in Unix file system DAC, with two important distinctions. First, a group is a set of users, whereas a role is a set of rights. Second, at least in some implementations, a user is always a member of a group, whereas a subject may activate or deactivate the rights associated with any of the subject's roles. This enables finer-grained implementation of the Principle of Least Privilege. Subjects may login with most of their roles deactivated, and activate a role only when the rights associated with the role are necessary.