These docs are under active development and cover the v0.20 Kobicha security model.
On this page
§3.1

SD Structure

A Security Descriptor (SD) defines the complete security policy for a protected object. Every protected object in Peios -- every file, registry key, IPC endpoint, service, token, and process -- MUST have exactly one Security Descriptor. An object MUST NOT carry multiple SDs; the SD is the single authoritative security policy for the object.

An SD has four components and a set of control flags:

  • Owner SID — the principal that owns the object. The owner has implicit rights (READ_CONTROL and WRITE_DAC) unless suppressed by an OWNER RIGHTS ACE.

  • Group SID — a primary group associated with the object. Stored and returned on query, used during CREATOR GROUP substitution during inheritance, but no access control decision depends on it directly.

  • DACL (Discretionary Access Control List) — an ordered list of ACEs that define who is allowed or denied access. The object's owner controls the DACL (via WRITE_DAC).

  • SACL (System Access Control List) — an ordered list of ACEs that define system-level policy. Despite the name, the SACL carries several distinct ACE types:

    • Audit ACEs — which access attempts to log.
    • Mandatory label ACE — the object's integrity level for MIC.
    • Resource attribute ACEs — name-value attributes for conditional ACE evaluation.
    • Scoped policy ID ACEs — references to central access policies.
    • Process trust label ACE — the object's PIP trust level.

    Modifying the SACL requires ACCESS_SYSTEM_SECURITY, which in turn requires SeSecurityPrivilege.

Both the DACL and SACL use the standard binary ACL format defined in the ACL Format section.

§3.1.1 Binary format

SDs use the self-relative binary format defined in MS-DTYP section 2.4.6. The format is a 20-byte header followed by the owner SID, group SID, SACL, and DACL at offsets specified in the header.

Offset Size Field
0 1 Revision (MUST be 1)
1 1 Reserved. Preserved for format compatibility but not interpreted by KACS. When SE_RM_CONTROL_VALID is set in the control flags, this byte carries resource manager control bits defined by the originating system.
2 2 Control flags (little-endian)
4 4 Offset to owner SID (little-endian, 0 if absent)
8 4 Offset to group SID (little-endian, 0 if absent)
12 4 Offset to SACL (little-endian, 0 if absent)
16 4 Offset to DACL (little-endian, 0 if absent)

The self-relative format packs everything into a contiguous byte buffer with no pointers. This makes it suitable for storage (xattrs, database fields) and wire transmission (IPC, SMB).

KACS MUST use the self-relative format exclusively.

§3.1.2 Control flags

The SD's 16-bit Control field records metadata about the descriptor:

Flag Bit Value Description
SE_OWNER_DEFAULTED (OD) 0 0x0001 The owner was established by default means.
SE_GROUP_DEFAULTED (GD) 1 0x0002 The group was established by default means.
SE_DACL_PRESENT (DP) 2 0x0004 A DACL is present. If clear, AccessCheck treats the DACL as null (grants all access).
SE_DACL_DEFAULTED (DD) 3 0x0008 The DACL was established by default means.
SE_SACL_PRESENT (SP) 4 0x0010 A SACL is present.
SE_SACL_DEFAULTED (SD) 5 0x0020 The SACL was established by default means.
SE_DACL_TRUSTED (DT) 6 0x0040 Reserved. Preserved during round-trip serialization. No operational semantics in v0.22.
SE_SERVER_SECURITY (SS) 7 0x0080 When set on a creator SD, the inheritance algorithm appends server ACEs from the caller's primary token's default DACL. See the inheritance section.
SE_DACL_AUTO_INHERIT_REQ (AR) 8 0x0100 Requests that the DACL be auto-inherited from the parent. When clear on a creator SD, parent inheritance is suppressed even if SE_DACL_PROTECTED is not set.
SE_SACL_AUTO_INHERIT_REQ 9 0x0200 Requests that the SACL be auto-inherited from the parent. Same semantics as bit 8 for the SACL.
SE_DACL_AUTO_INHERITED (DI) 10 0x0400 The DACL was created through automatic inheritance.
SE_SACL_AUTO_INHERITED (SI) 11 0x0800 The SACL was created through automatic inheritance.
SE_DACL_PROTECTED (PD) 12 0x1000 The DACL is protected from inheritance. Inheritable ACEs from parent objects MUST NOT be merged.
SE_SACL_PROTECTED (PS) 13 0x2000 The SACL is protected from inheritance.
SE_RM_CONTROL_VALID (RM) 14 0x4000 The Sbz1 byte is interpreted as resource manager control bits.
SE_SELF_RELATIVE (SR) 15 0x8000 The SD is in self-relative format. MUST always be set for stored SDs.

The architectural maximum SD size is 64 KB (constrained by the ACL header's 16-bit AclSize field).

The PROTECTED flags are operationally significant. Setting SE_DACL_PROTECTED prevents inheritance from parent objects -- the object keeps its current ACEs and stops accepting new inheritable ACEs from above.

§3.1.3 Null DACL vs empty DACL

The SE_DACL_PRESENT flag distinguishes two states with very different security consequences:

  • Null DACL (SE_DACL_PRESENT not set) — no discretionary access control. AccessCheck grants all requested access to every caller. This SHOULD almost never be used.

  • Empty DACL (SE_DACL_PRESENT set, zero ACEs) — AccessCheck grants no access to any caller (except the owner's implicit rights). An explicit statement that no principal has discretionary access.

Objects SHOULD always have a DACL. The SD creation algorithm ensures every new object receives one.