# Inspecting security state

---

# Inspecting security state

_Peios / Using Peios / Inspecting security state_

> Choose a supported read-only view of tokens, sessions, process protection or object policy, and understand what missing or refused information can establish.

Inspection answers a specific question about the running system: who a process
acts as, which session it belongs to, how it is protected, or what policy covers
an object. Start with the supported command or desktop view for that question,
and keep any access refusal or incomplete-view notice with the result.

For a failed operation, start with [Debugging a denial](/peios/using-peios/inspecting/debugging-a-denial.md).
It puts the caller, object and requested action together before interpreting
security state. A token dump alone does not tell you whether access is allowed.

## What you can inspect

These are read-only ways to begin. Replace `PID`, `TID` and `ID` with targets you
have identified, and the example paths with the actual objects.

| Question | Supported view | Interpretation limit |
|---|---|---|
| Which process is involved? | [Task Manager](/peios/using-peios/threads-and-processes/task-manager.md), **Processes** | Some command, owner and protected-process details may be hidden. |
| Who does a process act as, and what is on its token? | [`token show --pid PID --all`](/peios/using-peios/peiosutils/system-and-processes/token.md) | This selects the primary token; a thread may be impersonating. |
| What identity is a thread impersonating? | `token show --pid PID --tid TID --all` | Identify the failing thread and record the time; it may have reverted since the failure. |
| What is this process's protection? | [`logonse psb --pid PID`](/peios/using-peios/peiosutils/system-and-processes/logonse.md#logonse-psb) | The PSB reports PIP, mitigations and process GUID, not its security descriptor. |
| Which logon sessions and processes are visible? | `logonse list`, `logonse show ID`, or Task Manager's **Signed in** | The session list and the visible-process list have different access limits. |
| What rules protect a file? | [`sd show ./report.txt --all`](/peios/using-peios/peiosutils/files-and-directories/sd.md#sd-show) | Queries owner, group, DACL and the label subset, not the full SACL. `--all` adds formatting detail, not audit ACEs or a complete export. |
| What rules protect a registry key? | [`reg sd Machine/App`](/peios/using-peios/peiosutils/registry-tools/reg.md#reg-sd-key) | The default view is owner, group and DACL; SACL reading needs separate authority. |
| What was recorded about an earlier attempt? | [Event Viewer](/peios/using-peios/logs-and-events/event-viewer.md) or [evctl](/peios/advanced-peios/eventd/evctl/using-evctl.md) | Audit policy, reader permissions, query scope, retention and transport all limit the answer. |

For files, `sd check` can explain a simulated access check without performing the
file operation. Read [the rehearsal's limits](/peios/using-peios/inspecting/debugging-a-denial.md#rehearse-a-file-check-within-its-limits)
before treating its result as an explanation of an application's failure.

## Who can inspect what

The tool does not add authority. The underlying surface determines which checks
apply:

- **Another process's token:** `PROCESS_QUERY_INFORMATION` on the process, PIP
  dominance, and `TOKEN_QUERY` on the token's own descriptor. Administrator
  membership does not bypass PIP or a changed token descriptor.
- **Another process's PSB:** `PROCESS_QUERY_LIMITED` on the process descriptor;
  PIP dominance is not required for this view. Seeing its protection does not
  grant access to its token or memory.
- **Another process's descriptor:** `READ_CONTROL` plus PIP dominance for owner,
  group and DACL inspection. SACL inspection additionally needs
  `ACCESS_SYSTEM_SECURITY`. See [Inspecting processes](/peios/advanced-peios/security-diagnostics/processes.md).
- **The kernel's full session listing:** Administrators or SYSTEM, through the
  descriptor on `/sys/kernel/security/kacs/sessions`. `logonse` reports a refusal
  and can fall back to the sessions of processes you may inspect. Even an
  administrator's process list can omit protected processes.

Self-access is surface-specific. The Kernel TRM documents a process opening its
own `/proc` token paths without the cross-process or token-descriptor checks.
Opening its own token through the API still checks the token descriptor; a
changed descriptor can revoke that access. Do not turn the first rule into a
promise that every self-query succeeds. See
[Token access rights](/peios/advanced-peios/peios-kernel/kacs/tokens/access-rights.md).

A refused inspection is a result in its own right. Keep the target, operation
and error; ask an authorised operator or the component owner for the missing
evidence when needed. Do not change permissions, disable protection or adjust a
token just to obtain a fuller report.

## What you cannot inspect

These views have boundaries even when they return successfully:

- **No complete history.** They report current state. A destroyed token cannot
  be recovered from a live query, and an earlier impersonation or privilege
  state may have changed. Use recorded evidence for historical questions.
- **No atomic machine snapshot.** Processes and threads start and exit during a
  listing. Separate token queries can observe adjustments between reads; keep
  the token ID and modification counter where available.
- **No global inventory of every token.** Process-based inspection cannot list
  tokens held only by file descriptors with no running process using them.
- **No implied access verdict.** A token, PSB or descriptor report supplies
  inputs, not the outcome of every possible operation.
- **No inferred absence from a partial view.** Hidden processes, unreadable
  descriptor components and missing audit records remain unknown. A source or
  syscall error is not a successful empty result.

For registry output, use the documented result distinctions: `reg` exit `2`
means a key/value was not found, `3` is access denied, and `5` is another syscall
or source error. An empty value or listing alone is not one of those diagnoses.
See [`reg` exit status](/peios/using-peios/peiosutils/registry-tools/reg.md#exit-status).

## Standard query patterns

**Follow a process to its session.** Find the process in Task Manager, inspect
its primary token, and use the reported logon-session ID with `logonse show ID`.
`token show` labels this `session_id`; in the underlying statistics it is
`auth_id`. It is distinct from `interactivity_scope`. A service's impersonated
request may belong to a different session, so retain which token you inspected.

**Explain why a protected process has limited details.** Read its Protection
field in Task Manager or its PSB with `logonse psb --pid PID`. A visible PSB and
a refused token query can both be correct under the separate access rules.

**Investigate a privilege-related refusal.** Use `token privs --pid PID` for the
primary token, or the documented thread selector when impersonation is involved.
Separate present from enabled; neither proves the application supplied any
required intent or that another policy allowed the operation. Continue with
[Debugging a denial](/peios/using-peios/inspecting/debugging-a-denial.md#privileges).

## Two ways to read a token

For an operator, [`token`](/peios/using-peios/peiosutils/system-and-processes/token.md) opens and queries
the token, then renders readable output. [Inspecting tokens](/peios/using-peios/inspecting/tokens.md)
explains how to select the target and interpret the fields.

For a tool author, token file descriptors and `KACS_IOC_QUERY` expose structured
state. `/proc/<pid>/token` selects the process's primary token;
`/proc/<pid>/task/<tid>/token` selects the thread's effective token. These and
`/sys/kernel/security/kacs/self` provide handles, not text to print with `cat`.
The SDK [token-opening](/peios/developing-for-peios/sdk-reference/sdk-tokens/opening-and-creating-tokens.md) and
[query](/peios/developing-for-peios/sdk-reference/sdk-tokens/query.md) references document the programming interface;
the Kernel TRM [ABI notes](/peios/advanced-peios/peios-kernel/kacs/kacs-abi-notes.md#querying-a-token-handle)
cover the raw query protocol.

Other pseudo-files have different formats: the documented session listing and
`/proc/<pid>/psb` are text. The existence of one text surface does not make token
handles text, or make every surface follow the same access rules.

## Where to start

- [Inspecting tokens](/peios/using-peios/inspecting/tokens.md): choose a token and interpret its
  identity, groups, privileges and restrictions.
- [logonse](/peios/using-peios/peiosutils/system-and-processes/logonse.md) and
  the [session-listing reference](/peios/advanced-peios/security-diagnostics/sessions.md): use the
  command for session reports; consult the reference for the underlying format.
- [Task Manager](/peios/using-peios/threads-and-processes/task-manager.md) and
  the [process-inspection reference](/peios/advanced-peios/security-diagnostics/processes.md): use
  Task Manager for process views; consult the reference for the lower-level surfaces.
- [Debugging a denial](/peios/using-peios/inspecting/debugging-a-denial.md): combine these
  observations with the failed action and object policy.
- [The event stream](/peios/advanced-peios/security-diagnostics/the-event-stream.md): raw transport diagnosis
  when events are not reaching eventd. For ordinary recorded-event inspection,
  use [Event Viewer](/peios/using-peios/logs-and-events/event-viewer.md) or
  [evctl](/peios/advanced-peios/eventd/evctl/using-evctl.md) instead.

---

# Debugging a denial

_Peios / Using Peios / Inspecting security state_

> Diagnose an access refusal with the caller, object and operation in hand, using supported inspection tools, audit evidence and policy-specific next steps.

Start with the operation that failed, then gather the evidence you are allowed
to read. The aim is to explain the refusal and decide whether the caller or the
policy needs review. A refusal can be the intended protection working.

Use the inspection commands below before changing permissions, privileges or
labels. An empty registry result or a missing process detail is not, by itself,
evidence that a particular access-check layer denied the original operation.

## Record the failed operation

Keep these together:

- **What failed and when:** the application's message, error or exit status,
  timestamp, and the action you asked it to perform.
- **The caller:** the application or service, its PID, and the failing thread's
  TID if the application's diagnostics identify it. A service acting for a
  client may be using an impersonation token rather than its primary token.
- **The object:** the exact file path, registry key, process or other resource.
  For a file, establish whether the operation targeted a symbolic link or its
  target. For a registry operation, keep the key and value name separate.
- **The access requested:** read, write, execute, change permissions, or another
  specific operation. Keep the requested access mask when the diagnostic or
  audit record supplies it; an application may ask for more than its visible
  action suggests.
- **The point of failure:** opening an object, using an already-open handle,
  or a service's own authorisation check. These are different questions.

Access is normally decided when a handle is opened. Later operations use the
rights stored on that handle; inspecting today's descriptor does not reconstruct
what an older handle received. See [The decision is made at open](/peios/security-fundamentals/access-decisions/overview.md#the-decision-is-made-at-open-and-it-stays-made).

## Find the thread and its tokens

Use [Task Manager](/peios/using-peios/threads-and-processes/task-manager.md) to find the process
by name, PID, person or service. Check its command, owner, service or job, and
signed-in session where visible. Read any notice about hidden details or
protection before interpreting the view.

In a terminal, use the read-only subcommands of
[`token`](/peios/using-peios/peiosutils/system-and-processes/token.md). Replace `PID` and `TID` with the
identified process and thread:

```console
token show --pid PID --all
token privs --pid PID
token show --pid PID --tid TID --all
```

`--pid` selects the process's **primary** token. The command's `--tid` selector
is for a thread's impersonation token and is used with `--pid`; use it when
investigating impersonation. The identity that matters is the one the failing
thread used: its impersonation token while impersonating, otherwise its primary
token. If that identity is no longer available, record the gap rather than
substituting the inspection tool's own token. Running `token show --all` without
a target shows the tool's own token, not another application's.

The `/proc/<pid>/token`, `/proc/<pid>/task/<tid>/token` and
`/sys/kernel/security/kacs/self` surfaces provide token **handles**, not text to
read with `cat`. The process path identifies the primary token; the thread path
identifies the effective token. The command does the querying and decoding.
[Inspecting tokens](/peios/using-peios/inspecting/tokens.md) documents those interfaces for tool
authors.

Record the user SID, group attributes, token type and impersonation level,
integrity and mandatory policy, present and enabled privileges, restricted SIDs,
and confinement identity and capabilities where available. Keep token and
session IDs with the time of inspection: the thread can revert impersonation,
and token adjustments can change the state after the failure.

For process protection and session context, use
[`logonse`](/peios/using-peios/peiosutils/system-and-processes/logonse.md):

```console
logonse psb --pid PID
logonse list
logonse show ID
```

Here `ID` is the logon-session ID you have identified. `token show` calls it
`session_id`; it is separate from `interactivity_scope`. A PSB report shows
protection, mitigations and the process GUID; it is not the process's security
descriptor.

**Inspection has its own access checks.** Reading another process's token needs
`PROCESS_QUERY_INFORMATION`, PIP dominance, and `TOKEN_QUERY` on the token.
Reading its PSB needs `PROCESS_QUERY_LIMITED` and does not require PIP dominance.
The full kernel session list is restricted to Administrators and SYSTEM;
`logonse` can show a partial process-based view instead. A refused query or an
absent process in that view is a limit on your evidence, not a reason to remove
protection. See [Who can inspect what](/peios/using-peios/inspecting/overview.md#who-can-inspect-what).

## Find the object and its SD

For a file, [`sd show`](/peios/using-peios/peiosutils/files-and-directories/sd.md#sd-show) queries owner,
group, DACL and the integrity-label subset:

```console
sd show ./report.txt --all
```

Replace the example path with the object you identified. `sd` follows a named
symbolic link by default; its documented `--no-follow-symlinks` option selects
the link itself. Inspect the same object the failed operation meant to reach.
`--all` changes formatting, not selection: this view does not include audit
ACEs or the rest of the SACL, and its summaries omit some ACE payload details.
Do not infer that undisplayed policy is absent.

For a registry key, [`reg sd`](/peios/using-peios/peiosutils/registry-tools/reg.md#reg-sd-key) prints owner,
group and DACL by default:

```console
reg sd Machine/App
```

Only when you already have the authority to read the SACL, request it explicitly:

```console
reg sd Machine/App --sacl
```

The full SACL needs `ACCESS_SYSTEM_SECURITY`; the default registry
owner/group/DACL view does not establish which SACL labels or policies exist. Similarly, a refused
`sd show` is a failed inspection, not a decoded explanation of the original
operation. Keep the returned error and the scope of any descriptor you obtained.
For a process's descriptor, use the separate
[process-SD inspection reference](/peios/advanced-peios/security-diagnostics/processes.md#reading-the-process-sd)
with an authorised diagnostic tool; the PSB and a token report do not replace it.

In the parts you can read, look for:

- **Owner and DACL:** the owner SID, ordered allow/deny ACEs, inheritance flags,
  and the SIDs and rights each ACE names. `INHERIT_ONLY` (`IO`) rules apply to
  descendants rather than this object. A non-inherit-only access-control ACE
  naming `OWNER RIGHTS` suppresses the owner's implicit `READ_CONTROL | WRITE_DAC`
  grant.
- **Mandatory label:** the first applicable `SYSTEM_MANDATORY_LABEL_ACE` in the
  SACL and its policy bits.
- **Process-trust label:** an applicable `SYSTEM_PROCESS_TRUST_LABEL_ACE` and
  the rights its mask allows a non-dominant caller.
- **Other policy inputs:** scoped central-policy references
  (`SYSTEM_SCOPED_POLICY_ID_ACE`), resource attributes
  (`SYSTEM_RESOURCE_ATTRIBUTE_ACE`) and conditional ACEs.

A component omitted from your permitted view is unknown, not empty. Reading an
owner or finding one allow ACE is not enough to establish effective access.

## Rehearse a file check, within its limits

For a file, [`sd check`](/peios/using-peios/peiosutils/files-and-directories/sd.md#sd-check) explains a
check without performing the requested file operation:

```console
sd check ./report.txt read --pid PID --explain
```

Choose the documented permission name or mask that matches the failed request.
Without `--pid`, the check uses your own token. Save the explanation and any
error, not just the exit status: a non-zero status can also mean the path was
unreachable or the tool could not complete the check.

Treat this as evidence about the inputs tested. The command documents a process
token selector, not a thread selector or switches for every optional
access-check input. It does not establish that it reproduced a service's
impersonated caller, local claims, backup/restore intent or process-trust context.
It also does not test rights on an existing handle. An allowed rehearsal is not
a guarantee that the application's full operation will succeed. If the result
differs, compare the caller, target, requested rights and timing before changing
policy.

## Check audit evidence

Check the recorded attempt alongside the live state, rather than treating logs
as a last resort. In [Event Viewer](/peios/using-peios/logs-and-events/event-viewer.md), select
the relevant time range and filter **Type** to `kacs.audit.access.checked`.
Select a record to inspect its fields. The terminal route is
[Using evctl](/peios/advanced-peios/eventd/evctl/using-evctl.md).

Correlate the timestamp, emitting process, subject token/session and object
information actually present in the record. The subject is the caller; an
`object.process.*` or `object.token.*` field identifies the target. Some checks
cannot supply a path or a complete object identity, so do not infer one.

For a matching [access-check record](/peios/using-peios/events/kacs/kacs-audit-access-checked.md):

- Compare `access.requested` and `access.granted`. The requested mask is already
  generic-mapped to the object's rights.
- `access.denied-integrity` and `access.denied-trust`, when present, identify
  bits withheld by the mandatory-integrity or process-trust checks.
- `trigger.ace` identifies the **audit** ACE that caused a SACL-driven record;
  it is not a trace naming the DACL ACE that denied access.
- `fields.attestation.userspace` marks an advisory syscall check whose descriptor
  and supplied context came from userspace. It is not proof that the real
  operation used those same inputs.

For a [`kacs.audit.privilege.used`](/peios/using-peios/events/kacs/kacs-audit-privilege-used.md)
record with `operation.name` equal to `access-check`, a false `outcome.success`
means a privilege contributed rights that did not survive. It does not mean the
privilege was absent, and it does not identify one narrowing layer on its own.

**No record is not proof of no attempt.** Access auditing depends on matching
SACL rules or token policy, and syscall SACL records additionally require the
calling process's enabled `SeAuditPrivilege`. Reader permissions, query scope,
retention and transport loss also limit what you can see. One check can produce
several records; `MAXIMUM_ALLOWED` success is not evidence that a particular
right was granted, and it produces no access-check privilege-use record.
See [Find missing records](/peios/using-peios/logs-and-events/find-missing-records.md).

Use [the raw event stream](/peios/advanced-peios/security-diagnostics/the-event-stream.md) only to diagnose
the transport itself. It requires `SeSecurityPrivilege`, can lose events, and
is not a replacement for recorded history.

## The six places a denial can come from

For a completed access check, these are the common policy questions. They are
not a classification of every application error or failed inspection:

1. Could the impersonation token be used for access at all?
2. Did mandatory integrity control (MIC) withhold the requested rights?
3. Did process integrity protection (PIP) withhold them?
4. Did the DACL grant them for this caller?
5. Did a restricted-token pass, confinement or central policy narrow the grant?
6. Did an operation that legitimately needs a privilege have it present, enabled
   and, where required, accompanied by the caller's intent?

## Review the relevant policy

Use the evidence above to choose the relevant review below. The
[access-decision overview](/peios/security-fundamentals/access-decisions/overview.md) explains the complete
ordering; a visible allow rule or a hand-worked DACL alone is not a full verdict.

### Impersonation level

An **impersonation-type** token at Identification level cannot be used for an
access check. Confirm the type as well as the level. Ask the application's
owner to review what the client requested and whether the
[two-gate model](/peios/security-fundamentals/impersonation/the-two-gates.md) downgraded it. Identification
may have been deliberate; do not assume the client intended to delegate more
authority.

### MIC

Compare the caller's integrity and mandatory policy with the object's applicable
mandatory label and the requested rights. `NO_READ_UP`, `NO_WRITE_UP` and
`NO_EXECUTE_UP` affect the corresponding mapped categories. An object without an
applicable label defaults to Medium with no-write-up; an unreadable SACL does
not establish that this default applies.

Review whether the workload was launched at its intended integrity and whether
the object's label matches its purpose. Do not lower a label or elevate the
caller merely to make the test pass. MIC does not revoke rights already granted
by backup/restore privileges, so an integrity mismatch alone is not the full
answer. See [Mandatory integrity control](/peios/security-fundamentals/access-decisions/mandatory-integrity-control.md).

### PIP

PIP compares process trust, not the user's identity or token integrity. Both
caller trust axes must dominate the object's applicable trust label; otherwise
the label's mask limits the allowed rights and can revoke privilege grants.
Use the permitted PSB view and any recorded `access.denied-trust` evidence.

For a protected service, review whether the client is using its supported
interface and intended binary. Administrator membership or another privilege
does not bypass this boundary. Review unexpected protection or signing state
with the component owner. See [Process integrity protection](/peios/security-fundamentals/process-integrity-protection/overview.md).

### Privileges

First establish that this operation is intended to use a privilege. Then
separate three findings:

- **Absent:** review the principal's privilege assignment with its policy owner.
- **Present but disabled:** review the application's use of that privilege.
- **Enabled but intent missing:** backup/restore intent belongs to the caller's
  operation, and cannot be inferred from the token dump.

A privilege's presence is not a general access grant. Enabling privileges or
adding backup/restore intent is not a routine repair for an ordinary read or
write. PIP, confinement and central policy can still constrain privilege-granted
rights. See [Privileges in the pipeline](/peios/security-fundamentals/access-decisions/privileges-in-the-pipeline.md)
and [Intent-gated privileges](/peios/security-fundamentals/privileges/intent-gated.md).

### The DACL walk

Compare the requested rights with the ordered ACEs and the caller's actual SID
set. Enabled groups participate in allows; deny-only groups participate in
denies. Check `INHERIT_ONLY`, owner-rights suppression and inherited rules before
concluding that a rule applies. For conditional ACEs, missing claims or resource
attributes can produce UNKNOWN, which does not grant access through an allow
ACE.

ACE order matters: the walk is first-writer-wins for each undecided right, not a
search for any matching allow. Use [DACL evaluation](/peios/security-fundamentals/security-descriptors/dacl-evaluation.md)
and [Ownership](/peios/security-fundamentals/security-descriptors/ownership.md) for the exact matching
rules, including `OWNER RIGHTS` and `PRINCIPAL_SELF`.

If the evidence points to the DACL, ask the resource's policy owner to compare
its intended audience and rights with the current rules and inheritance. Avoid
broad grants, ownership changes or inheritance resets as diagnostic shortcuts.

### Narrowing layers

A DACL grant may still be narrowed:

- **Restricted token:** compare the restricting SIDs with the object's rules.
  The write-restricted variant narrows only write-category rights. Privilege
  grants can survive this pass; review the application's token construction.
- **Confinement:** compare the confinement SID and declared capabilities with
  the resource policy. Privileges do not bypass confinement. Review the
  workload's intended capabilities with its deployment or policy owner.
- **Central access policy (CAAP):** check referenced effective policies, their
  applicability and resource attributes with the directory/policy owner. A
  missing policy uses the documented recovery policy. A staged-policy mismatch
  is a rollout signal, not a statement that the staged policy caused the denial.

Do not remove restrictions, confinement or central-policy references to test a
hypothesis. See [Narrowing layers](/peios/security-fundamentals/access-decisions/narrowing-layers.md) for
the separate mechanisms and their policy-specific references.

## A compact checklist

1. Keep the failing action, time, caller, object, requested rights and exact
   error together.
2. Identify the process in Task Manager; inspect the relevant token and PSB
   using the documented commands and your existing authority.
3. Read the descriptor components you are allowed to see. Mark inaccessible
   components as unknown.
4. For a file, use `sd check --explain` with the identified target and rights;
   record which inputs the rehearsal does and does not reproduce.
5. Correlate available audit evidence. Account for missing records and changes
   since the failure.
6. Take the finding to the appropriate application or policy owner. After an
   approved correction, verify the original operation in its intended context;
   a changed descriptor or an allowed rehearsal alone is not completion.

## When the evidence is incomplete

Hand the investigation to the application or resource-manager developer when
the failure depends on a transient impersonation token, caller-supplied claims,
intent flags, object-type mapping or other inputs the operator tools cannot
reproduce. Include the evidence collected, its timestamps and scope, and each
inspection that was refused. Do not fill missing inputs with guesses.

The existing [SDK checking-access guide](/peios/developing-for-peios/sdk-access-control/checking-access.md)
covers programmatic evaluation. Its [request reference](/peios/developing-for-peios/sdk-reference/sdk-access/the-request.md)
defines the token, descriptor, desired mask, generic mapping, privilege intent,
self SID, local claims, object tree, PIP context and audit context. The
[check](/peios/developing-for-peios/sdk-reference/sdk-access/the-check.md) and [audit outputs](/peios/developing-for-peios/sdk-reference/sdk-access/audit-outputs.md)
references describe the granted mask, continuous-audit mask and staging-mismatch
flag. The Kernel TRM [KACS ABI](/peios/advanced-peios/peios-kernel/kacs/kacs-abi.md) preserves the
raw syscall structures.

These checks are advisory. A developer must match the original inputs and
understand the [syscall's audit limits](/peios/advanced-peios/peios-kernel/kacs/access-check/auditing.md)
before treating a reproduction as an explanation. Calling or decoding a syscall
is not a required operator step, and its answer does not perform or authorise
the original operation.

## Where to go next

- [Task Manager](/peios/using-peios/threads-and-processes/task-manager.md) and
  [token](/peios/using-peios/peiosutils/system-and-processes/token.md) for identifying the caller.
- [sd](/peios/using-peios/peiosutils/files-and-directories/sd.md) and
  [registry access control](/peios/using-peios/registry-security/access-control.md) for the
  object's policy and the supported inspection commands.
- [Event Viewer](/peios/using-peios/logs-and-events/event-viewer.md) and
  [Find missing records](/peios/using-peios/logs-and-events/find-missing-records.md) for recorded
  evidence and the limits of a search.
- [Inspecting security state](/peios/using-peios/inspecting/overview.md) for the underlying
  interfaces and access requirements.

---

# Inspecting tokens

_Peios / Using Peios / Inspecting security state_

> Select the right token, read its identity and security fields with token, and distinguish what the report proves from what needs object policy or historical evidence.

Use the read-only forms of [`token`](/peios/using-peios/peiosutils/system-and-processes/token.md) to learn
who a process acts as and what identity, privileges and restrictions its token
carries. Choose the target first: the inspection tool's token, a process's
primary token and a thread's impersonation token can describe different callers.

A report is current state, not a record of an earlier failure and not a list of
everything that caller may access. For a denial, keep the object and requested
operation alongside it; follow [Debugging a denial](/peios/using-peios/inspecting/debugging-a-denial.md).

## Reading from the shell

Start with a summary, then request only the detail needed:

```console
token
token show --all
token show --pid PID --all
token groups --pid PID
token privs --pid PID
token stats --pid PID
```

The first two inspect the token running the command. `--pid PID` selects the
identified process's **primary token**. Use [Task Manager](/peios/using-peios/threads-and-processes/task-manager.md)
to find and check the process rather than guessing its PID.

For impersonation, the command documents `--tid TID` together with `--pid PID`:

```console
token show --pid PID --tid TID --all
```

The failing thread's **effective token** is its impersonation token while
impersonating, otherwise the primary token. A primary-token report cannot stand
in for an impersonated client's identity. If the thread has exited or reverted,
keep that limitation with the result. Do not assume a query made later
reconstructs the token used earlier.

The other documented selectors are `--self` (the default), `--real` (your primary
token specifically), and `--peer SOCK_FD` (a connected socket's captured peer
identity). A peer token is the identity conveyed on that connection, not a
general lookup of another process. See [Choosing which token](/peios/using-peios/peiosutils/system-and-processes/token.md#choosing-which-token).

`--raw` prints raw SIDs, `--label` uses labels where known, and `--json` requests
structured output. Preserve the selector, timestamp and any error with a saved
report. The command also has mutating subcommands; adjusting, duplicating,
restricting or impersonating a token is not part of read-only inspection.

## Read the fields as evidence

| Field or question | Read with | What to check |
|---|---|---|
| Principal | `token user` | The user SID; a displayed name is a label for that identity. |
| Groups | `token groups` | Group SIDs and attributes. Enabled groups can match allows; deny-only groups match denies. |
| Privileges | `token privs` | Present and enabled are different. A disabled privilege cannot contribute, and presence alone does not bypass other policy. |
| Integrity | `token integrity` | The token's level; compare it with the object's label and mandatory policy when diagnosing MIC. |
| Logon context | `token logon`, `token stats` | Logon type, logon SID and session identity. The LogonSession ID is separate from interactive-environment scope. |
| Confinement capabilities | `token caps` | Which capabilities are present; combine them with the confinement identity from the fuller report and the object's rules. |
| Claims | `token claims` | User/device attributes available to conditional ACEs; the application may additionally supply per-call local claims. |
| Default owner, group and DACL | `token owner`, `token group`, `token default-dacl` | Defaults for objects created with this token, not the security descriptor of every existing object. |
| Origin and source | `token origin`, `token source` | The originating session of a derived token and information about what minted it. |
| Type, impersonation level, restrictions, elevation and mandatory policy | `token show --all` | The full set of supported query classes, interpreted with the limits below. |

Apply the same target selector to these field commands; without it they inspect
your own token. `token query CLASS` is the documented raw named-class JSON form
for tooling. The complete class numbers and payloads are maintained in the
[Kernel ABI](/peios/advanced-peios/peios-kernel/kacs/kacs-abi.md#token-constants)
and [token query payload reference](/peios/advanced-peios/peios-kernel/kacs/kacs-abi-notes.md#token-query-payloads),
rather than duplicated here.

`show --all` means every supported query class, not every internal token field.
The ABI notes explicitly list fields with no query class, including
`audit_policy`, `write_restricted` and `confinement_exempt`. Do not infer these
from their absence in a report.

## Patterns by use case

**Who was this thread acting as?** Use the process and thread identity supplied
by the failure report, inspect the relevant token, and distinguish its type from
its impersonation level. A primary token also carries an impersonation ceiling;
the level alone does not tell you that the thread is impersonating. For earlier
state, correlate the available audit record instead.

**Which session is this?** `token show` displays the LogonSession LUID as
`session_id`; the underlying statistics field is `auth_id`.
`interactivity_scope` is a separate interactive-environment scope. Use the logon
session ID with [`logonse show ID`](/peios/using-peios/peiosutils/system-and-processes/logonse.md#logonse-show),
subject to the session view's access limits.

**Is this the elevated half of a token pair?** The elevation type can be Full,
Limited or Default. Full and Limited describe the two sides of a linked pair;
Default means the token is not part of one. This is evidence about the token,
not a recommendation to elevate it. The separate `token linked` command reports
a linked counterpart where accessible.

**Did the token change?** Token statistics include its ID and `modified_id`,
which changes on adjustment. Keep both when comparing observations. Several
queries are not an atomic snapshot, and replacing a thread's token is not the
same as adjusting the one you previously inspected.

**Would this token be allowed to access an object?** The token is only one input.
For a file, use the documented `sd check` rehearsal and its
[limits](/peios/using-peios/inspecting/debugging-a-denial.md#rehearse-a-file-check-within-its-limits).
For other objects or caller-specific inputs, use their supported diagnostic
path or ask the component owner to investigate.

## Limits and refused queries

- Reading another process's token needs `PROCESS_QUERY_INFORMATION`, PIP
  dominance and the token's own `TOKEN_QUERY` grant. A refusal does not tell you
  which of those checks failed. Protected processes can remain closed to an
  administrator.
- Self-access depends on the surface. The documented own-process `/proc`
  token path is query-only without those checks; a direct self-open API checks
  the token's descriptor and can be denied after that descriptor changes.
- A missing or exited target, a denied query and an invalid request are
  different results. Keep the tool's message; a failed query is not an empty
  token.
- Process-based inspection cannot enumerate tokens held only by descriptors.
  Current queries cannot recover a destroyed token or historical fields.
- Queries do not grant adjustment, installation, duplication or impersonation
  rights. The `used` privilege state is not a timestamped history of each use;
  use audit evidence for that question.

See [Token access rights](/peios/advanced-peios/peios-kernel/kacs/tokens/access-rights.md) for the
per-surface checks and [Inspecting security state](/peios/using-peios/inspecting/overview.md)
for related views.

## Obtaining a token fd

This is the tool-author boundary. Token pseudo-files are **handles**, not
human-readable text: `cat /proc/<pid>/token` is not an inspection command.
The process path selects the primary token and
`/proc/<pid>/task/<tid>/token` selects the thread's effective token; the
`/sys/kernel/security/kacs/self` surface also provides a token handle.

The SDK [opening reference](/peios/developing-for-peios/sdk-reference/sdk-tokens/opening-and-creating-tokens.md) covers
self, process, thread and socket-peer token acquisition and error results.
The Kernel TRM [access-rights chapter](/peios/advanced-peios/peios-kernel/kacs/tokens/access-rights.md)
documents the query-only `/proc` handles, fixed peer-token rights, descriptor
checks and cached handle rights. A handle with only `TOKEN_QUERY` cannot perform
operations requiring other token rights.

## KACS_IOC_QUERY

Operators use `token` to perform and decode queries. Tool authors should start
with the SDK [query reference](/peios/developing-for-peios/sdk-reference/sdk-tokens/query.md) and
[two-call buffer protocol](/peios/developing-for-peios/sdk-reference/sdk-conventions/the-two-call-buffer-protocol.md).
The SDK provides typed readers for common fields and the generic class reader
for the rest.

For a raw-ABI consumer, the preserved
[querying-a-token-handle explanation](/peios/advanced-peios/peios-kernel/kacs/kacs-abi-notes.md#querying-a-token-handle)
covers `KACS_IOC_QUERY`, size probes, short buffers and the two-call sequence.
The generated [KACS ABI](/peios/advanced-peios/peios-kernel/kacs/kacs-abi.md) holds the exact ioctl
number, argument layout and class constants; its
[ABI notes](/peios/advanced-peios/peios-kernel/kacs/kacs-abi-notes.md#token-query-payloads)
define the returned bytes. There is no need to decode those bytes by hand to
follow this operator workflow.

## See also

- [token](/peios/using-peios/peiosutils/system-and-processes/token.md): the complete command interface.
- [Debugging a denial](/peios/using-peios/inspecting/debugging-a-denial.md): caller,
  object, requested action and audit evidence together.
- [Tokens](/peios/security-fundamentals/tokens/overview.md): the identity model behind the fields.
- [Working with tokens](/peios/developing-for-peios/sdk-access-control/working-with-tokens.md): developer
  tasks using the SDK.
