5.4 ACE Types

An Access Control Entry (ACE) is a single rule in an ACL. Each ACE has a header, an access mask, and a principal SID, with optional extensions for object-type and conditional ACEs.

5.4.1 ACE header #

Every ACE begins with a 4-byte header:

OffsetSizeFieldDescription
01AceTypeIdentifies the ACE type.
11AceFlagsInheritance and audit flags.
22AceSizeTotal size of the ACE in bytes, including the header. MUST be a multiple of 4.

5.4.2 ACE body layouts #

The ACE header is followed by a type-specific body. Every multibyte integer in the body is little-endian.

5.4.2.1 Single-SID ACE family #

The following ACE types share the same binary layout:

  • ACCESS_ALLOWED_ACE
  • ACCESS_DENIED_ACE
  • SYSTEM_AUDIT_ACE
  • SYSTEM_ALARM_ACE
  • SYSTEM_MANDATORY_LABEL_ACE
  • SYSTEM_SCOPED_POLICY_ID_ACE
  • SYSTEM_PROCESS_TRUST_LABEL_ACE

Layout:

OffsetSizeFieldDescription
04AceHeaderStandard ACE header.
44MaskAccess mask.
8variableSidPrincipal SID. Consumes the remainder of the ACE.

Parsing rules:

  • AceSize MUST be at least 16 bytes (header + mask + minimum SID).
  • The SID MUST consume the remainder of the ACE exactly.

5.4.2.2 Object ACE family #

The following ACE types share the object-ACE binary layout:

  • ACCESS_ALLOWED_OBJECT_ACE
  • ACCESS_DENIED_OBJECT_ACE
  • SYSTEM_AUDIT_OBJECT_ACE
  • SYSTEM_ALARM_OBJECT_ACE

Layout:

OffsetSizeFieldDescription
04AceHeaderStandard ACE header.
44MaskAccess mask.
84FlagsBitfield describing which GUIDs are present.
120 or 16ObjectTypePresent when ACE_OBJECT_TYPE_PRESENT is set.
12 or 280 or 16InheritedObjectTypePresent when ACE_INHERITED_OBJECT_TYPE_PRESENT is set.
variablevariableSidPrincipal SID. Begins immediately after the optional GUID fields and consumes the remainder of the ACE.

Object ACE flags:

FlagValueDescription
ACE_OBJECT_TYPE_PRESENT0x00000001ObjectType GUID is present.
ACE_INHERITED_OBJECT_TYPE_PRESENT0x00000002InheritedObjectType GUID is present.

Parsing rules:

  • AceSize MUST be large enough to contain the header, mask, flags, all GUIDs selected by Flags, and a complete SID.
  • Unknown bits in Flags MUST be ignored.
  • If neither GUID-presence bit is set, the ACE has no GUID fields and behaves like the corresponding basic ACE.
  • GUID fields are opaque 16-byte values at this layer. Their interpretation is described in the Peios Kernel TRM §3.8.5.

5.4.2.3 Callback ACE family #

The following ACE types extend the corresponding non-callback ACE layout by appending ApplicationData at the end of the ACE:

  • ACCESS_ALLOWED_CALLBACK_ACE
  • ACCESS_DENIED_CALLBACK_ACE
  • SYSTEM_AUDIT_CALLBACK_ACE
  • SYSTEM_ALARM_CALLBACK_ACE
  • ACCESS_ALLOWED_CALLBACK_OBJECT_ACE
  • ACCESS_DENIED_CALLBACK_OBJECT_ACE
  • SYSTEM_AUDIT_CALLBACK_OBJECT_ACE
  • SYSTEM_ALARM_CALLBACK_OBJECT_ACE

For non-object callback ACEs, the body layout is:

OffsetSizeFieldDescription
04AceHeaderStandard ACE header.
44MaskAccess mask.
8variableSidPrincipal SID.
variablevariableApplicationDataTrailing type-specific bytes. Consumes the remainder of the ACE.

For callback object ACEs, the body layout is:

OffsetSizeFieldDescription
04AceHeaderStandard ACE header.
44MaskAccess mask.
84FlagsObject ACE flags.
120 or 16ObjectTypePresent when ACE_OBJECT_TYPE_PRESENT is set.
12 or 280 or 16InheritedObjectTypePresent when ACE_INHERITED_OBJECT_TYPE_PRESENT is set.
variablevariableSidPrincipal SID.
variablevariableApplicationDataTrailing type-specific bytes. Consumes the remainder of the ACE.

Parsing rules:

  • The SID begins after the fixed fields and any optional GUIDs, exactly as in the corresponding non-callback ACE family.
  • ApplicationData MAY be empty. Semantics for empty or malformed callback payloads are defined by the relevant subsystem.
  • For conditional ACEs, ApplicationData carries the conditional expression bytecode defined in the Conditional ACE Bytecode Reference.

5.4.2.4 Resource attribute ACE #

SYSTEM_RESOURCE_ATTRIBUTE_ACE uses the single-SID ACE prefix followed by trailing application data:

