Peios Learn
Products
PePeios pkpekit PvProvium UDUniversal Directory TrTrail Ckclackatoo PrProject WiWispist
Using Peios Security Basics Technical Documentation Source
Using Peios Security Basics Technical Documentation Source
Peios

Administration

Single-page view · as markdown

Registry startup and configuration

Peios / Using Peios / Administration

LCS uses compiled-in defaults at startup, then reads its settings from Machine\System\Registry when the Machine hive becomes available. For routine tuning, inspect and document the specific parameter before changing it:

reg get Machine/System/Registry
regman 'Machine\System\Registry'

Use the normal change-and-verification workflow. These parameters affect the registry itself, so keep changes narrow and record a recovery value before modifying them.

What startup defaults do and do not mean #

The kernel's registry machinery and base layer can operate before there is stored configuration. That does not make hives available before their source registers. Until a source supplies a hive, a path naming it cannot be opened.

The registryd role, supplied by loregd by default, starts early so the rest of the system can read configuration. Its backing database paths come from startup arguments rather than registry settings. See LCS and sources.

When a registry parameter change applies #

LCS watches its configuration and validates changes before publishing new operational parameters; the normal transition needs no LCS restart. Use the parameter's manual and the LCS operational-parameters reference for type, range and effect. That reference also describes the limits of in-flight parameter snapshots; do not assume every ongoing operation changes at exactly the same instant.

It applies reject-or-keep to itself #

A valid parameter is adopted. An invalid value, wrong type or missing parameter leaves the previously active value in force, which may be the compiled default or a previously accepted value. Values are not clamped. The documented rejection event is lcs.config.value.rejected.

Warning

Deleting a registry tuning value is not a reliable way to reset its running value to the compiled default. Read the parameter documentation, write the intended valid value if a reset is needed, and verify the result.

Read-back shows stored data, so inspect the registry's events too. A missing whole configuration key during first boot differs from individual missing parameters in an existing key; the TRM describes that distinction.

First boot, with no data #

The source creates hive roots with their initial security descriptors. LCS keeps its defaults while configuration is absent. The init system then restores a seed containing the initial configuration; LCS notices it, reads the settings and validates them.

For a machine that does not reach normal startup, examine the source's early diagnostic output and the init-system failure information. With loregd, peinit relays output to the console if the source fails before readiness; after logging starts, its buffered output reaches eventd. Do not assume missing configuration alone proves that the databases need to be replaced or seeded again.

Where to go next #

  • Source availability and recovery checks
  • Backup and restore, including destructive replacement
  • Kernel boot sequence and self-watch implementation

Backup and restore

Peios / Using Peios / Administration

Use a backup when recovery must preserve a subtree's security descriptors and tagged layer entries. Use a JSON export for a reviewable configuration document. They serve different purposes.

Choose the recovery format #

NeedToolImportant limit
Review or transfer visible keys and valuesreg export --json KEY FILE and reg apply FILEExport does not save key security descriptors or the complete layered store.
Recover a subtree with its descriptors and layer entriesreg backup KEY FILE and reg restore KEY FILEPrivileged; restore replaces the target contents and descendants.
Recover a managed configuration bundleThe role or policy workflow, or a reviewed layer operationLayer removal does not restore key permissions or reverse consumer side effects.

Registry Editor offers these under Files as Export…, Import…, Back up… and Restore…. Its export is a JSON registry document. Text-format reg export is for review; text input to reg apply is not implemented, so use JSON for reapplication.

Take a backup before a risky change #

For example, to capture the KMES configuration subtree:

reg backup Machine/System/KMES kmes.snap

Confirm the command succeeded and retain the file together with its original key path and the change it precedes. Choose a protected file location: backup privilege can include configuration you could not read through ordinary key access. A failed or interrupted output is not a verified recovery copy.

Backup is a point-in-time snapshot #

A backup captures a consistent subtree while other writes can continue. It includes key descriptors, layer-tagged entries and absence markers, rather than just effective values. The stream has integrity checks to reject truncation or corruption on restore. Integrity does not establish that an unknown backup is trustworthy.

Warning

A backup's layer manifest records layer information for validation; it does not recreate layer definitions. A layer definition is included only if its metadata key under Machine\System\Registry\Layers\<Name> is part of the backed-up subtree.

If you restore entries for a layer that no longer exists, and the backup does not restore that layer's metadata, those entries remain inactive until real metadata exists. This matters when recovering after layer deletion or moving configuration to another machine. Review which layer definitions are needed before relying on a narrow subtree snapshot. See the LCS backup reference and restored-layer rules.

Restore is replace, not merge #

Before restoring:

  1. Confirm the backup is trusted and corresponds to the intended target.
  2. Save the current target if you need a way back from the restore itself.
  3. Review the target subtree, affected consumers and restored permissions.
  4. Confirm needed layer metadata exists or is included, and arrange any required privileges or consumer restart/reload.
  5. Run restore only after approving the replacement scope.

For the earlier example:

reg restore Machine/System/KMES kmes.snap

The target key object remains, but its mutable fields, values and contents are restored and its descendants are replaced. Its immutable volatile/link flags must match the backup root. Do not assume a backup can be restored onto any arbitrary key.

The operation uses one transaction. A rejected stream or a failure before commit leaves no partial restored subtree. If the commit times out or reports a source failure, its result can be uncertain: inspect the live state before retrying or reporting that nothing changed.

reg restore prompts on terminal input; with non-terminal input it proceeds without that prompt. Do not use a script's lack of a prompt as evidence that the operation is non-destructive.

Both bypass per-key permissions — by design #

Backup requires SeBackupPrivilege; restore requires SeRestorePrivilege. They bypass ordinary per-key checks and are audited independently of each key's audit settings.

Warning

Restore writes the backed-up security descriptors, including the target key's descriptor. Its privilege effectively permits rewriting owners and permissions throughout the target subtree.

