# 5.5 lcs.audit.key.descriptor.changed

_Peios / Using Peios / Events / Registry Events_

> The record that a registry key's security descriptor was changed through a key handle, or that an attempt failed.

- **Event type:** `lcs.audit.key.descriptor.changed`
- **Defined in:** `lcs.evman`
- **Tier:** essential
- **Gating:** always when the change includes the SACL; otherwise WRITE_DAC or WRITE_OWNER overlaps the alarm mask cached on the key handle
- **Cardinality:** once per descriptor change it covers

The record that a registry key's security descriptor was changed through a
key handle, or that an attempt failed.

**A change to the SACL is always recorded**, whatever the handle's mask.
It takes `ACCESS_SYSTEM_SECURITY`, which only `SeSecurityPrivilege` grants,
such changes are rare, and removing a SACL is exactly how someone hides
what follows. It is recorded once the handle's own access check admits it:
a caller whose handle lacks `ACCESS_SYSTEM_SECURITY` is refused before any
record, so asking for a SACL change cannot be used to write records.
Owner, group and DACL changes follow the handle's mask, as writes do.

Both descriptors are recorded by length, SHA-256 digest and owner, never
in full. Whether the SACL was part of the change is
`object.sd.components`.

## 5.5.1 Fields

| Field | Type | Presence | Meaning |
|---|---|---|---|
| [`subject.token.sid`](/peios/using-peios/events/field-index/fields-subject.md#subject.token.sid) | `bin.sid` | via [`caller`](/peios/using-peios/events/groups/group-caller.md) | The user SID of the effective token the operation ran under. |
| [`subject.token.integrity`](/peios/using-peios/events/field-index/fields-subject.md#subject.token.integrity) | `uint.integrity` | via [`caller`](/peios/using-peios/events/groups/group-caller.md) | The integrity RID of the effective token. |
| [`subject.token.id`](/peios/using-peios/events/field-index/fields-subject.md#subject.token.id) | `uint.luid` | via [`caller`](/peios/using-peios/events/groups/group-caller.md) | The token's own LUID, identifying this specific token rather than the logon session it belongs to. |
| [`subject.token.auth-id`](/peios/using-peios/events/field-index/fields-subject.md#subject.token.auth-id) | `uint.luid` | via [`caller`](/peios/using-peios/events/groups/group-caller.md) | The LUID of the logon session the effective token belongs to. |
| [`subject.token.type`](/peios/using-peios/events/field-index/fields-subject.md#subject.token.type) | `str.enum` | via [`caller`](/peios/using-peios/events/groups/group-caller.md) | Whether the effective token is a primary token or an impersonation token. |
| [`subject.token.impersonation`](/peios/using-peios/events/field-index/fields-subject.md#subject.token.impersonation) | `uint.enum` | via [`caller`](/peios/using-peios/events/groups/group-caller.md) | The impersonation level of the effective token. |
| [`object.kind`](/peios/using-peios/events/field-index/fields-object.md#object.kind) | `str.enum` | required | Always `key`. |
| [`object.key.guid`](/peios/using-peios/events/field-index/fields-object.md#object.key.guid) | `bin.guid` | required | The registry key an operation acted on. |
| [`object.key.path`](/peios/using-peios/events/field-index/fields-object.md#object.key.path) | `str` | required | The resolved absolute path of the registry key, in canonical form, such as `Machine\System\KMES`. |
| [`object.sd.components`](/peios/using-peios/events/field-index/fields-object.md#object.sd.components) | `uint.flags` | required | The parts the caller asked to change, its `security_info`. |
| [`object.sd.length`](/peios/using-peios/events/field-index/fields-object.md#object.sd.length) | `uint.bytes` | optional | The descriptor as written: the merge of the caller's parts into the old one. Absent when the request failed before the merge. |
| [`object.sd.length-previous`](/peios/using-peios/events/field-index/fields-object.md#object.sd.length-previous) | `uint.bytes` | optional | Absent when the request failed before the old descriptor was read. |
| [`object.sd.digest`](/peios/using-peios/events/field-index/fields-object.md#object.sd.digest) | `bin` | optional | Present with `object.sd.length`. |
| [`object.sd.digest-previous`](/peios/using-peios/events/field-index/fields-object.md#object.sd.digest-previous) | `bin` | optional | Present with `object.sd.length-previous`. |
| [`object.sd.owner`](/peios/using-peios/events/field-index/fields-object.md#object.sd.owner) | `bin.sid` | optional | Present with `object.sd.length`. |
| [`object.sd.owner-previous`](/peios/using-peios/events/field-index/fields-object.md#object.sd.owner-previous) | `bin.sid` | optional | Present with `object.sd.length-previous`. |
| [`access.requested`](/peios/using-peios/events/field-index/fields-access.md#access.requested) | `uint.mask` | required | The rights the change needs: `WRITE_OWNER` for the owner or group, `WRITE_DAC` for the DACL, `ACCESS_SYSTEM_SECURITY` for the SACL. |
| [`access.granted`](/peios/using-peios/events/field-index/fields-access.md#access.granted) | `uint.mask` | required | The access mask in force. |
| [`access.matched`](/peios/using-peios/events/field-index/fields-access.md#access.matched) | `uint.mask` | required | Zero when the record exists only because the change included the SACL. |
| [`access.audit-mask`](/peios/using-peios/events/field-index/fields-access.md#access.audit-mask) | `uint.mask` | required | The full continuous-audit mask cached on a handle, of which `access.matched` is the part this operation touched. |
| [`transaction.id`](/peios/using-peios/events/field-index/fields-transaction.md#transaction.id) | `uint` | optional | The transaction the operation belonged to, registry or package. |
| [`request.timed-out`](/peios/using-peios/events/field-index/fields-request.md#request.timed-out) | `bool` | when `outcome.success == false` | True when the source did not answer in time, so the change may have been applied after all. |
| [`outcome.success`](/peios/using-peios/events/field-index/fields-outcome.md#outcome.success) | `bool` | required | Whether the operation succeeded. |
| [`outcome.errno`](/peios/using-peios/events/field-index/fields-outcome.md#outcome.errno) | `int.errno` | when `outcome.success == false` | The error the operation failed with, as a negative errno. |

Every record also carries the header fields of [the envelope](/peios/using-peios/events/introduction/the-envelope.md), which no payload repeats.

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