3.1 kacs.audit.access.checked

  • Event type: kacs.audit.access.checked
  • Defined in: kacs.evman
  • Tier: essential
  • Gating: a matching SACL audit ACE, or the token's audit policy; on the AccessCheck syscall a SACL record also needs the caller to hold SeAuditPrivilege, enabled
  • Cardinality: once per matching audit ACE, not once per access

The record that an access check completed, and what it decided. The most common event on the system, and the one most investigations start from.

A daemon's own checks need SeAuditPrivilege. A userspace component that guards its objects with the AccessCheck syscall supplies the descriptor itself, SACL included. Its records are written only if the calling process holds SeAuditPrivilege, enabled, on its effective token, as Windows asks of AccessCheckAndAuditAlarm; without it the check is answered and its SACL records are silently withheld. The privilege is the caller's, not the checked client's. Records the checked token's own audit policy forces are written either way.

It fires against every kind of object KACS protects — files, processes, tokens, sockets and SysV IPC objects — which is why object.kind is required. A process opening another process, or a token adjusting another token, puts an actor and an object of the same kind in one record, so the subject. and object. fields are never interchangeable.

It is silent by default. Nothing is recorded unless an audit ACE in the object's SACL matches, or the calling token's audit policy forces it. An object with no SACL produces no record on any outcome, including denials.

One access can produce several records. The event is per matching audit ACE, so an access matching three ACEs produces three records differing only in trigger.ace.

3.1.1 Fields #

FieldTypePresenceMeaning
subject.token.sidbin.sidvia subjectThe user SID of the effective token the operation ran under.
subject.token.groupsbin.sid[]via subjectThe group SIDs carried by the effective token.
subject.token.group-attributesuint.flags[]via subjectPer-group attribute bitmasks, positionally parallel to subject.token.groups.
subject.token.integrityuint.integrityvia subjectThe integrity RID of the effective token.
subject.token.iduint.luidvia subjectThe token's own LUID, identifying this specific token rather than the logon session it belongs to.
subject.token.auth-iduint.luidvia subjectThe LUID of the logon session the effective token belongs to.
subject.token.typestr.enumvia subjectWhether the effective token is a primary token or an impersonation token.
subject.token.impersonationuint.enumvia subjectThe impersonation level of the effective token.
subject.token.uiduintvia subjectThe Linux UID this token projects onto, for correlating a Peios event with Linux-side audit data.
emitter.process.piduintvia subjectThe process ID the record was written from.
emitter.process.namestrvia subjectThe kernel's name for the emitting process, typically the executable's basename.
emitter.process.executablestr.pathvia subjectThe path the emitting process was executed from, resolved at exec with symbolic links already followed.
subject.pip.typeuint.enumvia subjectThe Protected Isolated Process type in force for the access check.
subject.pip.trustuintvia subjectThe PIP trust level in force for the access check.
object.kindstr.enumrequiredWhat sort of thing the operation acted on.
object.file.pathstr.pathwhen object.kind == fileThe absolute path of the file the operation acted on, resolved at the enforcement point.
object.process.piduintwhen object.kind == processThe process ID of the process the operation acted on.
object.process.guidbin.guidwhen object.kind == processThe durable GUID of the process the operation acted on.
object.token.iduint.luidwhen object.kind == tokenThe LUID of the token the operation acted on, for token-open and token-adjust checks.
object.token.guidbin.guidwhen object.kind == tokenThe durable GUID of the token the operation acted on.
access.requesteduint.maskrequiredThe access mask the caller asked for, after generic bits have been mapped to type-specific ones.
access.granteduint.maskrequiredThe mask this check granted.
access.denied-integrityuint.maskoptionalThe requested bits the object's mandatory label withheld — every bit it withheld, for MAXIMUM_ALLOWED. Absent when it withheld none. With access.denied-trust, often the whole explanation of a denial the DACL alone would have allowed.
access.denied-trustuint.maskoptionalThe requested bits the object's process-trust label withheld, read the same way.
outcome.successboolrequiredTrue when every requested bit is in access.granted. A MAXIMUM_ALLOWED request always reports true, because such a request returns whatever is available and cannot fail — so a success rate computed over these records is skewed by them.
trigger.kindstr.enumrequiredWhy an audit record exists at all.
trigger.acebin.acewhen trigger.kind == saclThe exact ACE that caused this record, so a consumer can identify which rule fired.
fields.attestation.userspacebooloptionalSet on every record of the AccessCheck syscall, and on no other. There the descriptor, and with it trigger.ace, is always the caller's, as are any audit context and PIP state it passes.

Every record also carries the header fields of the envelope, which no payload repeats.

Generated from kacs.evman by pkm/tools/gen-events-book.py. Edit the fragment, not this page.

Edit this page