SeRestorePrivilege alone is not enough for every snapshot. A manifest layer with precedence above 0, or a matching existing layer above 0, requires SeTcbPrivilege. Restored layer metadata is also subject to its positive-precedence check. See the restore precedence gate.

Verify the recovery #

  • Inspect the subtree and representative effective values with reg tree, reg get -L and Registry Editor.
  • Inspect key descriptors and reg layer ls -l; missing or different layer definitions can change what is effective.
  • Check relevant consumer status and events after the setting's documented application point. Restore notifications require watchers to re-read; they are not consumer acceptance acknowledgements.
  • Check fresh opens when restored permissions matter; existing handles retain the rights granted when they were opened.

Where to go next #

  • Change a setting and verify it
  • Recover using a layer
  • LCS backup and restore implementation

LCS and sources

Peios / Using Peios / Administration

The registry depends on both the kernel's LCS subsystem and a userspace source that persists hive data. On a standard installation, loregd provides the registryd role and serves Machine and Users.

For ordinary configuration, use reg or Registry Editor. Do not edit a source's database to bypass the registry's access checks, layer handling or notifications.

Which component to investigate #

Symptom or questionStart with
What is a setting and when does it apply?regman and its owning component.
Why does a stored value lose to another?Layers.
Why is one operation denied?Key and layer access.
Why are a hive's reads and writes unavailable?Its source's startup and failure diagnostics.
Why did a source response get rejected?LCS events and the validation reference.

LCS owns routing, access decisions, effective layer resolution, watches and transaction coordination. Sources persist and return entries; each hive has one source, and one source may serve several hives. Programs reach the registry through LCS rather than talking directly to a source.

The base source: registryd #

registryd is a replaceable role, not a second daemon alongside loregd. peinit starts its provider early because later services need the registry. The default provider takes one HiveName=DatabasePath argument per hive; its own startup does not depend on reading registry configuration.

The reviewed peinit bootstrap passes Machine=/var/state/loregd/Machine.hive and Users=/var/state/loregd/Users.hive to the source. These paths are peinit's boot policy, not defaults chosen by loregd; see the pinned service definition. The /var/state/registry/*.regdb paths in generic loregd examples do not establish the deployed locations. Inspect the installed startup configuration before assuming these paths apply to a particular image or release. Do not launch another source against the same databases as an exploratory repair step.

The loregd command-line reference covers arguments and validation. The loregd overview covers packaging and its boot role. Alternative source implementations may have different storage diagnostics.

When a source goes away #

Its hives become unavailable. Open key handles remain, but operations requiring source access fail until it returns. Watches stay armed and receive overflow recovery on re-registration, so consumers must re-read.

To investigate:

  1. Save the exact failed operation, key and error. reg exit status 3 means access denied; 5 includes source and syscall failures. Avoid treating every failure as a permissions problem.
  2. Check the source's diagnostic output and init-system status. For loregd, peinit relays failures before readiness to the console and carries buffered output into eventd once logging starts.
  3. Establish why the source failed before restarting it or replacing data. When reads work again, re-read the affected keys and verify consumers.
  4. After a timeout or source failure during a mutation, check state before retrying. The source may have applied it even though the caller did not receive success.

A transaction commit timeout is especially important: neither the timeout nor the transaction's timed-out status proves the writes were rolled back. See Transactions and the LCS late-response reference.

The trust boundary #

A source is part of the trusted computing base. LCS checks access using the descriptors the source returns. It validates response structure, but cannot detect well-formed false data, such as fabricated permissions or layer metadata. Protect the source's service definition, privileges, process and storage as critical system components.

Do not interpret "sources make no access decisions" as "sources need no trust". The LCS source model explains that boundary.

Two operations the kernel coordinates #

  • Transactions group changes to one hive into a commit. A source must support the needed transaction mode.
  • Backup and restore use the source's storage operations, with LCS enforcing privileges and the backup format. Restore replaces a subtree, including descriptors.

These are administrative interfaces; the private source protocol is not a troubleshooting command surface.

Where to go next #

  • Registry startup and self-configuration
  • LCS source registration and dispatch
  • Registry Source Interface specification
  • SDK guide for source authors

Registry Editor

Peios / Using Peios / Administration

Registry Editor shows the registry: its keys as a tree, and the values of the key you pick, which you can change. A key is a container in the registry, like a folder, and a value is a named, typed piece of data in a key. It reads the registry as you, so it shows what you may read, and it says what you may not.

Before changing anything #

  1. Browse to the exact key and inspect its current values. Select a value to see its winning layer and the registry manual beside it.
  2. Check the manual's expected type, valid values and application timing. A saved value can still be rejected by the component that reads it.
  3. Check Writes go to in the bar. Your change goes to that layer, which may differ from the layer currently winning the value.
  4. Record the original state. Use Files → Back up… if recovery needs key permissions and layered entries; Export… is a reviewable configuration document with different coverage.
  5. Save one intended change, then verify it.

Opening it #

  • From the launcher: start Registry Editor. It opens on Machine.
  • From a program: gxwi-registry-editor --key PATH opens on the key at PATH, such as gxwi-registry-editor --key 'Machine\System\Services'.

The window's title names the key shown, such as Registry Editor: Services.

The keys #

On the left is the tree. It starts from three keys:

  • Machine holds the machine's own settings.
  • Users holds each person's settings, under a key named for their SID, the number that identifies them. The tree shows whose each one is, such as dana, before the SID.
  • CurrentUser is your own key under Users, by a shorter name.

Select ▸ beside a key to show the keys under it, and ▾ to hide them. Select a key's name to show its values.

To go straight to a key, type its path in the box at the top and press Enter or select Go. Write the path with \ between the names, as in Machine\System\Services; / works too. The tree opens down to the key. A path with no key at it is refused, with the reason.