OffsetSizeFieldDescription
04AceHeaderStandard ACE header.
44MaskReserved for compatibility. Not used for access decisions.
8variableSidMUST be Everyone (S-1-1-0).
variablevariableApplicationDataOne claim entry using §5.9. Consumes the remainder of the ACE.

Parsing rules:

  • The SID MUST be Everyone.
  • ApplicationData MUST contain exactly one claim entry using §5.9.

5.4.3 DACL ACE types #

5.4.3.1 Basic ACEs #

StructureValueEffect
ACCESS_ALLOWED_ACE0x00Grants the specified rights to the SID.
ACCESS_DENIED_ACE0x01Denies the specified rights to the SID.

5.4.3.2 Object-type ACEs #

Extend basic ACEs with one or two GUIDs that scope the rule to a specific property or object class. Used for Active Directory access control.

StructureValueEffect
ACCESS_ALLOWED_OBJECT_ACE0x05Grants rights scoped to a property/class GUID.
ACCESS_DENIED_OBJECT_ACE0x06Denies rights scoped to a property/class GUID.

The ObjectType GUID identifies the property or property set the ACE applies to. The InheritedObjectType GUID restricts inheritance to child objects of a specific class. Either or both GUIDs MAY be absent (indicated by a flags field), in which case the ACE behaves like a basic ACE for that dimension.

5.4.3.3 Conditional ACEs #

Extend basic and object-type ACEs with a conditional expression. The ACE only takes effect if the expression evaluates to TRUE against the caller's token attributes and the object's resource attributes.

StructureValueEffect
ACCESS_ALLOWED_CALLBACK_ACE0x09Conditional allow.
ACCESS_DENIED_CALLBACK_ACE0x0AConditional deny.
ACCESS_ALLOWED_CALLBACK_OBJECT_ACE0x0BConditional allow, scoped to GUID.
ACCESS_DENIED_CALLBACK_OBJECT_ACE0x0CConditional deny, scoped to GUID.

5.4.4 SACL ACE types #

5.4.4.1 Audit ACEs #

Trigger audit log entries when matching access attempts occur. The AceFlags field carries SUCCESSFUL_ACCESS_ACE_FLAG (0x40) and/or FAILED_ACCESS_ACE_FLAG (0x80).

StructureValueEffect
SYSTEM_AUDIT_ACE0x02Audit access matching the SID and mask.
SYSTEM_AUDIT_OBJECT_ACE0x07Audit access scoped to a GUID.
SYSTEM_AUDIT_CALLBACK_ACE0x0DConditional audit.
SYSTEM_AUDIT_CALLBACK_OBJECT_ACE0x0FConditional audit, scoped to GUID.

5.4.4.2 Alarm ACEs (continuous auditing) #

StructureValueEffect
SYSTEM_ALARM_ACE0x03Continuous audit for matching SID and mask.
SYSTEM_ALARM_OBJECT_ACE0x08Continuous audit scoped to a GUID.
SYSTEM_ALARM_CALLBACK_ACE0x0EConditional continuous audit.
SYSTEM_ALARM_CALLBACK_OBJECT_ACE0x10Conditional continuous audit, scoped to GUID.

5.4.4.3 Mandatory label ACE #

Defines the object's integrity level for MIC. Conforming producers SHOULD emit at most one non-inherit-only mandatory-label ACE per SACL. Imported or existing SACLs MAY contain multiple mandatory-label ACEs; MIC uses the first non-inherit-only mandatory-label ACE as described in the Peios Kernel TRM §3.8.3. Inherit-only mandatory-label ACEs do not apply to the current object. The SID encodes the integrity level. The access mask encodes the MIC policy (which operations are blocked for non-dominant callers).

StructureValueEffect
SYSTEM_MANDATORY_LABEL_ACE0x11Sets the object's integrity level and MIC policy.

5.4.4.4 Resource attribute ACE #

Attaches name-value attributes to the object for conditional ACE evaluation. The ACE's SID is always Everyone (S-1-1-0).

StructureValueEffect
SYSTEM_RESOURCE_ATTRIBUTE_ACE0x12Defines a resource attribute on the object.

5.4.4.5 Scoped policy ID ACE #

References a central access policy by SID. During AccessCheck, the referenced policy's rules are evaluated in addition to the object's own DACL.

StructureValueEffect
SYSTEM_SCOPED_POLICY_ID_ACE0x13References a central access policy.

5.4.4.6 Process trust label ACE #

Defines the object's PIP trust level. The SID encodes the PIP type and trust level. The access mask specifies the exact rights that non-dominant callers are allowed.

StructureValueEffect
SYSTEM_PROCESS_TRUST_LABEL_ACE0x14Sets the object's PIP trust level.

5.4.5 Allocated but unimplemented ACE types #

Two values in the range have a name but no KACS behaviour.

StructureValueNotes
ACCESS_ALLOWED_COMPOUND_ACE0x04Never implemented. Reserved.
SYSTEM_ACCESS_FILTER_ACE0x15Defined by MS-DTYP. Named by the KACS ABI for format parity; no KACS semantics.

