Level 2 · Chapter 3
Security descriptors & ACLs
The object-side rulebook: owners, DACLs, SACLs, and the sharp edge between 'no policy' and 'nobody allowed'.
Access tokens covered the caller's side of every access decision. This chapter covers the object's side: the security descriptor, the metadata structure attached to nearly every securable object in Windows — files, registry keys, processes, services, named pipes, and more — that defines exactly what's allowed to happen to it.
What a security descriptor actually holds
- An owner SID — the identity considered to own the object, with an implicit, structural right to read and modify its own security descriptor regardless of what the DACL says.
- A DACL (Discretionary Access Control List) — the authorization rules: who can do what.
- A SACL (System Access Control List) — the auditing rules: what activity should be logged to the Security event log, independent of whether it's allowed.
Both the DACL and SACL are ordered lists of ACEs (Access Control Entries), each one naming a trustee (a SID), a set of rights, and whether it's an Allow, Deny, or Audit entry.
Missing DACL vs. empty DACL: the distinction that trips almost everyone up
This is worth stating precisely, because the two are easy to confuse and behave in opposite ways:
- No DACL at all (a null DACL) means "no policy is defined for this object" — and the access check, finding nothing to evaluate against, allows the request. A null DACL is effectively unrestricted access.
- An empty DACL (a DACL that exists but contains zero ACEs) means "an explicit policy exists, and it grants nothing" — the access check finds no ACE that could allow the request, and denies everything, including to the object's own owner for anything beyond the implicit owner rights.
These produce opposite real-world outcomes from what looks, at a glance, like a very similar state, which is exactly why this distinction is worth memorizing rather than reasoning about from first principles under time pressure during an incident.
ACE order is not decorative
A DACL is evaluated top to bottom, and the access check for a given requested right stops as soon as that right has been either fully granted or explicitly denied — it does not necessarily scan every ACE. This has a specific, important consequence: a Deny ACE listed before an Allow ACE for the same trustee (or an overlapping group) wins, because the check reaches the deny first and stops. This is exactly why Windows' own tooling (and best practice) conventionally places Deny ACEs before Allow ACEs in a DACL — not as a style preference, but because the evaluation order is genuinely what decides the outcome.
A worked example: a deny ACE for one group blocking a different, broader allow
Consider a file whose DACL has, in order: a Deny-Write ACE for a specific "Contractors" group, followed by an Allow-Write ACE for "Authenticated Users." A contractor is a member of both groups. When that user requests write access, the SRM (covered next, in Access checks & the Security Reference Monitor) reaches the Deny ACE first and stops — the write is denied, even though a later ACE would, in isolation, have allowed it for a group this user also belongs to. This is the single most common source of "but I'm clearly allowed, why is this denied" confusion in real troubleshooting, and it's entirely explained by ACE order plus overlapping group membership.
A common mistake
Treating a DACL as an unordered set of rules — as if Windows evaluates every ACE and somehow combines the results — leads directly to the confusion above. It's an ordered list with early-exit semantics, much closer to a firewall rule list than to a simple permission bitmask, and reasoning about it that way from the start avoids a large share of real access-control debugging pain.
Where this connects
- Access checks & the Security Reference Monitor is where this chapter's ACE-by-ACE evaluation is actually carried out, against a specific caller's token.
- Object Manager covers where security descriptors live as part of the general kernel-object model, not something specific to files alone.