The values #

The middle shows the values of the key shown, each with its name, its type and its data. The default value comes first, as (Default): it is the value a key can hold without a name.

Types are given in words:

It saysTypeShown as
TextREG_SZthe text
Text with variablesREG_EXPAND_SZthe text, with any %NAME% left as written
LinkREG_LINKthe path the link points to
List of textREG_MULTI_SZthe items, separated by ·
NumberREG_DWORDthe number, then in hexadecimal
Number, big-endianREG_DWORD_BIG_ENDIANthe number, then in hexadecimal
Large numberREG_QWORDthe number, then in hexadecimal
BytesREG_BINARYthe bytes, in hexadecimal
No typeREG_NONEnothing

The registry doesn't check that a value's data fits its type. Data that doesn't fit, such as a number of the wrong length or text that isn't valid UTF-8, is shown in red, as bytes.

A value or a key in full #

Select a value to see it in full in the pane on the right: its type, its size, the layer its data came from, and all of its data. A layer is a set of registry entries that can override another. Bytes are shown eight to a row, after the offset of the first.

With no value selected, the pane describes the key: when it last changed, how many keys and values it holds, and whether it is a link or is kept only until the machine restarts. Copy path copies the key's path.

What the registry manual says #

Packages document their keys and values in the registry manual, which regman shows in a terminal. Registry Editor shows the same, at the foot of the pane:

  • For a key, what it is for.
  • For a value, the type the manual expects, its default, the values it may take, and when a change applies: at once, when the program that reads it next starts, or when the machine next starts. Then what it is for.

Values the manual documents that aren't set on the key are listed after the values that are, greyed, with Not set and the default the manual gives, as in Not set · default 30. Check the manual for the consumer's missing-value behavior; some retain a previously active value. These manual-only entries aren't stored values, so they aren't counted or exported. Select one to see what the manual says of it, and double-click it or choose Set… to start a new value with its name, the type the manual gives it and, where the default is a plain value, the default.

If a value's type isn't the one the manual expects, the pane says so in red, since whatever reads it may not accept it. A key or value the manual doesn't mention says so too.

Changing values #

To change a value, double-click it, or select it and choose Edit… in the pane or on its right-click menu. The pane shows a form for its type:

  • Text and Link take one line.
  • List of text takes one item to a line. Empty lines are left out.
  • Numbers take a whole number, typed in Decimal or Hexadecimal. Changing between them rewrites the number in the other form.
  • Bytes take two hexadecimal digits to a byte. Spaces and new lines are ignored.

Data that doesn't fit its type is edited as bytes, and keeps its type. Save writes it, and Cancel or Esc leaves it as it was.

If Save reports a concurrent change, it refuses the edit and refreshes the list. Review the current value and destination layer before choosing Save again; submitting your edit again can replace another writer's entry in that layer. Conditional-write checks are scoped to the destination layer, so do not assume they guard every change to another layer's effective winner. See Transactions.

New value… adds a value to the key shown. Give it a name, or leave the name empty for the key's default value, and pick its type: text, text with variables, a list of text, a number, a large number or bytes. A name the key already uses is refused.

To delete a value, select it and choose Delete…, then confirm.

Changing keys #

  • New key… creates a key under the one shown, and shows it.
  • Delete key… deletes the key shown and everything under it, keys and values, after asking. It is all or nothing: if any part can't be deleted, nothing is. Links under it are deleted; the keys they point to are not. Large trees can exceed file-descriptor or transaction limits and be refused. Review the deletion limits and agree a smaller deletion scope before splitting the operation: separate deletions are no longer one atomic change.

The root keys can't be deleted. Changes go to the base layer, the one every change goes to unless it names another.

The key shown has these on its right-click menu in the tree too, with Copy path.

Layers #

A layer is a set of registry entries that can override another. Layers… in the bar opens them in a window of their own, each with its precedence, whether it is enabled, and who owns it. Where entries for the same value are in several layers, the one in the layer of highest precedence wins; at equal precedence, the most recent write to that value wins. Different values can have different winning layers.

  • New layer… creates one. A layer may be disabled from the start: it then takes part only for programs that name it.
  • Disable and Enable switch a layer off and on.
  • Set gives a layer a new precedence.
  • Delete… deletes a layer after asking, and every entry written into it goes with it.

A precedence above 0 needs the privilege to act as part of the operating system (SeTcbPrivilege), which administrators don't hold, so for them only 0 may be set, and the window says so. The base layer is always there, at precedence 0, and can't be changed.

Writes go to, in the bar, picks the layer your changes are written into, base unless you choose another. You need to be allowed to write into it as well as to change the key: if you may not, the key is shown read-only, with the reason. Deleting a value deletes only that layer's entry for it; another surviving entry can then show. Deletion does not necessarily leave the value absent or select its documented default.

The pane says which layer a value's data came from. The registry can't yet list a value's entries in the layers beneath the one that wins, so only the winning entry is shown. If your changes go to a lower layer than the one a value comes from, the pane warns that they won't show while that entry is there.

Permissions #

Warning

Changing a key's permissions is not a layered edit. Disabling or deleting the selected layer does not restore the key's old owner or permissions. Existing open handles keep their granted rights until they are reopened.

Each key has its own permissions, which say who may read it, change it and so on. Permissions… in the pane, or on the key's right-click menu, opens them in the permissions editor. Read covers reading the key's values and listing the keys under it, and Write covers changing values and creating keys. The editor adds inheritable grants for children. Inheritance is computed at creation; changing the parent does not by itself rewrite keys that already exist. Inspect the actual descriptors on existing descendants.

