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

Token Lifecycle

§4.3.1 Fork and clone

All process and thread creation paths go through clone(). KACS branches on the CLONE_THREAD flag.

§4.3.1.1 Clone without CLONE_THREAD (fork, vfork)

New process. The child MUST receive an independent deep copy of the parent's primary token. If the parent is impersonating, the impersonation token MUST NOT be inherited — the child's effective credential is set from real_cred.

After fork, mutations to either token (parent or child) are invisible to the other.

§4.3.1.2 Clone with CLONE_THREAD

New thread. Threads share the parent's real_cred (reference-counted), and therefore share the same primary token object. Privilege adjustments on the primary token are visible to all threads. Each thread maintains independent impersonation state via its own cred.

If the cloning thread is impersonating at the time of clone(CLONE_THREAD), the impersonation token MUST NOT become the new thread's primary or effective identity. The new thread starts with the shared primary token as both objective and effective identity. It may later impersonate independently through the normal impersonation APIs.

§4.3.1.3 Exec

The primary token survives execve() unchanged, with one exception: the NEW_PROCESS_MIN mechanism (below).

If the calling thread is impersonating, impersonation MUST be reverted before the new program runs. The new program always starts with the primary token as its effective identity.

Token assignment for services happens between fork and exec: peinit forks, installs the service's token on the child, then the child execs the service binary.

§4.3.2 Self-install of a primary token

KACS_IOC_INSTALL commits a new primary token on the calling process. The operation is process-wide: the kernel replaces the primary token for the entire current thread group, not only for the calling thread.

If a thread is not impersonating, both real_cred and cred switch to the new primary token. If a thread is currently impersonating, the replacement affects real_cred only; the active impersonation remains in cred until revert or exec. Reverting after install restores the thread to the new primary token, not the old one.

The calling thread performs its install immediately. Sibling threads in the same thread group converge in their own context via queued in-kernel credential work; there is no atomic all-threads-at-once swap requirement. During this brief transition window, some sibling threads MAY still observe the old primary token until they execute their queued install work. No completion barrier is exposed to the caller.

If the installed token's user SID differs from the old primary token's user SID, the process SD is regenerated from the default template for the new primary token. Otherwise the existing process SD is preserved.

§4.3.2.1 NEW_PROCESS_MIN

If the token's mandatory_policy includes NEW_PROCESS_MIN, the kernel MUST replace the child's primary token at exec time when the executable has a lower integrity label:

  1. Read the executable file's integrity label from its SD (the mandatory label ACE in the SACL). If the file has no label, use the default (Medium).
  2. If the file's integrity level is lower than the token's integrity level, create a new token following DuplicateToken semantics (new token_id, new token_guid, modified_id initialized to the new token_id, elevation_type reset to Default) with integrity_level set to the file's label. All other fields are copied from the source. The original token is dropped.
  3. If the file's integrity level is greater than or equal to the token's integrity level, no action — the token survives exec unchanged.

NEW_PROCESS_MIN can only lower integrity, never raise it. The child's integrity level is always less than or equal to the parent's. The flag is immutable on the token.

§4.3.3 Bootstrap

The SYSTEM token (S-1-5-18) is created by PKM during kernel initialization, before any userspace process exists. It is hardcoded:

  • User SID: S-1-5-18 (Local System)
  • Groups: S-1-5-32-544 (BUILTIN\Administrators), S-1-1-0 (Everyone), S-1-5-11 (Authenticated Users), and other well-known SIDs
  • Privileges: all defined privileges, present and enabled
  • Integrity level: System
  • Token type: Primary
  • Elevation type: Default (no linked token)
  • Token source: PeiosKrn
  • Projected UID: 0

The SYSTEM token is assigned to the kernel's init task and inherited by PID 1 on exec. No syscall is involved — the kernel allocates the token object directly during initialization.

The Anonymous token (S-1-5-7) is also created by PKM during kernel initialization as the canonical socket-impersonation Anonymous shape:

  • User SID: S-1-5-7 (Anonymous)
  • Groups: Everyone (S-1-1-0) only
  • Privileges: none
  • Integrity level: Untrusted
  • Logon type: Network
  • Token type: Impersonation
  • Impersonation level: Anonymous
  • Elevation type: Default
  • Token source: PeiosKrn
  • auth_id: ANONYMOUS_LOGON_LUID (998 / 0x3E6)

Socket-based Anonymous capture MUST produce this minimal identity shape rather than preserving any part of the caller's real token.

ⓘ Informative
The SYSTEM token carries SeBackupPrivilege and SeRestorePrivilege (present and enabled at boot). FACS passes backup/restore intent flags to AccessCheck, which grants read and write access regardless of file DACLs — subject to PIP enforcement. Once peinit has launched TCB services and early boot is complete, peinit disables these privileges on child service tokens via FilterToken.

§4.3.4 External token replacement

⚠ Warning
External token replacement is not implemented in v0.20. This section defines the intended behaviour for a future release.

A privileged process (peinit) MAY replace the primary token on a running process — for example, downgrading a pre-authd service from SYSTEM to a purpose-built token.

The mechanism uses task_work_add() to queue a credential swap on each task in the target thread group. Each task executes the swap in its own context, preserving RCU safety. If a thread is impersonating, the replacement affects real_cred (primary token) only — the impersonation state is left intact.

This operation is gated by SeAssignPrimaryTokenPrivilege.

ⓘ Informative
The per-thread queuing creates a brief transition window where some threads have the new token while others still have the old one. This is acceptable because replacement is always a privilege downgrade. There is no completion barrier — the caller cannot determine when all threads have executed the swap.
ⓘ Informative
Until external token replacement is implemented, the mitigation for pre-authd services is privilege removal: peinit uses FilterToken to create a copy of the SYSTEM token with dangerous privileges permanently deleted, and assigns this filtered token to the service at launch. The service retains the SYSTEM SID but permanently lacks the ability to exercise privileged operations.