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 #
| Field | Type | Presence | Meaning |
|---|---|---|---|
subject.token.sid | bin.sid | via subject | The user SID of the effective token the operation ran under. |
subject.token.groups | bin.sid[] | via subject | The group SIDs carried by the effective token. |
subject.token.group-attributes | uint.flags[] | via subject | Per-group attribute bitmasks, positionally parallel to subject.token.groups. |
subject.token.integrity | uint.integrity | via subject | The integrity RID of the effective token. |
subject.token.id | uint.luid | via subject | The token's own LUID, identifying this specific token rather than the logon session it belongs to. |
subject.token.auth-id | uint.luid | via subject | The LUID of the logon session the effective token belongs to. |
subject.token.type | str.enum | via subject | Whether the effective token is a primary token or an impersonation token. |
subject.token.impersonation | uint.enum | via subject | The impersonation level of the effective token. |
subject.token.uid | uint | via subject | The Linux UID this token projects onto, for correlating a Peios event with Linux-side audit data. |
emitter.process.pid | uint | via subject | The process ID the record was written from. |
emitter.process.name | str | via subject | The kernel's name for the emitting process, typically the executable's basename. |
emitter.process.executable | str.path | via subject | The path the emitting process was executed from, resolved at exec with symbolic links already followed. |
subject.pip.type | uint.enum | via subject | The Protected Isolated Process type in force for the access check. |
subject.pip.trust | uint | via subject | The PIP trust level in force for the access check. |
object.kind | str.enum | required | What sort of thing the operation acted on. |
object.file.path | str.path | when object.kind == file | The absolute path of the file the operation acted on, resolved at the enforcement point. |
object.process.pid | uint | when object.kind == process | The process ID of the process the operation acted on. |
object.process.guid | bin.guid | when object.kind == process | The durable GUID of the process the operation acted on. |
object.token.id | uint.luid | when object.kind == token | The LUID of the token the operation acted on, for token-open and token-adjust checks. |
object.token.guid | bin.guid | when object.kind == token | The durable GUID of the token the operation acted on. |
access.requested | uint.mask | required | The access mask the caller asked for, after generic bits have been mapped to type-specific ones. |
access.granted | uint.mask | required | The mask this check granted. |
access.denied-integrity | uint.mask | optional | The 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-trust | uint.mask | optional | The requested bits the object's process-trust label withheld, read the same way. |
outcome.success | bool | required | True 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.kind | str.enum | required | Why an audit record exists at all. |
trigger.ace | bin.ace | when trigger.kind == sacl | The exact ACE that caused this record, so a consumer can identify which rule fired. |
fields.attestation.userspace | bool | optional | Set 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.