Some values hold a security descriptor: a list of who may do what, kept for a program that reads it, such as a service's ServiceSecurity. Registry Editor recognises one by its bytes, and shows it as Security descriptor, written in SDDL, a short text form, rather than as bytes. Permissions… beside it opens it in the permissions editor. What its rights mean is the reading program's to say, so only the general ones are named there: Full control, Read, Write and Execute. Anything else it grants is shown as special and kept as it is. To change one, you need to be allowed to change the key's values; otherwise it opens read-only and says why. For a service's own permissions, Services Manager names its rights properly: see Who can manage a service.

Files #

Files, in the key's pane, takes the key to a file and back. Each opens a file dialog, where you choose where to save or what to open:

  • Export… writes the key and everything under it to a registry document, a JSON file of keys and values that you can read and change by hand, and that reg apply reads too. It keeps every value exactly.
  • Import… reads a registry document and, after showing where it will write, writes it into the registry, into the layer chosen in the bar. It is all or nothing: if any part can't be written, none is.
  • Back up… copies the key and everything under it, permissions and layers included, to a backup file.
  • Restore… replaces the key's contents and subtree and restores its security descriptor from a backup, after asking. It does not merge with the current contents.

Backing up needs the privilege to back up files and keys (SeBackupPrivilege), and restoring the privilege to restore them (SeRestorePrivilege). Administrators hold both. Without them, the buttons are shown disabled, with the reason. A backup containing or matching positive-precedence layers additionally needs SeTcbPrivilege for restore; having the restore privilege alone is not enough.

An export does not include key permissions or the full set of layer entries. A backup preserves tagged entries, but its layer manifest does not recreate missing layer definitions. Before recovery after layer deletion, check whether the needed metadata was included. See Backup and restore.

Review the target before importing or restoring. A restore can rewrite owners and permissions throughout that subtree. If a write or commit times out or reports a source failure, refresh and inspect state before retrying; the error does not prove that it was rolled back.

The file dialog shows one folder at a time, starting in your home folder. Open a folder to go into it; Up and Home move about, and you can type a path. It can also make a folder, rename and delete, as you, and says which of those you may not do, and which folders you may not list. Saving over a file that is there asks first.

Changes made elsewhere #

The window watches the keys it shows. A value or key added, changed or removed by a program or in a terminal appears within a moment, with no need to refresh. Refresh, or F5, reads everything again.

What you may not see #

Each key has its own permissions, and the registry checks only the key being opened, not the keys above it. So:

  • A key you may not list shows You may not list this key's subkeys. under it in the tree. A key you may not read at all shows You may not read this key. where its values would be.
  • You may still go to a key under one you may not list, by typing its path. The tree then shows it, in italics, under the key that couldn't be listed.

Some keys let you list their subkeys but not read their values, or the other way round. Registry Editor shows whichever you may, and says which you may not.

What you may change of a key is its own permissions' to say: changing its values, creating keys under it and deleting it are each a separate right. Registry Editor asks the registry which of them you hold. What you may not do is still shown, greyed out, and the pane says why, such as You may read this key but not change it.

In a terminal #

reg does the same in a terminal. The tree is reg ls and reg tree, the values are reg get on a key, and a value in full is reg get KEY NAME. Saving a value is reg set, a new key is reg new, and deleting is reg del, with -r for a key and everything under it. Export and import are reg export --json and reg apply, back up and restore are reg backup and reg restore, and layers are reg layer. See reg.

Verify a saved change #

After saving, inspect the displayed value, type and winning layer. Use Refresh or F5 for a fresh read. If a different layer still wins, check Layers rather than saving repeatedly.

Then follow the manual's application timing and inspect the consuming component's status and events. An updated row proves what is stored, not that a service accepted it. Follow Change a setting and verify it for rejected settings and recovery choices.

The registry manual (regman)

Peios / Using Peios / Administration

Configuration, not storage established that the registry holds values but not their meaning: it keeps a type tag and some bytes, and never knows that BufferCapacity must be a power of two or what it is for. That knowledge has to live somewhere a person can look it up. It lives in regman, the registry's manual.

regman is the man of the registry. Give it a path and it tells you what a key or value actually is. It is the everyday tool for configuring a Peios system — before you touch a knob, regman is how you find out what it does and what changing it will cost.

regman, in one sentence #

regman <path> [value] documents what a registry key or value means — its type, default, valid values, when a change takes effect, and a prose description — drawn from shipped documentation, never from the live registry.

That last clause is the one to hold onto; there is a section on it below.

Looking up a value #

Give regman a key path and a value name and it prints a knob-card — an identity line, an aligned block of facts, and a description:

$ regman 'Machine\System\KMES' BufferCapacity

Machine\System\KMES BufferCapacity                    documented by kmes

  Type     REG_QWORD
  Default  4194304  (4 MB)
  Valid    65536–268435456 bytes (64 KB–256 MB), power of two
  Applies  live — ring-buffer swap

Per-CPU ring buffer capacity, in bytes. Must be a power of two; values
that are not are treated as invalid and ignored.

Every registry value is a knob, and every knob has the same few facts worth knowing, so the card is uniform rather than free-form:

FieldTells you
TypeThe value's registry type (REG_QWORD, REG_SZ, …).
DefaultThe value used when nothing is set.
ValidThe range, set, or constraint a sensible value must satisfy.
AppliesWhen a change takes effect — live, on restart, or on reboot.

The Applies field is the one operators reach for most: it is the difference between "edit it and you're done" and "edit it and schedule a reboot". Only the fields that make sense for a given item are shown, and a knob that is being retired carries a prominent deprecation notice at the top of its card.

Looking up a key #

Give regman just a key — no value — and it does double duty as an index: the key's own description, then a list of every value documented under it, one summary line each.

$ regman 'Machine\System\KMES'

Machine\System\KMES                                   documented by kmes

The KMES event subsystem reads its tuning parameters from the values
under this key...

