There's a dirty little secret in the computer security world that makes the dream of least-privilege access control very hard to attain: It's often literally impossible to determine who has what level of access to which objects.
How so? The access privileges granted to a person or any other security subject -- such as another computer, service, daemon, and so on -- are determined by the permissions configured on each individual computer and each individual object, such as file, folder, registry key, memory area, and more. Both can be difficult to check, but the latter is much more difficult, thanks to scale.
[ It's time to reconsider security. Two former CIOs show you how to rethink your security strategy for today's world. Bonus: Available in PDF and e-book versions. | Stay up to date on the latest security developments with InfoWorld's Security Central newsletter. ]
Your basic access-control model
Overall access policies are defined for every computer. These include the types of access that are allowed, either for all users or specific sets of users. In Windows, more than a dozen different types of general access can be defined: logging on locally, using RDP, over the network, anonymously.
After access has been granted, the objects a user can view, read, delete, or modify are controlled by the individual permissions stored along with each object. In Windows, these permissions are called access-control entries, and the collection of all access-control entries is called an access-control list.
When the user attempts to access a particular object, Windows first checks to see if the user is allowed to access the computer via the method employed, whether local, network, or otherwise. Then it compares the access-control list's set of permissions to the access requested. If they match, the user is allowed to access the object.
That's the local machine. When the user requests write access to a particular file on a remote computer over the network, the user's "security token" -- holding his or her authenticated identity and group memberships -- is passed to the remote operating system along with the user's desired access request. A security mechanism in the remote operating system then queries the file's access-control list. The access-control list defines what users and groups are allowed to work with the object and with what permissions (read, write, and so on).
Let's say the user account is allowed read access only, but the user belongs to a group that is allowed write access. In most modern operating systems, that group membership would enable the user to write to the file. This is a pretty straightforward process -- or so it seems.
Who can do what
Now suppose a company wants to know all about a particular user's access privileges. Unless that has been meticulously documented, every computer system and every object on every computer system in the environment must be queried to generate an accurate list.
Now repeat this process for every user and computer within your environment. Even if you limit queries to important computers and important files, you can easily end up with hundreds of billions of individual queries and answers, even in a small-to-midsize business.
To obtain accurate results, the query must match the user and the groups they belong to against the object's allowed users and group memberships -- and understand how nested groups impact the answer. It's not unusual for a single user to belong to dozens or even hundreds of groups, and no small percentage of those groups are typically members of other groups. I've seen a user account that apparently belonged to 10 groups, but after taking nesting into account, the user actually belonged to more than 100 groups.
When an access-control query comparison is made, the querying tool must first build a master list of all the groups the person belongs to, including nested groups. This is no small task, since most companies I deal with have more groups than users. The real world is far messier.