ACCESS_ALLOWED_COMPOUND_ACE was specified and then abandoned before any conforming system implemented it. Nothing produces it.

SYSTEM_ACCESS_FILTER_ACE is different: it is a live MS-DTYP ACE type that KACS has not implemented. The kernel ABI defines a constant for it (KACS_ACE_TYPE_SYSTEM_ACCESS_FILTER) so that a decoder can put a name to the byte, but no section of this specification assigns it meaning. A 0x15 ACE therefore takes the unrecognised-ACE path described at the end of this section: skipped during evaluation, preserved byte-for-byte on round-trip. An implementation MUST NOT grant, deny, audit, or filter access on the basis of a 0x15 ACE.

Values above 0x15 are unallocated.

5.4.6 AceType constants #

The tables above name each ACE structure. The AceType header field carries a constant with its own name, which is what a reader decoding a descriptor by hand will be holding. Both spellings, in value order:

ValueAceType constantStructure
0x00ACCESS_ALLOWED_ACE_TYPEACCESS_ALLOWED_ACE
0x01ACCESS_DENIED_ACE_TYPEACCESS_DENIED_ACE
0x02SYSTEM_AUDIT_ACE_TYPESYSTEM_AUDIT_ACE
0x03SYSTEM_ALARM_ACE_TYPESYSTEM_ALARM_ACE
0x04ACCESS_ALLOWED_COMPOUND_ACE_TYPEACCESS_ALLOWED_COMPOUND_ACE
0x05ACCESS_ALLOWED_OBJECT_ACE_TYPEACCESS_ALLOWED_OBJECT_ACE
0x06ACCESS_DENIED_OBJECT_ACE_TYPEACCESS_DENIED_OBJECT_ACE
0x07SYSTEM_AUDIT_OBJECT_ACE_TYPESYSTEM_AUDIT_OBJECT_ACE
0x08SYSTEM_ALARM_OBJECT_ACE_TYPESYSTEM_ALARM_OBJECT_ACE
0x09ACCESS_ALLOWED_CALLBACK_ACE_TYPEACCESS_ALLOWED_CALLBACK_ACE
0x0AACCESS_DENIED_CALLBACK_ACE_TYPEACCESS_DENIED_CALLBACK_ACE
0x0BACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPEACCESS_ALLOWED_CALLBACK_OBJECT_ACE
0x0CACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPEACCESS_DENIED_CALLBACK_OBJECT_ACE
0x0DSYSTEM_AUDIT_CALLBACK_ACE_TYPESYSTEM_AUDIT_CALLBACK_ACE
0x0ESYSTEM_ALARM_CALLBACK_ACE_TYPESYSTEM_ALARM_CALLBACK_ACE
0x0FSYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPESYSTEM_AUDIT_CALLBACK_OBJECT_ACE
0x10SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPESYSTEM_ALARM_CALLBACK_OBJECT_ACE
0x11SYSTEM_MANDATORY_LABEL_ACE_TYPESYSTEM_MANDATORY_LABEL_ACE
0x12SYSTEM_RESOURCE_ATTRIBUTE_ACE_TYPESYSTEM_RESOURCE_ATTRIBUTE_ACE
0x13SYSTEM_SCOPED_POLICY_ID_ACE_TYPESYSTEM_SCOPED_POLICY_ID_ACE
0x14SYSTEM_PROCESS_TRUST_LABEL_ACE_TYPESYSTEM_PROCESS_TRUST_LABEL_ACE
0x15SYSTEM_ACCESS_FILTER_ACE_TYPESYSTEM_ACCESS_FILTER_ACE

5.4.7 ACL revision #

ACLs carry a revision number that constrains which ACE types MAY appear:

  • ACL_REVISION (0x02) — basic ACE types (0x00, 0x01, 0x02, 0x03), mandatory label (0x11), resource attribute (0x12), scoped policy (0x13), and process trust label (0x14).
  • ACL_REVISION_DS (0x04) — additionally permits object-type ACEs (0x05–0x08), callback ACEs (0x09–0x0C, 0x0D–0x10). Required for Active Directory access control.

When creating new ACLs containing only recognised ACE types, the revision MUST be set to the minimum required by the ACE types present. When rewriting an existing ACL while preserving one or more unrecognised ACE types, KACS MUST set the revision to the greater of the minimum required by recognised ACE types present and the source ACL revision. When parsing ACLs, KACS MUST NOT reject an ACL based on revision-vs-ACE-type mismatch — accept permissively, write correctly.

Unrecognised ACE types — every value not given semantics above, which today means 0x04, 0x15, and everything from 0x16 up — MUST be silently skipped during evaluation and preserved byte-for-byte during round-trip serialisation. The ACE's raw bytes (from AceType through AceType + AceSize) are stored opaquely and written back unchanged. ACEs with AceSize not a multiple of 4 MUST be rejected (the containing ACL is malformed).

Edit this page