Values
  BufferCapacity         Per-CPU ring buffer capacity in bytes.
  MaxEventSize           Max total size of a userspace-emitted event.
  MaxNestingDepth        Max nesting depth for userspace event payloads.
  MaxEmitRatePerProcess  Max events per second a single process may emit.

So you can start at a subtree, see what is configurable there, and drill into any single value.

Keys that come in families #

Much of the registry is not at a fixed path. Every service has a key under Machine\System\Services\, every interface one under Machine\System\Network\Interfaces\, every principal one under Machine\Generic\Authn\Policy\. You ask about a real one — sshd, an interface id — and the documentation is written once for the whole family.

regman resolves that for you. Ask about the concrete path and you get the family's page:

$ regman 'Machine\System\Services\sshd' ImagePath

Machine\System\Services\<name> ImagePath              documented by peinit

  Type     REG_SZ
  Default  (required)
  Valid    a non-empty absolute path
  Applies  restart

Absolute path to the service binary.

The heading keeps the <name> so you can see you have been handed the page for the family rather than one written about sshd specifically. Everything on the card applies to the key you asked about.

A heading with a trailing ... — Machine\System\Network\Rules\<Layer>\<rule...> — means the family is a tree and the page covers it at any depth. That is what firewall rules are: an exception is a subkey of a rule, and a rule nested five deep has the same values meaning the same things as one at the top, so one page answers for all of them.

If a package has documented your exact key — its own service's knob, a particular principal's privileges — that page wins instead, and the heading shows the concrete path. The more specific documentation always answers.

Searching, when you do not know the path #

If you don't know where a setting lives, regman -k searches names and summaries — the registry's apropos:

$ regman -k buffer
Machine\System\KMES BufferCapacity   Per-CPU ring buffer capacity in bytes.

regman documents intent, not current state #

This is the boundary that matters most. regman tells you what a setting should be — what it means and which values are legal — not what it is currently set to on this machine. It reads shipped documentation, never the live registry; it does not talk to LCS at all. Ask regman about BufferCapacity and you learn it must be a power of two and defaults to 4 MB; you do not learn that this particular box has it set to 8 MB right now. Reading the current value is a separate, live query against the registry — that is reg's job. regman tells you a knob should be a power of two; reg get tells you what it is set to, and reg set changes it. Reach for regman to decide what to write, and reg to write it.

Put regman next to the other two things from Configuration, not storage and a clean division of labour appears:

To learn…Look at…
What a setting means, and what is validregman — the manual
What the value is set toreg — a live query against the store
What the subsystem is actually running onthe event log

regman is the one you consult first, and the only one that works before you have changed anything — because documentation ships with the software, not with the machine's state. It is the natural complement to reject-or-keep: regman tells you the valid range up front, so you set a good value the first time instead of writing one the owning subsystem will quietly refuse.

Where the documentation comes from #

regman has no built-in database of every setting. Each package ships its own documentation as files dropped into a well-known directory (/usr/share/regman/), one fragment per package documenting that package's whole configuration surface. Install a package and its registry documentation appears; remove the package and it goes away. The package that owns a set of keys is the package that documents them — the only arrangement that stays correct as the system changes.

A consequence worth knowing: regman can only describe settings that some installed package has documented. An undocumented key is invisible to it — regman is exactly as complete as the packages on the machine make it. If two packages happen to document the same item, regman shows both and flags the overlap rather than silently picking a winner.

(For the people who write that documentation, regman fmt and regman lint prepare and check fragments, and regman index keeps lookups fast on large corpora — the lookup is always correct without an index, which is purely an accelerator. These are packaging concerns rather than everyday operator ones.)

Where to go next #

For the idea regman exists to serve — why the registry holds values without holding their meaning, and what reject-or-keep means — read Configuration, not storage.

For the other half of the picture — reading what a value is actually set to, which is a live query against the store rather than a documentation lookup — read LCS and sources.

reg

Peios / Using Peios / Administration

reg is the command-line interface to the live registry — the running LCS store, reached through the registry system calls. Where regman reads shipped documentation and tells you what a key means, reg talks to the kernel and reads or writes what a key is. It is the everyday tool for scripting configuration: querying effective values, writing to layers, masking and hiding, managing security descriptors, watching for change, and taking backups.

reg <command> [options] <key> [value] [data]

reg is the read/write half of the registry toolset and regman is the lookup half. The division is exact:

To…Use…
Read or change what a value is set to, on this machine, right nowreg
Look up what a value means — its type, default, valid range, when it appliesregman

Consult regman first to learn the legal range for a knob, then use reg set to write a value inside it. reg never checks a value's meaning and regman never touches the live store; they are complementary.

How reg treats access and privilege #

Every reg operation goes through the kernel's access check against the single key it opens — the same access-control path as any other protected object, with no traversal check on the parent keys. reg performs no identity or membership checks of its own: it does not refuse a privileged operation up front. It attempts the operation and reports faithfully whatever the kernel returns. An operation that needs a privilege you lack (creating a link, a positive-precedence layer, a backup or restore, reading a SACL) simply fails with access denied (exit 3) rather than being blocked by the tool. A single reg command may legitimately span privilege tiers.

Addressing model #

Almost every subcommand shares one addressing scheme: a key path positional, and an optional value name positional. Understanding the split is most of understanding reg.

Key paths #

The key is a positional path argument. Both / and \ are accepted as separators — neither character is legal inside an LCS key component, so there is no ambiguity, and you may use whichever your shell quotes most comfortably:

reg get Machine/System/KMES
reg get 'Machine\System\KMES'      # identical

A leading separator is optional and ignored (/Machine/X is the same as Machine/X). Paths are compared case-insensitively. The first component is the hive:

PathMeaning
Machine\…The machine hive — system-wide configuration.
Users\<SID>\…A specific principal's hive.
CurrentUser\…A kernel alias, rewritten to the caller's own Users\<SID>\ at the syscall boundary.

