When we talk about enterprise computing, and enterprise identity, we usually talk in terms of large-scale system architectures. But architectures can scale from enormous to minuscule—down to the level of packets on the wire. In my past few columns, I’ve spoken about some of the big identity issues we’re dealing with today, such as securely connecting your enterprise to that great big service station in the sky (aka the cloud). This month, I’d like to talk about something on the other end of the identity scale, something down near the atomic level in IT terms: the Active Directory (AD) security access token. This little mote controls authorization in an AD domain, and if you don’t pay attention to it, you might be setting yourself up for some big problems.
A Token in a Ticket
The Kerberos security protocol is the bedrock upon which AD builds practically everything else. Strictly speaking, the Kerberos protocol handles only authentication (securely identifying a user’s identity on a computer network). With the introduction of Windows 2000, Microsoft extended the Kerberos protocol to also handle authorization (determining whether a user has rights to access a resource). At the time, Microsoft was criticized for extending existing standards for its own purposes and causing interoperability problems with other Kerberos systems. In this case, the Kerberos standard does provide for extensions by making a user-defined field—a placeholder—in the ticket-granting ticket (TGT) called the Privilege Attribute Certificate (PAC). Microsoft stores the security access token in the PAC field of the Kerberos ticket to handle authorization.
How is the access token created? When a user successfully authenticates to an AD domain, the Kerberos Key Distribution Center’s Authentication Service queries its local directory service and the closest Global Catalog to determine what groups the user is a member of. It then generates an access token that contains those groups and their SIDs, and the user’s name and SID, and adds it to the TGT.
Token Bloat
The size of the PAC field and the access token it holds is finite; the field doesn’t stretch to fit a large access token pushing up against the PAC’s limits. Therefore, the limit to the number of groups a user can be a member of is about 1,015. This is because the PAC can hold only 1,024 SIDs, minus a varying number of well-known groups that the Local Security Authority (LSA) adds to the access token. (See the Microsoft article “Users who are members of more than 1,015 groups may fail logon authentication” at support.microsoft.com/kb/328889.) That might sound very large, but users can run up against this access token limit with as few as 270 groups, and begin to feel its effects long before they reach the limit. This situation is known as token bloat, and it won’t affect just one of your users when it hits: It will affect a lot of them.
Why? Because other mechanisms, such as RPC and HTTP, rely on the MaxTokenSize registry value (HKEY_LOCAL_MACHINE\SYSTEM\CCS\Control\Lsa\Kerberos\Parameters) when they allocate buffers for authentication. By default, MaxTokenSize is 12,000 bytes; if a user is a member of more than 120 groups, he or she might begin to experience slow logons and other erratic behavior, and users with greater numbers of groups in their access token will encounter authentication errors and Access Denied authorization errors.
The MaxTokenSize value can be adjusted upward to accommodate more groups (see the Microsoft article “How to use Group Policy to add the MaxTokenSize registry entry to multiple computers” at support.microsoft.com/kb/938118), but OSs since Windows Vista and Windows Server 2008 will automatically adjust MaxTokenSize upward to compensate for greater group membership. However, this is just a Band-Aid on the problem; users will still experience the slowdown effects of a large access token, and the 1,015-group limit cannot be exceeded regardless of how high you manually set MaxTokenSize.
It’s important to keep in mind that when a user’s group membership is enumerated to create the access token, it includes all transitive group memberships as well. This means that using a deeply nested group structure—though it might be convenient from an organizational viewpoint—will increase the average size of the user’s access tokens. For example, if you’re a member of the Muleshoe Users security group, which is a member of the Bailey County Users group, which is a member of the Texas Region group, which is a member of the US Region group, you already have four group SIDs in your access token.
There’s a further consideration in this debate about token size. Different group types take up varying amounts of space in the PAC. Domain local groups take 40 bytes to store in the PAC, but global groups and universal groups take only 8 bytes per group. So, if you’ve been following group-nesting guidelines to focus on domain local groups, you’ll see token-bloat problems sooner than in a domain that uses global and universal groups.
Another place token bloat will bite you is related to Microsoft SharePoint. Starting with SharePoint 2007, security groups—not just distribution lists (DLs), which don’t have a SID—are required to configure permissions to SharePoint resources. The easiest solution, and one I’m sure many companies have implemented, is to simply turn all DLs into security groups. This is potentially a nightmare—first, because you probably haven’t managed or organized your DLs in the same way you’ve organized your security groups for access control, and second, because it will dramatically increase the size of your user’s access token when all these DLs show up in it. How many mail distribution lists are you a member of? Do you even know?