On output, reg displays paths with a backslash by default. --sep=/ (or REG_SEP=/) switches display to forward slash for that invocation; this affects display only, never how a path is parsed.

The value-name positional #

The value name is a separate positional argument — it is never folded into the key path. This is deliberate: an LCS value name may itself contain / or \ (which a key component may not), so keeping them apart removes all ambiguity.

reg get Machine/System/KMES BufferCapacity
#       └──── key path ─────┘ └── value ──┘

The presence or absence of the value argument selects what the command targets:

  • No value argument ⇒ the command targets the key itself — its metadata, its values as a set, its security descriptor, its children.
  • A value argument ⇒ the command targets that one named value.
  • The default value (the empty-name value) is addressed by the literal token @ in the value-name position, mirroring .reg convention: reg get Machine/App @.

This split applies uniformly to get, set, del, mask, and unmask.

Value literals and types #

On set (and in a batch), the value's data is a single token whose registry type is either forced by a type: prefix or inferred from its shape. The registry value types and their literal syntax:

PrefixRegistry typeData syntax
sz:REG_SZUTF-8 string (rest of token, verbatim).
expand:REG_EXPAND_SZUTF-8 string, %VAR% left unexpanded on disk.
dword:REG_DWORD42 or 0x2A; must fit u32.
dword-be:REG_DWORD_BIG_ENDIAN42 or 0x2A; must fit u32.
qword:REG_QWORD42 or 0x2A; must fit u64.
multi:REG_MULTI_SZComma-separated; \, escapes a literal comma.
hex: / bin:REG_BINARYHex bytes; :, -, and space separators are ignored.
link:REG_LINKAn absolute key path (a symlink target).
none:REG_NONENo data (token must be empty after the prefix).

When the substring before the first : is not a recognised keyword (for example http://host), the token is not treated as typed and inference applies:

Token shapeInferred type
all decimal digits, fits u32REG_DWORD
all decimal digits, fits u64 but not u32REG_QWORD
0x… hex, ≤ 8 significant hex digitsREG_DWORD
0x… hex, ≤ 16 significant hex digitsREG_QWORD
anything else (including empty)REG_SZ

Inference is intentionally broad, so any all-digit token becomes a number — a PIN, a zip code, or 007 becomes a REG_DWORD and loses its textual form. To force a string, prefix it with sz: (sz:007 stores the string 007; sz:dword:42 stores the literal string dword:42). Because the coercion is a known trap, reg set always echoes the resolved type on success, so a surprising conversion is never silent even under --quiet.

Global options #

Every subcommand accepts the following. Each behavioural toggle also has an environment-variable equivalent, so it can be set per-invocation (the flag) or once per shell or script (the variable). The flag wins over the variable, which wins over the built-in default.

OptionEnv varEffect
--jsonREG_JSON=1Emit structured JSON instead of human text. watch emits JSON-lines.
-v, --verboseREG_VERBOSE=1More detailed output.
-q, --quiet—Suppress non-essential output. (A surprising type coercion is still reported.)
--sep=CHARREG_SEPPath display separator: \ (default) or /.
--help—Print help for the command and exit 0.
--version—Print the version and exit 0.

Mutating subcommands additionally accept:

OptionEnv varEffect
--layer NAMEREG_LAYERTarget layer for the write (default: the base layer).
-y, --yesREG_ASSUME_YES=1Skip the confirmation prompt on a destructive command.

Destructive commands (del -r, restore, layer del) prompt for confirmation when standard input is a terminal, and auto-proceed when it is not — so interactive use is guarded while scripts are never blocked. Set -y/--yes or REG_ASSUME_YES=1 to skip the prompt explicitly.


Reading #

reg get <key> [value] #

Read the effective (resolved) value. With a value, prints that value's data; with no value, lists the key's effective values (the default @ value first, then named values sorted case-insensitively) — a shorthand for ls --values-only.

OptionEffect
-L, --layersAnnotate the value with the layer it resolved from and its sequence number.
--rawWrite the value's raw bytes to standard output verbatim — for piping REG_BINARY data.
--no-followOperate on a symlink key itself rather than following it to its target.

The single-value default form prints data bare (no quotes; one element per line for REG_MULTI_SZ) so it pipes cleanly. -L shows the winning layer's provenance:

$ reg get Machine/System/KMES BufferCapacity
4194304

$ reg get Machine/App Theme -L
Theme = REG_SZ "dark"   (layer: policy, seq 7)

Only the winning value is shown; the full shadowed stack beneath it is not yet exposed by any client ABI (the -L flag will render the whole stack unchanged once that primitive lands). See Layers for what "effective" resolves against.

reg ls <key> #

One-level listing of a key's immediate subkeys and values.

OptionEffect
-l, --longLong form: for subkeys, child and value counts; for values, type and byte size.
--keys-onlyList subkeys only.
--values-onlyList values only.
$ reg ls Machine/System/KMES -l
BufferCapacity = REG_QWORD 4194304   (8 bytes)
MaxEventSize   = REG_DWORD 65536   (4 bytes)

reg tree <key> #

Recursively list the subkey tree rooted at key.

OptionEffect
--depth NLimit recursion to N levels.
--valuesInclude each node's values, not just its keys.
$ reg tree Machine/System --depth 2

reg info <key> #

Print a key's metadata: leaf name, subkey and value counts, last-write time, hive generation, security-descriptor size, and the volatile and symlink flags.

OptionEffect
--no-followInspect a symlink key itself rather than its target.
$ reg info Machine/System/KMES
path             Machine\System\KMES
name             KMES
subkeys          0
values           4
last_write_ns    1717243800000000000
hive_generation  42
sd_size          164
volatile         false
symlink          false

Writing #

reg set <key> <value> <data> #

Create or update a value. The value name (or @) and the data token are both required. Writes are tagged with --layer (default: base). See value literals for the data syntax.

OptionEffect
--layer NAMEWrite into layer NAME instead of the base layer.
-p, --parentsCreate any missing ancestor keys.
--expected-seq NCompare-and-swap guard: apply only if the value's current sequence is N; a mismatch exits 6 without writing.
$ reg set Machine/App Build 4096
set Machine\App Build = REG_DWORD 4096   (layer: base)

$ reg set Machine/App Servers multi:alpha,beta --layer policy

--expected-seq supports lock-free read-modify-write: read the value with -L to learn its sequence, then write back with --expected-seq set to that number; if another writer changed it in between, your write fails cleanly instead of clobbering theirs.

reg new <key> #

Create a key with no values. Reports whether the key was created or already existed.

OptionEffect
--layer NAMECreate the key in layer NAME.
-p, --parentsCreate any missing ancestor keys.
--volatileCreate a volatile (RAM-only) key that does not survive a reboot.
$ reg new Machine/App/Cache --volatile
created Machine\App\Cache   (layer: base)

reg del <key> [value] #

Delete a value, or a key. (Alias: delete.)

With a value, deletes this layer's entry for that value only — lower-layer entries resurface, because a per-layer delete is not a tombstone (use mask for that). With no value, deletes the key, which must be empty unless -r is given.

OptionEffect
--layer NAMEDelete from layer NAME.
-r, --recursiveDelete the key and all its descendants, in one transaction: all of them go, or, on any failure, none do. Links under the key are deleted, not followed. Every key in the tree is opened before any is deleted, so a tree larger than reg may hold open at once (1,024 files by default) is refused whole, as is one of more than 4,096 keys, which is all a transaction holds.
-y, --yesSkip the confirmation prompt (recursive deletes prompt on a terminal).
$ reg del Machine/App Legacy
deleted value Legacy from Machine\App

$ reg del Machine/App/Temp -r
Recursively delete key Machine\App\Temp and all its contents? [y/N] y
deleted Machine\App\Temp (3 keys)

See Deleting keys and values for how a per-layer delete differs from a tombstone.


Masking and hiding #

These commands expose LCS's tombstone and hide primitives, which mask lower-precedence state rather than removing a layer's own entry — the distinction that makes layers revertible. The layer is chosen with --layer (default: base).

reg mask <key> [value] / reg unmask <key> [value] #

mask sets a tombstone: a per-value marker in the target layer that hides that value from all layers below it. unmask clears it.

OptionEffect
--layer NAMEThe layer that carries the tombstone.
--allBlanket tombstone: mask all lower-layer values on the key (no value argument).

A value is required unless --all is given.

$ reg mask Machine/App ApiKey --layer policy
set tombstone on Machine\App ApiKey (layer: policy)

$ reg mask Machine/App --all --layer policy
set blanket tombstone on Machine\App (layer: policy)

reg hide <key> / reg unhide <key> #

hide installs a HIDDEN path entry in the target layer, masking the key's existence in that layer and below. unhide removes that layer's path entry, letting the key reappear.

OptionEffect
--layer NAMEThe layer that hides (or unhides) the key.
$ reg hide Machine/App/Debug --layer policy
hid Machine\App\Debug (layer: policy)

Layers #

reg layer ls #

List layers with name, precedence, enabled state, and (informational) owner SID, ordered by descending precedence. The base layer is always listed. A layer whose metadata values have the wrong type is marked (malformed metadata): the registry goes by what it last knew of that layer, not by what is shown.

OptionEffect
-l, --longLong form.
$ reg layer ls
policy                   prec=100    enabled   owner=S-1-5-32-544
base                     prec=0      enabled

reg layer new <name> #

Create a layer by writing its metadata key under Machine\System\Registry\Layers\, with its precedence and enabled state, in one transaction.

OptionEffect
--precedence NPrecedence (higher wins). A precedence above 0 requires SeTcbPrivilege; the tool attempts it and reports any denial.
--owner SIDRecord an informational owner SID, stored as a binary SID. Without it, the owner is whoever creates the layer.
--disabledCreate the layer disabled.
$ reg layer new policy --precedence 100 --owner S-1-5-32-544
created layer policy (precedence 100, enabled)

reg layer set <name> #

Modify an existing layer's metadata.

OptionEffect
--precedence NChange the precedence.
--enable / --disableEnable or disable the layer.
--owner SIDChange the informational owner SID.

reg layer del <name> #

Delete a layer — removes its metadata key; LCS tears down the layer's entries. Prompts for confirmation on a terminal.

$ reg layer del policy
Delete layer policy and all its entries? [y/N] y
deleted layer policy

Managing per-process private layer views is out of scope for reg; see private hives and layers.


Security descriptors #

reg sd <key> #

Show or set a key's security descriptor as SDDL, using the same codec as the sd tool, so its output is consistent. With no scope flags, the default is owner + group + DACL (a SACL requires the privileged ACCESS_SYSTEM_SECURITY right).

OptionEffect
--set SDDLApply the given SDDL. Without it, sd prints the current descriptor.
--ownerScope to the owner.
--groupScope to the group.
--daclScope to the DACL.
--saclScope to the SACL (needs ACCESS_SYSTEM_SECURITY).
$ reg sd Machine/App
O:BAG:BAD:(A;;KA;;;BA)(A;;KR;;;WD)

$ reg sd Machine/App --set 'O:BAG:BAD:(A;;KA;;;BA)' --owner --dacl
set security descriptor on Machine\App

A security-descriptor change takes effect on future opens only (existing handles keep the access mask they were granted). Security changes are not layered and are not undone by layer removal — they mutate the key object directly. See Access control on keys.


Symlinks #

reg link <key> <target> #

Create a symlink key pointing at the absolute target key path. This creates a key with the immutable symlink flag and a default REG_LINK value holding the target. Requires KEY_CREATE_LINK and SeTcbPrivilege/Administrator; the tool attempts it and reports any denial.

OptionEffect
--layer NAMECreate the link key in layer NAME.
$ reg link Machine/App/CurrentConfig Machine/App/Config/v3
linked Machine\App\CurrentConfig -> Machine\App\Config\v3 (layer: base)

get and info follow symlinks to their target by default; pass --no-follow to inspect the link key itself. See Advanced: registry links.


Watching #

reg watch <key> #

Arm a change watch and stream one event per change until interrupted (or until --count events). Each event faithfully means "something under the filter changed — re-read"; reg does not decode the change records' contents. With --json, emits one JSON object per line.

OptionEffect
--subtreeWatch descendant keys too, not just this key.
--filter LISTComma-separated subset of value, subkey, sd (default: all).
--count NExit after N events.
$ reg watch Machine/System/KMES --subtree --filter value
changed: Machine\System\KMES
changed: Machine\System\KMES

See Watching for changes for why a service watches instead of polling.


Batch, export, backup, and restore #

Two paths move a subtree around: export/apply are the portable, reviewable path (a diffable text or JSON document); backup/restore are the exact, privileged path (an opaque kernel snapshot).

reg apply <file> #

Apply a batch of operations to one hive in a single transaction — all-or-nothing. All operations must target one hive (a cross-hive batch fails with exit 4). - reads standard input.

OptionEffect
--dir DIRApply every batch file in DIR (sorted), each as its own transaction. A missing or empty directory applies nothing and succeeds.
--once-deleteDelete each batch file after it applies successfully (a drain).
-y, --yesSkip confirmation.

The batch format is JSON (canonical and exact) or a line-oriented text format; apply auto-detects (a leading { or [ means JSON). Text-format input is not yet implemented — supply JSON, or generate one with reg export --json. Text export works for review.

$ reg export --json Machine/App - | reg apply -
applied 4 keys

A JSON batch is an object with a keys array, parents before the keys under them. Each entry has a path, an optional values array (each value {name, type, data}, or hex in place of data, as in the output formats below), and an optional descriptor: security descriptor parts in SDDL, set on the key in the same transaction as its values. Only the parts the SDDL gives are set, so "descriptor": "S:(AL;CI;0x10002;;;WD)" sets the SACL and leaves the owner, group and DACL the key inherited. Setting a SACL needs SeSecurityPrivilege, as reg sd --sacl does; a descriptor that does not parse, or that gives no part at all, fails the batch before anything is written. export never writes a descriptor.

{"keys": [
  {"path": "Machine\\Generic"},
  {"path": "Machine\\Generic\\Events", "descriptor": "S:(AL;CI;0x10002;;;WD)"}
]}

A key entry with a member apply does not know is refused rather than ignored. Versions of reg before descriptor existed ignore it and report success without setting anything, so a batch that carries one needs a reg that knows it.

reg export <key> [file] #

Dump a subtree to the batch format. Omit file (or pass -) to write to standard output. Human-readable text by default; --json emits the canonical exact form.

OptionEffect
--layer NAMEExport one layer's view (default: the effective state).
$ reg export Machine/App app-config.reg

reg backup <key> <file> #

Write an opaque, exact, binary kernel snapshot of a key and its subtree to file. Requires SeBackupPrivilege.

$ reg backup Machine/System/KMES kmes.snap
backed up Machine\System\KMES -> kmes.snap

reg restore <key> <file> #

Replace a key and its entire subtree from a snapshot, in one transaction. Requires SeRestorePrivilege. Prompts for confirmation on a terminal.

$ reg restore Machine/System/KMES kmes.snap
Replace key Machine\System\KMES and its entire subtree from kmes.snap? [y/N] y
restored Machine\System\KMES from kmes.snap

See Backup and restore for when to reach for each path.


Output formats #

Default output is terse, human-readable, and grep-friendly. --json switches every command to structured output — a single self-contained JSON document, except watch, which emits JSON-lines (one object per event). In any value listing, the default (@) value is emitted first, then named values sorted case-insensitively.

Type formatting on read:

Registry typeHuman formJSON form
REG_SZ / REG_EXPAND_SZthe string{"type":"sz","data":"…"}
REG_DWORD / REG_QWORDdecimal{"type":"dword","data":42}
REG_MULTI_SZone element per line{"type":"multi","data":["a","b"]}
REG_BINARYhex{"type":"binary","data":"deadbeef"}
REG_LINKthe target path{"type":"link","data":"…"}

The registry doesn't check that a value's bytes fit its type. Bytes that don't are shown as hex, in both forms, under the value's own type. Examples are a string that is not UTF-8, a number of the wrong length, and REG_NONE with data. In the JSON form such a value has a hex member, its bytes exactly, in place of data, as {"type":"sz","hex":"ff00"}: it survives export --json and apply unchanged.

Exit status #

CodeMeaningTypical cause
0Success.—
1Usage error.Bad arguments; a required option missing.
2Key or value not found.ENOENT.
3Access denied.EACCES, EPERM — the kernel refused the operation.
4Invalid specification.Bad path, type, or literal; a cross-hive batch; a name too long (EINVAL, EXDEV, ENAMETOOLONG).
5Syscall or source failure.EIO, ETIMEDOUT, ENOSPC, ENOMEM.
6Compare-and-swap conflict.EAGAIN — an --expected-seq guard did not match; the value changed under you.

A denial (3) reports the operation, the target, and, where relevant, the access that was required — in the style of the sd and token tools.

See also #

  • regman — the registry manual: what a key or value means, as opposed to what it is set to. Consult it before you reg set.
  • Keys, values, and types — the data model reg addresses.
  • Layers — what "effective" resolves against, and what --layer, mask, and hide operate on.
  • Access control on keys — the check every reg operation goes through.

Peios Learn — documentation for the Peios project.

Built with Trail.