1---
2title: JSON User Records
3category: Users, Groups and Home Directories
4layout: default
5SPDX-License-Identifier: LGPL-2.1-or-later
6---
7
8# JSON User Records
9
10systemd optionally processes user records that go beyond the classic UNIX (or
11glibc NSS) `struct passwd`. Various components of systemd are able to provide
12and consume records in a more extensible format of a dictionary of key/value
13pairs, encoded as JSON. Specifically:
14
151. [`systemd-homed.service`](https://www.freedesktop.org/software/systemd/man/systemd-homed.service.html)
16   manages `human` user home directories and embeds these JSON records
17   directly in the home directory images
18   (see [Home Directories](HOME_DIRECTORY.md) for details).
19
202. [`pam_systemd`](https://www.freedesktop.org/software/systemd/man/pam_systemd.html)
21   processes these JSON records for users that log in, and applies various
22   settings to the activated session, including environment variables, nice
23   levels and more.
24
253. [`systemd-logind.service`](https://www.freedesktop.org/software/systemd/man/systemd-logind.service.html)
26   processes these JSON records of users that log in, and applies various
27   resource management settings to the per-user slice units it manages. This
28   allows setting global limits on resource consumption by a specific user.
29
304. [`nss-systemd`](https://www.freedesktop.org/software/systemd/man/nss-systemd.html)
31   is a glibc NSS module that synthesizes classic NSS records from these JSON
32   records, providing full backwards compatibility with the classic UNIX APIs
33   both for look-up and enumeration.
34
355. The service manager (PID 1) exposes dynamic users (i.e. users synthesized as
36   effect of `DynamicUser=` in service unit files) as these advanced JSON
37   records, making them discoverable to the rest of the system.
38
396. [`systemd-userdbd.service`](https://www.freedesktop.org/software/systemd/man/systemd-userdbd.service.html)
40   is a small service that can translate UNIX/glibc NSS records to these JSON
41   user records. It also provides a unified [Varlink](https://varlink.org/) API
42   for querying and enumerating records of this type, optionally acquiring them
43   from various other services.
44
45JSON user records may contain various fields that are not available in `struct
46passwd`, and are extensible for other applications. For example, the record may
47contain information about:
48
491. Additional security credentials (PKCS#11 security token information,
50   biometrical authentication information, SSH public key information)
51
522. Additional user metadata, such as a picture, email address, location string,
53   preferred language or timezone
54
553. Resource Management settings (such as CPU/IO weights, memory and tasks
56   limits, classic UNIX resource limits or nice levels)
57
584. Runtime parameters such as environment variables or the `nodev`, `noexec`,
59   `nosuid` flags to use for the home directory
60
615. Information about where to mount the home directory from
62
63And various other things. The record is intended to be extensible, for example
64the following extensions are envisioned:
65
661. Windows network credential information
67
682. Information about default IMAP, SMTP servers to use for this user
69
703. Parental control information to enforce on this user
71
724. Default parameters for backup applications and similar
73
74Similar to JSON User Records there are also
75[JSON Group Records](GROUP_RECORD.md) that encapsulate UNIX groups.
76
77JSON User Records may be transferred or written to disk in various protocols
78and formats. To inquire about such records defined on the local system use the
79[User/Group Lookup API via Varlink](USER_GROUP_API.md). User/group records may
80also be dropped in number of drop-in directories as files. See
81[`nss-systemd(8)`](https://www.freedesktop.org/software/systemd/man/nss-systemd.html)
82for details.
83
84## Why JSON?
85
86JSON is nicely extensible and widely used. In particular it's easy to
87synthesize and process with numerous programming languages. It's particularly
88popular in the web communities, which hopefully should make it easy to link
89user credential data from the web and from local systems more closely together.
90
91Please note that this specification assumes that JSON numbers may cover the full
92integer range of -2^63 … 2^64-1 without loss of precision (i.e. INT64_MIN …
93UINT64_MAX). Please read, write and process user records as defined by this
94specification only with JSON implementations that provide this number range.
95
96## General Structure
97
98The JSON user records generated and processed by systemd follow a general
99structure, consisting of seven distinct "sections". Specifically:
100
1011. Various fields are placed at the top-level of user record (the `regular`
102   section). These are generally fields that shall apply unconditionally to the
103   user in all contexts, are portable and not security sensitive.
104
1052. A number of fields are located in the `privileged` section (a sub-object of
106   the user record). Fields contained in this object are security sensitive,
107   i.e. contain information that the user and the administrator should be able
108   to see, but other users should not. In many ways this matches the data
109   stored in `/etc/shadow` in classic Linux user accounts, i.e. includes
110   password hashes and more. Algorithmically, when a user record is passed to
111   an untrusted client, by monopolizing such sensitive records in a single
112   object field we can easily remove it from view.
113
1143. A number of fields are located in objects inside the `perMachine` section
115   (an array field of the user record). Primarily these are resource
116   management-related fields, as those tend to make sense on a specific system
117   only, e.g. limiting a user's memory use to 1G only makes sense on a specific
118   system that has more than 1G of memory. Each object inside the `perMachine`
119   array comes with a `matchMachineId` or `matchHostname` field which indicate
120   which systems to apply the listed settings to. Note that many fields
121   accepted in the `perMachine` section can also be set at the top level (the
122   `regular` section), where they define the fallback if no matching object in
123   `perMachine` is found.
124
1254. Various fields are located in the `binding` section (a sub-sub-object of the
126   user record; an intermediary object is inserted which is keyed by the
127   machine ID of the host). Fields included in this section "bind" the object
128   to a specific system. They generally include non-portable information about
129   paths or UID assignments, that are true on a specific system, but not
130   necessarily on others, and which are managed automatically by some user
131   record manager (such as `systemd-homed`). Data in this section is considered
132   part of the user record only in the local context, and is generally not
133   ported to other systems. Due to that it is not included in the reduced user
134   record the cryptographic signature defined in the `signature` section is
135   calculated on. In `systemd-homed` this section is also removed when the
136   user's record is stored in the `~/.identity` file in the home directory, so
137   that every system with access to the home directory can manage these
138   `binding` fields individually. Typically, the binding section is persisted
139   to the local disk.
140
1415. Various fields are located in the `status` section (a sub-sub-object of the
142   user record, also with an intermediary object between that is keyed by the
143   machine ID, similar to the way the `binding` section is organized). This
144   section is augmented during runtime only, and never persisted to disk. The
145   idea is that this section contains information about current runtime
146   resource usage (for example: currently used disk space of the user), that
147   changes dynamically but is otherwise immediately associated with the user
148   record and for many purposes should be considered to be part of the user
149   record.
150
1516. The `signature` section contains one or more cryptographic signatures of a
152   reduced version of the user record. This is used to ensure that only user
153   records defined by a specific source are accepted on a system, by validating
154   the signature against the set of locally accepted signature public keys. The
155   signature is calculated from the JSON user record with all sections removed,
156   except for `regular`, `privileged`, `perMachine`. Specifically, `binding`,
157   `status`, `signature` itself and `secret` are removed first and thus not
158   covered by the signature. This section is optional, and is only used when
159   cryptographic validation of user records is required (as it is by
160   `systemd-homed.service` for example).
161
1627. The `secret` section contains secret user credentials, such as password or
163   PIN information. This data is never persisted, and never returned when user
164   records are inquired by a client, privileged or not. This data should only
165   be included in a user record very briefly, for example when certain very
166   specific operations are executed. For example, in tools such as
167   `systemd-homed` this section may be included in user records, when creating
168   a new home directory, as passwords and similar credentials need to be
169   provided to encrypt the home directory with.
170
171Here's a tabular overview of the sections and their properties:
172
173| Section    | Included in Signature | Persistent | Security Sensitive | Contains Host-Specific Data |
174|------------|-----------------------|------------|--------------------|-----------------------------|
175| regular    | yes                   | yes        | no                 | no                          |
176| privileged | yes                   | yes        | yes                | no                          |
177| perMachine | yes                   | yes        | no                 | yes                         |
178| binding    | no                    | yes        | no                 | yes                         |
179| status     | no                    | no         | no                 | yes                         |
180| signature  | no                    | yes        | no                 | no                          |
181| secret     | no                    | no         | yes                | no                          |
182
183Note that services providing user records to the local system are free to
184manage only a subset of these sections and never include the others in
185them. For example, a service that has no concept of signed records (for example
186because the records it manages are inherently trusted anyway) does not have to
187bother with the `signature` section. A service that only defines records in a
188strictly local context and without signatures doesn't have to deal with the
189`perMachine` or `binding` sections and can include its data exclusively in the
190regular section. A service that uses a separate, private channel for
191authenticating users (or that doesn't have a concept of authentication at all)
192does not need to be concerned with the `secret` section of user records, as
193the fields included therein are only useful when executing authentication
194operations natively against JSON user records.
195
196The `systemd-homed` manager uses all seven sections for various
197purposes. Inside the home directories (and if the LUKS2 backend is used, also
198in the LUKS2 header) a user record containing the `regular`, `privileged`,
199`perMachine` and `signature` sections is stored. `systemd-homed` also stores a
200version of the record on the host, with the same four sections and augmented
201with an additional, fifth `binding` section. When a local client enquires about
202a user record managed by `systemd-homed` the service will add in some
203additional information about the user and home directory in the `status`
204section — this version is only transferred via IPC and never written to
205disk. Finally the `secret` section is used during authentication operations via
206IPC to transfer the user record along with its authentication tokens in one go.
207
208## Fields in the `regular` section
209
210As mentioned, the `regular` section's fields are placed at the top level
211object. The following fields are currently defined:
212
213`userName` → The UNIX user name for this record. Takes a string with a valid
214UNIX user name. This field is the only mandatory field, all others are
215optional. Corresponds with the `pw_name` field of of `struct passwd` and the
216`sp_namp` field of `struct spwd` (i.e. the shadow user record stored in
217`/etc/shadow`). See [User/Group Name Syntax](USER_NAMES.md) for
218the (relaxed) rules the various systemd components enforce on user/group names.
219
220`realm` → The "realm" a user is defined in. This concept allows distinguishing
221users with the same name that originate in different organizations or
222installations. This should take a string in DNS domain syntax, but doesn't have
223to refer to an actual DNS domain (though it is recommended to use one for
224this). The idea is that the user `lpoetter` in the `redhat.com` realm might be
225distinct from the same user in the `poettering.hq` realm. User records for the
226same user name that have different realm fields are considered referring to
227different users. When updating a user record it is required that any new
228version has to match in both `userName` and `realm` field. This field is
229optional, when unset the user should not be considered part of any realm. A
230user record with a realm set is never compatible (for the purpose of updates,
231see above) with a user record without one set, even if the `userName` field matches.
232
233`realName` → The real name of the user, a string. This should contain the
234user's real ("human") name, and corresponds loosely to the GECOS field of
235classic UNIX user records. When converting a `struct passwd` to a JSON user
236record this field is initialized from GECOS (i.e. the `pw_gecos` field), and
237vice versa when converting back. That said, unlike GECOS this field is supposed
238to contain only the real name and no other information. This field must not
239contain control characters (such as `\n`) or colons (`:`), since those are used
240as record separators in classic `/etc/passwd` files and similar formats.
241
242`emailAddress` → The email address of the user, formatted as
243string. [`pam_systemd`](https://www.freedesktop.org/software/systemd/man/pam_systemd.html)
244initializes the `$EMAIL` environment variable from this value for all login
245sessions.
246
247`iconName` → The name of an icon picked by the user, for example for the
248purpose of an avatar. This must be a string, and should follow the semantics
249defined in the [Icon Naming
250Specification](https://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html).
251
252`location` → A free-form location string describing the location of the user,
253if that is applicable. It's probably wise to use a location string processable
254by geo-location subsystems, but this is not enforced nor required. Example:
255`Berlin, Germany` or `Basement, Room 3a`.
256
257`disposition` → A string, one of `intrinsic`, `system`, `dynamic`, `regular`,
258`container`, `reserved`. If specified clarifies the disposition of the user,
259i.e. the context it is defined in. For regular, "human" users this should be
260`regular`, for system users (i.e. users that system services run under, and
261similar) this should be `system`. The `intrinsic` disposition should be used
262only for the two users that have special meaning to the OS kernel itself,
263i.e. the `root` and `nobody` users. The `container` string should be used for
264users that are used by an OS container, and hence will show up in `ps` listings
265and such, but are only defined in container context. Finally `reserved` should
266be used for any users outside of these use-cases. Note that this property is
267entirely optional and applications are assumed to be able to derive the
268disposition of a user automatically from a record even in absence of this
269field, based on other fields, for example the numeric UID. By setting this
270field explicitly applications can override this default determination.
271
272`lastChangeUSec` → An unsigned 64bit integer value, referring to a timestamp in µs
273since the epoch 1970, indicating when the user record (specifically, any of the
274`regular`, `privileged`, `perMachine` sections) was last changed. This field is
275used when comparing two records of the same user to identify the newer one, and
276is used for example for automatic updating of user records, where appropriate.
277
278`lastPasswordChangeUSec` → Similar, also an unsigned 64bit integer value,
279indicating the point in time the password (or any authentication token) of the
280user was last changed. This corresponds to the `sp_lstchg` field of `struct
281spwd`, i.e. the matching field in the user shadow database `/etc/shadow`,
282though provides finer resolution.
283
284`shell` → A string, referring to the shell binary to use for terminal logins of
285this user. This corresponds with the `pw_shell` field of `struct passwd`, and
286should contain an absolute file system path. For system users not suitable for
287terminal log-in this field should not be set.
288
289`umask` → The `umask` to set for the user's login sessions. Takes an
290integer. Note that usually on UNIX the umask is noted in octal, but JSON's
291integers are generally written in decimal, hence in this context we denote it
292umask in decimal too. The specified value should be in the valid range for
293umasks, i.e. 0000…0777 (in octal as typical in UNIX), or 0…511 (in decimal, how
294it actually appears in the JSON record). This `umask` is automatically set by
295[`pam_systemd`](https://www.freedesktop.org/software/systemd/man/pam_systemd.html)
296for all login sessions of the user.
297
298`environment` → An array of strings, each containing an environment variable
299and its value to set for the user's login session, in a format compatible with
300[`putenv()`](http://man7.org/linux/man-pages/man3/putenv.3.html). Any
301environment variable listed here is automatically set by
302[`pam_systemd`](https://www.freedesktop.org/software/systemd/man/pam_systemd.html)
303for all login sessions of the user.
304
305`timeZone` → A string indicating a preferred timezone to use for the user. When
306logging in
307[`pam_systemd`](https://www.freedesktop.org/software/systemd/man/pam_systemd.html)
308will automatically initialize the `$TZ` environment variable from this
309string. The string should be a `tzdata` compatible location string, for
310example: `Europe/Berlin`.
311
312`preferredLanguage` → A string indicating the preferred language/locale for the
313user. When logging in
314[`pam_systemd`](https://www.freedesktop.org/software/systemd/man/pam_systemd.html)
315will automatically initialize the `$LANG` environment variable from this
316string. The string hence should be in a format compatible with this environment
317variable, for example: `de_DE.UTF8`.
318
319`niceLevel` → An integer value in the range -20…19. When logging in
320[`pam_systemd`](https://www.freedesktop.org/software/systemd/man/pam_systemd.html)
321will automatically initialize the login process' nice level to this value with,
322which is then inherited by all the user's processes, see
323[`setpriority()`](http://man7.org/linux/man-pages/man2/setpriority.2.html) for
324more information.
325
326`resourceLimits` → An object, where each key refers to a Linux resource limit
327(such as `RLIMIT_NOFILE` and similar). Their values should be an object with
328two keys `cur` and `max` for the soft and hard resource limit. When logging in
329[`pam_systemd`](https://www.freedesktop.org/software/systemd/man/pam_systemd.html)
330will automatically initialize the login process' resource limits to these
331values, which is then inherited by all the user's processes, see
332[`setrlimit()`](http://man7.org/linux/man-pages/man2/setrlimit.2.html) for more
333information.
334
335`locked` → A boolean value. If true, the user account is locked, the user may
336not log in. If this field is missing it should be assumed to be false,
337i.e. logins are permitted. This field corresponds to the `sp_expire` field of
338`struct spwd` (i.e. the `/etc/shadow` data for a user) being set to zero or
339one.
340
341`notBeforeUSec` → An unsigned 64bit integer value, indicating a time in µs since
342the UNIX epoch (1970) before which the record should be considered invalid for
343the purpose of logging in.
344
345`notAfterUSec` → Similar, but indicates the point in time *after* which logins
346shall not be permitted anymore. This corresponds to the `sp_expire` field of
347`struct spwd`, when it is set to a value larger than one, but provides finer
348granularity.
349
350`storage` → A string, one of `classic`, `luks`, `directory`, `subvolume`,
351`fscrypt`, `cifs`. Indicates the storage mechanism for the user's home
352directory. If `classic` the home directory is a plain directory as in classic
353UNIX. When `directory`, the home directory is a regular directory, but the
354`~/.identity` file in it contains the user's user record, so that the directory
355is self-contained. Similar, `subvolume` is a `btrfs` subvolume that also
356contains a `~/.identity` user record; `fscrypt` is an `fscrypt`-encrypted
357directory, also containing the `~/.identity` user record; `luks` is a per-user
358LUKS volume that is mounted as home directory, and `cifs` a home directory
359mounted from a Windows File Share. The five latter types are primarily used by
360`systemd-homed` when managing home directories, but may be used if other
361managers are used too. If this is not set, `classic` is the implied default.
362
363`diskSize` → An unsigned 64bit integer, indicating the intended home directory
364disk space in bytes to assign to the user. Depending on the selected storage
365type this might be implemented differently: for `luks` this is the intended size
366of the file system and LUKS volume, while for the others this likely translates
367to classic file system quota settings.
368
369`diskSizeRelative` → Similar to `diskSize` but takes a relative value, but
370specifies a fraction of the available disk space on the selected storage medium
371to assign to the user. This unsigned integer value is normalized to 2^32 =
372100%.
373
374`skeletonDirectory` → Takes a string with the absolute path to the skeleton
375directory to populate a new home directory from. This is only used when a home
376directory is first created, and defaults to `/etc/skel` if not defined.
377
378`accessMode` → Takes an unsigned integer in the range 0…511 indicating the UNIX
379access mask for the home directory when it is first created.
380
381`tasksMax` → Takes an unsigned 64bit integer indicating the maximum number of
382tasks the user may start in parallel during system runtime. This counts
383all tasks (i.e. threads, where each process is at least one thread) the user starts or that are
384forked from these processes even if the user identity is changed (for example
385by setuid binaries/`su`/`sudo` and similar).
386[`systemd-logind.service`](https://www.freedesktop.org/software/systemd/man/systemd-logind.service.html)
387enforces this by setting the `TasksMax` slice property for the user's slice
388`user-$UID.slice`.
389
390`memoryHigh`/`memoryMax` → These take unsigned 64bit integers indicating upper
391memory limits for all processes of the user (plus all processes forked off them
392that might have changed user identity), in bytes. Enforced by
393[`systemd-logind.service`](https://www.freedesktop.org/software/systemd/man/systemd-logind.service.html),
394similar to `tasksMax`.
395
396`cpuWeight`/`ioWeight` → These take unsigned integers in the range 1…10000
397(defaults to 100) and configure the CPU and IO scheduling weights for the
398user's processes as a whole. Also enforced by
399[`systemd-logind.service`](https://www.freedesktop.org/software/systemd/man/systemd-logind.service.html),
400similar to `tasksMax`, `memoryHigh` and `memoryMax`.
401
402`mountNoDevices`/`mountNoSuid`/`mountNoExecute` → Three booleans that control
403the `nodev`, `nosuid`, `noexec` mount flags of the user's home
404directories. Note that these booleans are only honored if the home directory
405is managed by a subsystem such as `systemd-homed.service` that automatically
406mounts home directories on login.
407
408`cifsDomain` → A string indicating the Windows File Sharing domain (CIFS) to
409use. This is generally useful, but particularly when `cifs` is used as storage
410mechanism for the user's home directory, see above.
411
412`cifsUserName` → A string indicating the Windows File Sharing user name (CIFS)
413to associate this user record with. This is generally useful, but particularly
414useful when `cifs` is used as storage mechanism for the user's home directory,
415see above.
416
417`cifsService` → A string indicating the Windows File Share service (CIFS) to
418mount as home directory of the user on login. Should be in format
419`//<host>/<service>/<directory/…>`. The directory part is optional. If missing
420the top-level directory of the CIFS share is used.
421
422`cifsExtraMountOptions` → A string with additional mount options to pass to
423`mount.cifs` when mounting the home directory CIFS share.
424
425`imagePath` → A string with an absolute file system path to the file, directory
426or block device to use for storage backing the home directory. If the `luks`
427storage is used, this refers to the loopback file or block device node to store
428the LUKS volume on. For `fscrypt`, `directory`, `subvolume` this refers to the
429directory to bind mount as home directory on login. Not defined for `classic`
430or `cifs`.
431
432`homeDirectory` → A string with an absolute file system path to the home
433directory. This is where the image indicated in `imagePath` is mounted to on
434login and thus indicates the application facing home directory while the home
435directory is active, and is what the user's `$HOME` environment variable is set
436to during log-in. It corresponds to the `pw_dir` field of `struct passwd`.
437
438`uid` → An unsigned integer in the range 0…4294967295: the numeric UNIX user ID (UID) to
439use for the user.  This corresponds to the `pw_uid` field of `struct passwd`.
440
441`gid` → An unsigned integer in the range 0…4294967295: the numeric UNIX group
442ID (GID) to use for the user. This corresponds to the `pw_gid` field of
443`struct passwd`.
444
445`memberOf` → An array of strings, each indicating a UNIX group this user shall
446be a member of. The listed strings must be valid group names, but it is not
447required that all groups listed exist in all contexts: any entry for which no
448group exists should be silently ignored.
449
450`fileSystemType` → A string, one of `ext4`, `xfs`, `btrfs` (possibly others) to
451use as file system for the user's home directory. This is primarily relevant
452when the storage mechanism used is `luks` as a file system to use inside the
453LUKS container must be selected.
454
455`partitionUuid` → A string containing a lower-case, text-formatted UUID, referencing
456the GPT partition UUID the home directory is located in. This is primarily
457relevant when the storage mechanism used is `luks`.
458
459`luksUuid` → A string containing a lower-case, text-formatted UUID, referencing
460the LUKS volume UUID the home directory is located in. This is primarily
461relevant when the storage mechanism used is `luks`.
462
463`fileSystemUuid` → A string containing a lower-case, text-formatted UUID,
464referencing the file system UUID the home directory is located in. This is
465primarily relevant when the storage mechanism used is `luks`.
466
467`luksDiscard` → A boolean. If true and `luks` storage is used, controls whether
468the loopback block devices, LUKS and the file system on top shall be used in
469`discard` mode, i.e. erased sectors should always be returned to the underlying
470storage. If false and `luks` storage is used turns this behavior off. In
471addition, depending on this setting an `FITRIM` or `fallocate()` operation is
472executed to make sure the image matches the selected option.
473
474`luksOfflineDiscard` → A boolean. Similar to `luksDiscard`, it controls whether
475to trim/allocate the file system/backing file when deactivating the home
476directory.
477
478`luksExtraMountOptions` → A string with additional mount options to append to
479the default mount options for the file system in the LUKS volume.
480
481`luksCipher` → A string, indicating the cipher to use for the LUKS storage mechanism.
482
483`luksCipherMode` → A string, selecting the cipher mode to use for the LUKS storage mechanism.
484
485`luksVolumeKeySize` → An unsigned integer, indicating the volume key length in
486bytes to use for the LUKS storage mechanism.
487
488`luksPbkdfHashAlgorithm` → A string, selecting the hash algorithm to use for
489the PBKDF operation for the LUKS storage mechanism.
490
491`luksPbkdfType` → A string, indicating the PBKDF type to use for the LUKS storage mechanism.
492
493`luksPbkdfTimeCostUSec` → An unsigned 64bit integer, indicating the intended
494time cost for the PBKDF operation, when the LUKS storage mechanism is used, in
495µs.
496
497`luksPbkdfMemoryCost` → An unsigned 64bit integer, indicating the intended
498memory cost for the PBKDF operation, when LUKS storage is used, in bytes.
499
500`luksPbkdfParallelThreads` → An unsigned 64bit integer, indicating the intended
501required parallel threads for the PBKDF operation, when LUKS storage is used.
502
503`autoResizeMode` → A string, one of `off`, `grow`, `shrink-and-grow`. Unless
504set to `off`, controls whether the home area shall be grown automatically to
505the size configured in `diskSize` automatically at login time. If set to
506`shrink-and-grown` the home area is also shrunk to the minimal size possible
507(as dictated by used disk space and file system constraints) on logout.
508
509`rebalanceWeight` → An unsigned integer, `null` or a boolean. Configures the
510free disk space rebalancing weight for the home area. The integer must be in
511the range 1…10000 to configure an explicit weight. If unset, or set to `null`
512or `true` the default weight of 100 is implied. If set to 0 or `false`
513rebalancing is turned off for this home area.
514
515`service` → A string declaring the service that defines or manages this user
516record. It is recommended to use reverse domain name notation for this. For
517example, if `systemd-homed` manages a user a string of `io.systemd.Home` is
518used for this.
519
520`rateLimitIntervalUSec` → An unsigned 64bit integer that configures the
521authentication rate limiting enforced on the user account. This specifies a
522timer interval (in µs) within which to count authentication attempts. When the
523counter goes above the value configured n `rateLimitIntervalBurst` log-ins are
524temporarily refused until the interval passes.
525
526`rateLimitIntervalBurst` → An unsigned 64bit integer, closely related to
527`rateLimitIntervalUSec`, that puts a limit on authentication attempts within
528the configured time interval.
529
530`enforcePasswordPolicy` → A boolean. Configures whether to enforce the system's
531password policy when creating the home directory for the user or changing the
532user's password. By default the policy is enforced, but if this field is false
533it is bypassed.
534
535`autoLogin` → A boolean. If true the user record is marked as suitable for
536auto-login. Systems are supposed to automatically log in a user marked this way
537during boot, if there's exactly one user on it defined this way.
538
539`stopDelayUSec` → An unsigned 64bit integer, indicating the time in µs the
540per-user service manager is kept around after the user fully logged out.  This
541value is honored by
542[`systemd-logind.service`](https://www.freedesktop.org/software/systemd/man/systemd-logind.service.html). If
543set to zero the per-user service manager is immediately terminated when the
544user logs out, and longer values optimize high-frequency log-ins as the
545necessary work to set up and tear down a log-in is reduced if the service
546manager stays running.
547
548`killProcesses` → A boolean. If true all processes of the user are
549automatically killed when the user logs out. This is enforced by
550[`systemd-logind.service`](https://www.freedesktop.org/software/systemd/man/systemd-logind.service.html). If
551false any processes left around when the user logs out are left running.
552
553`passwordChangeMinUSec`/`passwordChangeMaxUSec` → An unsigned 64bit integer,
554encoding how much time has to pass at least/at most between password changes of
555the user. This corresponds with the `sp_min` and `sp_max` fields of `struct
556spwd` (i.e. the `/etc/shadow` entries of the user), but offers finer
557granularity.
558
559`passwordChangeWarnUSec` → An unsigned 64bit integer, encoding how much time to
560warn the user before their password expires, in µs. This corresponds with the
561`sp_warn` field of `struct spwd`.
562
563`passwordChangeInactiveUSec` → An unsigned 64bit integer, encoding how much
564time has to pass after the password expired that the account is
565deactivated. This corresponds with the `sp_inact` field of `struct spwd`.
566
567`passwordChangeNow` → A boolean. If true the user has to change their password
568on next login. This corresponds with the `sp_lstchg` field of `struct spwd`
569being set to zero.
570
571`pkcs11TokenUri` → An array of strings, each with an RFC 7512 compliant PKCS#11
572URI referring to security token (or smart card) of some form, that shall be
573associated with the user and may be used for authentication. The URI is used to
574search for an X.509 certificate and associated private key that may be used to
575decrypt an encrypted secret key that is used to unlock the user's account (see
576below). It's undefined how precise the URI is: during log-in it is tested
577against all plugged in security tokens and if there's exactly one matching
578private key found with it it is used.
579
580`fido2HmacCredential` → An array of strings, each with a Base64-encoded FIDO2
581credential ID that shall be used for authentication with FIDO2 devices that
582implement the `hmac-secret` extension. The salt to pass to the FIDO2 device is
583found in `fido2HmacSalt`.
584
585`recoveryKeyType` → An array of strings, each indicating the type of one
586recovery key. The only supported recovery key type at the moment is `modhex64`,
587for details see the description of `recoveryKey` below. An account may have any
588number of recovery keys defined, and the array should have one entry for each.
589
590`privileged` → An object, which contains the fields of the `privileged` section
591of the user record, see below.
592
593`perMachine` → An array of objects, which contain the `perMachine` section of
594the user record, and thus fields to apply on specific systems only, see below.
595
596`binding` → An object, keyed by machine IDs formatted as strings, pointing
597to objects that contain the `binding` section of the user record,
598i.e. additional fields that bind the user record to a specific machine, see
599below.
600
601`status` → An object, keyed by machine IDs formatted as strings, pointing to
602objects that contain the `status` section of the user record, i.e. additional
603runtime fields that expose the current status of the user record on a specific
604system, see below.
605
606`signature` → An array of objects, which contain cryptographic signatures of
607the user record, i.e. the fields of the `signature` section of the user record,
608see below.
609
610`secret` → An object, which contains the fields of the `secret` section of the
611user record, see below.
612
613## Fields in the `privileged` section
614
615As mentioned, the `privileged` section is encoded in a sub-object of the user
616record top-level object, in the `privileged` field. Any data included in this
617object shall only be visible to the administrator and the user themselves, and
618be suppressed implicitly when other users get access to a user record. It thus
619takes the role of the `/etc/shadow` records for each user, which has similarly
620restrictive access semantics. The following fields are currently defined:
621
622`passwordHint` → A user-selected password hint in free-form text. This should
623be a string like "What's the name of your first pet?", but is entirely for the
624user to choose.
625
626`hashedPassword` → An array of strings, each containing a hashed UNIX password
627string, in the format
628[`crypt(3)`](http://man7.org/linux/man-pages/man3/crypt.3.html) generates. This
629corresponds with `sp_pwdp` field of `struct spwd` (and in a way the `pw_passwd`
630field of `struct passwd`).
631
632`sshAuthorizedKeys` → An array of strings, each listing an SSH public key that
633is authorized to access the account. The strings should follow the same format
634as the lines in the traditional `~/.ssh/authorized_key` file.
635
636`pkcs11EncryptedKey` → An array of objects. Each element of the array should be
637an object consisting of three string fields: `uri` shall contain a PKCS#11
638security token URI, `data` shall contain a Base64-encoded encrypted key and
639`hashedPassword` shall contain a UNIX password hash to test the key
640against. Authenticating with a security token against this account shall work
641as follows: the encrypted secret key is converted from its Base64
642representation into binary, then decrypted with the PKCS#11 `C_Decrypt()`
643function of the PKCS#11 module referenced by the specified URI, using the
644private key found on the same token. The resulting decrypted key is then
645Base64-encoded and tested against the specified UNIX hashed password. The
646Base64-encoded decrypted key may also be used to unlock further resources
647during log-in, for example the LUKS or `fscrypt` storage backend. It is
648generally recommended that for each entry in `pkcs11EncryptedKey` there's also
649a matching one in `pkcs11TokenUri` and vice versa, with the same URI, appearing
650in the same order, but this should not be required by applications processing
651user records.
652
653`fido2HmacSalt` → An array of objects, implementing authentication support with
654FIDO2 devices that implement the `hmac-secret` extension. Each element of the
655array should be an object consisting of three string fields: `credential`,
656`salt`, `hashedPassword`, and three boolean fields: `up`, `uv` and
657`clientPin`. The first two string fields shall contain Base64-encoded binary
658data: the FIDO2 credential ID and the salt value to pass to the FIDO2
659device. During authentication this salt along with the credential ID is sent to
660the FIDO2 token, which will HMAC hash the salt with its internal secret key and
661return the result. This resulting binary key should then be Base64-encoded and
662used as string password for the further layers of the stack. The
663`hashedPassword` field of the `fido2HmacSalt` field shall be a UNIX password
664hash to test this derived secret key against for authentication. The `up`, `uv`
665and `clientPin` booleans map to the FIDO2 concepts of the same name and encode
666whether the `uv`/`up` options are enabled during the authentication, and
667whether a PIN shall be required. It is generally recommended that for each
668entry in `fido2HmacSalt` there's also a matching one in `fido2HmacCredential`,
669and vice versa, with the same credential ID, appearing in the same order, but
670this should not be required by applications processing user records.
671
672`recoveryKey`→ An array of objects, each defining a recovery key. The object
673has two mandatory fields: `type` indicates the type of recovery key. The only
674currently permitted value is the string `modhex64`. The `hashedPassword` field
675contains a UNIX password hash of the normalized recovery key. Recovery keys are
676in most ways similar to regular passwords, except that they are generated by
677the computer, not chosen by the user, and are longer. Currently, the only
678supported recovery key format is `modhex64`, which consists of 64
679[modhex](https://developers.yubico.com/yubico-c/Manuals/modhex.1.html)
680characters (i.e. 256bit of information), in groups of 8 chars separated by
681dashes,
682e.g. `lhkbicdj-trbuftjv-tviijfck-dfvbknrh-uiulbhui-higltier-kecfhkbk-egrirkui`. Recovery
683keys should be accepted wherever regular passwords are. The `recoveryKey` field
684should always be accompanied by a `recoveryKeyType` field (see above), and each
685entry in either should map 1:1 to an entry in the other, in the same order and
686matching the type. When accepting a recovery key it should be brought
687automatically into normalized form, i.e. the dashes inserted when missing, and
688converted into lowercase before tested against the UNIX password hash, so that
689recovery keys are effectively case-insensitive.
690
691## Fields in the `perMachine` section
692
693As mentioned, the `perMachine` section contains settings that shall apply to
694specific systems only. This is primarily interesting for resource management
695properties as they tend to require a per-system focus, however they may be used
696for other purposes too.
697
698The `perMachine` field in the top-level object is an array of objects. When
699processing the user record first the various fields on the top-level object
700should be used. Then this array should be iterated in order, and the various
701settings be applied that match either the indicated machine ID or host
702name. There may be multiple array entries that match a specific system, in
703which case all the object's setting should be applied. If the same option is
704set in the top-level object as in a per-machine object the latter wins and
705entirely undoes the setting in the top-level object (i.e. no merging of
706properties that are arrays themselves is done). If the same option is set in
707multiple per-machine objects the one specified later in the array wins (and
708here too no merging of individual fields is done, the later field always wins
709in full).
710
711The following fields are defined in this section:
712
713`matchMachineId` → An array of strings that are formatted 128bit IDs in
714hex. If any of the specified IDs match the system's local machine ID
715(i.e. matches `/etc/machine-id`) the fields in this object are honored.
716
717`matchHostname` → An array of strings that are valid hostnames. If any of
718the specified hostnames match the system's local hostname, the fields in this
719object are honored. If both `matchHostname` and `matchMachineId` are used
720within the same array entry, the object is honored when either match succeeds,
721i.e. the two match types are combined in OR, not in AND.
722
723These two are the only two fields specific to this section. All other fields
724that may be used in this section are identical to the equally named ones in the
725`regular` section (i.e. at the top-level object). Specifically, these are:
726
727`iconName`, `location`, `shell`, `umask`, `environment`, `timeZone`,
728`preferredLanguage`, `niceLevel`, `resourceLimits`, `locked`, `notBeforeUSec`,
729`notAfterUSec`, `storage`, `diskSize`, `diskSizeRelative`, `skeletonDirectory`,
730`accessMode`, `tasksMax`, `memoryHigh`, `memoryMax`, `cpuWeight`, `ioWeight`,
731`mountNoDevices`, `mountNoSuid`, `mountNoExecute`, `cifsDomain`,
732`cifsUserName`, `cifsService`, `cifsExtraMountOptions`, `imagePath`, `uid`,
733`gid`, `memberOf`, `fileSystemType`, `partitionUuid`, `luksUuid`,
734`fileSystemUuid`, `luksDiscard`, `luksOfflineDiscard`, `luksCipher`,
735`luksCipherMode`, `luksVolumeKeySize`, `luksPbkdfHashAlgorithm`,
736`luksPbkdfType`, `luksPbkdfTimeCostUSec`, `luksPbkdfMemoryCost`,
737`luksPbkdfParallelThreads`, `autoResizeMode`, `rebalanceWeight`,
738`rateLimitIntervalUSec`, `rateLimitBurst`, `enforcePasswordPolicy`,
739`autoLogin`, `stopDelayUSec`, `killProcesses`, `passwordChangeMinUSec`,
740`passwordChangeMaxUSec`, `passwordChangeWarnUSec`,
741`passwordChangeInactiveUSec`, `passwordChangeNow`, `pkcs11TokenUri`,
742`fido2HmacCredential`.
743
744## Fields in the `binding` section
745
746As mentioned, the `binding` section contains additional fields about the user
747record, that bind it to the local system. These fields are generally used by a
748local user manager (such as `systemd-homed.service`) to add in fields that make
749sense in a local context but not necessarily in a global one. For example, a
750user record that contains no `uid` field in the regular section is likely
751extended with one in the `binding` section to assign a local UID if no global
752UID is defined.
753
754All fields in the `binding` section only make sense in a local context and are
755suppressed when the user record is ported between systems. The `binding` section
756is generally persisted on the system but not in the home directories themselves
757and the home directory is supposed to be fully portable and thus not contain
758the information that `binding` is supposed to contain that binds the portable
759record to a specific system.
760
761The `binding` sub-object on the top-level user record object is keyed by the
762machine ID the binding is intended for, which point to an object with the
763fields of the bindings. These fields generally match fields that may also be
764defined in the `regular` and `perMachine` sections, however override
765both. Usually, the `binding` value should not contain settings different from
766those set via `regular` or `perMachine`, however this might happen if some
767settings are not supported locally (think: `fscrypt` is recorded as intended
768storage mechanism in the `regular` section, but the local kernel does not
769support `fscrypt`, hence `directory` was chosen as implicit fallback), or have
770been changed in the `regular` section through updates (e.g. a home directory
771was created with `luks` as storage mechanism but later the user record was
772updated to prefer `subvolume`, which however doesn't change the actual storage
773used already which is pinned in the `binding` section).
774
775The following fields are defined in the `binding` section. They all have an
776identical format and override their equally named counterparts in the `regular`
777and `perMachine` sections:
778
779`imagePath`, `homeDirectory`, `partitionUuid`, `luksUuid`, `fileSystemUuid`,
780`uid`, `gid`, `storage`, `fileSystemType`, `luksCipher`, `luksCipherMode`,
781`luksVolumeKeySize`.
782
783## Fields in the `status` section
784
785As mentioned, the `status` section contains additional fields about the user
786record that are exclusively acquired during runtime, and that expose runtime
787metrics of the user and similar metadata that shall not be persisted but are
788only acquired "on-the-fly" when requested.
789
790This section is arranged similarly to the `binding` section: the `status`
791sub-object of the top-level user record object is keyed by the machine ID,
792which points to the object with the fields defined here. The following fields
793are defined:
794
795`diskUsage` → An unsigned 64bit integer. The currently used disk space of the
796home directory in bytes. This value might be determined in different ways,
797depending on the selected storage mechanism. For LUKS storage this is the file
798size of the loopback file or block device size. For the
799directory/subvolume/fscrypt storage this is the current disk space used as
800reported by the file system quota subsystem.
801
802`diskFree` → An unsigned 64bit integer, denoting the number of "free" bytes in
803the disk space allotment, i.e. usually the difference between the disk size as
804reported by `diskSize` and the used already as reported in `diskFree`, but
805possibly skewed by metadata sizes, disk compression and similar.
806
807`diskSize` → An unsigned 64bit integer, denoting the disk space currently
808allotted to the user, in bytes. Depending on the storage mechanism this can mean
809different things (see above). In contrast to the top-level field of the same
810(or the one in the `perMachine` section), this field reports the current size
811allotted to the user, not the intended one. The values may differ when user
812records are updated without the home directory being re-sized.
813
814`diskCeiling`/`diskFloor` → Unsigned 64bit integers indicating upper and lower
815bounds when changing the `diskSize` value, in bytes. These values are typically
816derived from the underlying data storage, and indicate in which range the home
817directory may be re-sized in, i.e. in which sensible range the `diskSize` value
818should be kept.
819
820`state` → A string indicating the current state of the home directory. The
821precise set of values exposed here are up to the service managing the home
822directory to define (i.e. are up to the service identified with the `service`
823field below). However, it is recommended to stick to a basic vocabulary here:
824`inactive` for a home directory currently not mounted, `absent` for a home
825directory that cannot be mounted currently because it does not exist on the
826local system, `active` for a home directory that is currently mounted and
827accessible.
828
829`service` → A string identifying the service that manages this user record. For
830example `systemd-homed.service` sets this to `io.systemd.Home` to all user
831records it manages. This is particularly relevant to define clearly the context
832in which `state` lives, see above. Note that this field also exists on the
833top-level object (i.e. in the `regular` section), which it overrides. The
834`regular` field should be used if conceptually the user record can only be
835managed by the specified service, and this `status` field if it can
836conceptually be managed by different managers, but currently is managed by the
837specified one.
838
839`signedLocally` → A boolean. If true indicates that the user record is signed
840by a public key for which the private key is available locally. This means that
841the user record may be modified locally as it can be re-signed with the private
842key. If false indicates that the user record is signed by a public key
843recognized by the local manager but whose private key is not available
844locally. This means the user record cannot be modified locally as it couldn't
845be signed afterwards.
846
847`goodAuthenticationCounter` → An unsigned 64bit integer. This counter is
848increased by one on every successful authentication attempt, i.e. an
849authentication attempt where a security token of some form was presented and it
850was correct.
851
852`badAuthenticationCounter` → An unsigned 64bit integer. This counter is
853increased by one on every unsuccessfully authentication attempt, i.e. an
854authentication attempt where a security token of some form was presented and it
855was incorrect.
856
857`lastGoodAuthenticationUSec` → An unsigned 64bit integer, indicating the time
858of the last successful authentication attempt in µs since the UNIX epoch (1970).
859
860`lastBadAuthenticationUSec` → Similar, but the timestamp of the last
861unsuccessfully authentication attempt.
862
863`rateLimitBeginUSec` → An unsigned 64bit integer: the µs timestamp since the
864UNIX epoch (1970) where the most recent rate limiting interval has been
865started, as configured with `rateLimitIntervalUSec`.
866
867`rateLimitCount` → An unsigned 64bit integer, counting the authentication
868attempts in the current rate limiting interval, see above. If this counter
869grows beyond the value configured in `rateLimitBurst` authentication attempts
870are temporarily refused.
871
872`removable` → A boolean value. If true the manager of this user record
873determined the home directory being on removable media. If false it was
874determined the home directory is in internal built-in media. (This is used by
875`systemd-logind.service` to automatically pick the right default value for
876`stopDelayUSec` if the field is not explicitly specified: for home directories
877on removable media the delay is selected very low to minimize the chance the
878home directory remains in unclean state if the storage device is removed from
879the system by the user).
880
881`accessMode` → The access mode currently in effect for the home directory
882itself.
883
884`fileSystemType` → The file system type backing the home directory: a short
885string, such as "btrfs", "ext4", "xfs".
886
887## Fields in the `signature` section
888
889As mentioned, the `signature` section of the user record may contain one or
890more cryptographic signatures of the user record. Like all others, this section
891is optional, and only used when cryptographic validation of user records shall
892be used. Specifically, all user records managed by `systemd-homed.service` will
893carry such signatures and the service refuses managing user records that come
894without signature or with signatures not recognized by any locally defined
895public key.
896
897The `signature` field in the top-level user record object is an array of
898objects. Each object encapsulates one signature and has two fields: `data` and
899`key` (both are strings). The `data` field contains the actual signature,
900encoded in Base64, the `key` field contains a copy of the public key whose
901private key was used to make the signature, in PEM format. Currently only
902signatures with Ed25519 keys are defined.
903
904Before signing the user record should be brought into "normalized" form,
905i.e. the keys in all objects should be sorted alphabetically. All redundant
906white-space and newlines should be removed and the JSON text then signed.
907
908The signatures only cover the `regular`, `perMachine` and `privileged` sections
909of the user records, all other sections (include `signature` itself), are
910removed before the signature is calculated.
911
912Rationale for signing and threat model: while a multi-user operating system
913like Linux strives for being sufficiently secure even after a user acquired a
914local login session reality tells us this is not the case. Hence it is
915essential to restrict carefully which users may gain access to a system and
916which ones shall not. A minimal level of trust must be established between
917system, user record and the user themselves before a log-in request may be
918permitted. In particular if the home directory is provided in its own LUKS2
919encapsulated file system it is essential this trust is established before the
920user logs in (and hence the file system mounted), since file system
921implementations on Linux are well known to be relatively vulnerable to rogue
922disk images. User records and home directories in many context are expected to
923be something shareable between multiple systems, and the transfer between them
924might not happen via exclusively trusted channels. Hence it's essential that
925the user record is not manipulated between uses. Finally, resource management
926(which may be done by the various fields of the user record) is security
927sensitive, since it should forcefully lock the user into the assigned resource
928usage and not allow them to use more. The requirement of being able to trust
929the user record data combined with the potential transfer over untrusted
930channels suggest a cryptographic signature mechanism where only user records
931signed by a recognized key are permitted to log in locally.
932
933Note that other mechanisms for establishing sufficient trust exist too, and are
934perfectly valid as well. For example, systems like LDAP/ActiveDirectory
935generally insist on user record transfer from trusted servers via encrypted TLS
936channels only. Or traditional UNIX users created locally in `/etc/passwd` never
937exist outside of the local trusted system, hence transfer and trust in the
938source are not an issue. The major benefit of operating with signed user
939records is that they are self-sufficiently trusted, not relying on a secure
940channel for transfer, and thus being compatible with a more distributed model
941of home directory transfer, including on USB sticks and such.
942
943## Fields in the `secret` section
944
945As mentioned, the `secret` section of the user record should never be persisted
946nor transferred across machines. It is only defined in short-lived operations,
947for example when a user record is first created or registered, as the secret
948key data needs to be available to derive encryption keys from and similar.
949
950The `secret` field of the top-level user record contains the following fields:
951
952`password` → an array of strings, each containing a plain text password.
953
954`tokenPin` → an array of strings, each containing a plain text PIN, suitable
955for unlocking security tokens that require that. (The field `pkcs11Pin` should
956be considered a compatibility alias for this field, and merged with `tokenPin`
957in case both are set.)
958
959`pkcs11ProtectedAuthenticationPathPermitted` → a boolean. If set to true allows
960the receiver to use the PKCS#11 "protected authentication path" (i.e. a
961physical button/touch element on the security token) for authenticating the
962user. If false or unset, authentication this way shall not be attempted.
963
964`fido2UserPresencePermitted` → a boolean. If set to true allows the receiver to
965use the FIDO2 "user presence" flag. This is similar to the concept of
966`pkcs11ProtectedAuthenticationPathPermitted`, but exposes the FIDO2 "up"
967concept behind it. If false or unset authentication this way shall not be
968attempted.
969
970`fido2UserVerificationPermitted` → a boolean. If set to true allows the
971receiver to use the FIDO2 "user verification" flag. This is similar to the
972concept of `pkcs11ProtectedAuthenticationPathPermitted`, but exposes the FIDO2
973"uv" concept behind it. If false or unset authentication this way shall not be
974attempted.
975
976## Mapping to `struct passwd` and `struct spwd`
977
978When mapping classic UNIX user records (i.e. `struct passwd` and `struct spwd`)
979to JSON user records the following mappings should be applied:
980
981| Structure       | Field       | Section      | Field                        | Condition                  |
982|-----------------|-------------|--------------|------------------------------|----------------------------|
983| `struct passwd` | `pw_name`   | `regular`    | `userName`                   |                            |
984| `struct passwd` | `pw_passwd` | `privileged` | `password`                   | (See notes below)          |
985| `struct passwd` | `pw_uid`    | `regular`    | `uid`                        |                            |
986| `struct passwd` | `pw_gid`    | `regular`    | `gid`                        |                            |
987| `struct passwd` | `pw_gecos`  | `regular`    | `realName`                   |                            |
988| `struct passwd` | `pw_dir`    | `regular`    | `homeDirectory`              |                            |
989| `struct passwd` | `pw_shell`  | `regular`    | `shell`                      |                            |
990| `struct spwd`   | `sp_namp`   | `regular`    | `userName`                   |                            |
991| `struct spwd`   | `sp_pwdp`   | `privileged` | `password`                   | (See notes below)          |
992| `struct spwd`   | `sp_lstchg` | `regular`    | `lastPasswordChangeUSec`     | (if `sp_lstchg` > 0)       |
993| `struct spwd`   | `sp_lstchg` | `regular`    | `passwordChangeNow`          | (if `sp_lstchg` == 0)      |
994| `struct spwd`   | `sp_min`    | `regular`    | `passwordChangeMinUSec`      |                            |
995| `struct spwd`   | `sp_max`    | `regular`    | `passwordChangeMaxUSec`      |                            |
996| `struct spwd`   | `sp_warn`   | `regular`    | `passwordChangeWarnUSec`     |                            |
997| `struct spwd`   | `sp_inact`  | `regular`    | `passwordChangeInactiveUSec` |                            |
998| `struct spwd`   | `sp_expire` | `regular`    | `locked`                     | (if `sp_expire` in [0, 1]) |
999| `struct spwd`   | `sp_expire` | `regular`    | `notAfterUSec`               | (if `sp_expire` > 1)       |
1000
1001At this time almost all Linux machines employ shadow passwords, thus the
1002`pw_passwd` field in `struct passwd` is set to `"x"`, and the actual password
1003is stored in the shadow entry `struct spwd`'s field `sp_pwdp`.
1004
1005## Extending These Records
1006
1007User records following this specifications are supposed to be extendable for
1008various applications. In general, subsystems are free to introduce their own
1009keys, as long as:
1010
1011* Care should be taken to place the keys in the right section, i.e. the most
1012  appropriate for the data field.
1013
1014* Care should be taken to avoid namespace clashes. Please prefix your fields
1015  with a short identifier of your project to avoid ambiguities and
1016  incompatibilities.
1017
1018* This specification is supposed to be a living specification. If you need
1019  additional fields, please consider submitting them upstream for inclusion in
1020  this specification. If they are reasonably universally useful, it would be
1021  best to list them here.
1022
1023## Examples
1024
1025The shortest valid user record looks like this:
1026
1027```json
1028{
1029        "userName" : "u"
1030}
1031```
1032
1033A reasonable user record for a system user might look like this:
1034
1035```json
1036{
1037        "userName" : "httpd",
1038        "uid" : 473,
1039        "gid" : 473,
1040        "disposition" : "system",
1041        "locked" : true
1042}
1043```
1044
1045A fully featured user record associated with a home directory managed by
1046`systemd-homed.service` might look like this:
1047
1048```json
1049{
1050        "autoLogin" : true,
1051        "binding" : {
1052                "15e19cf24e004b949ddaac60c74aa165" : {
1053                        "fileSystemType" : "ext4",
1054                        "fileSystemUuid" : "758e88c8-5851-4a2a-b88f-e7474279c111",
1055                        "gid" : 60232,
1056                        "homeDirectory" : "/home/grobie",
1057                        "imagePath" : "/home/grobie.home",
1058                        "luksCipher" : "aes",
1059                        "luksCipherMode" : "xts-plain64",
1060                        "luksUuid" : "e63581ba-79fb-4226-b9de-1888393f7573",
1061                        "luksVolumeKeySize" : 32,
1062                        "partitionUuid" : "41f9ce04-c827-4b74-a981-c669f93eb4dc",
1063                        "storage" : "luks",
1064                        "uid" : 60232
1065                }
1066        },
1067        "disposition" : "regular",
1068        "enforcePasswordPolicy" : false,
1069        "lastChangeUSec" : 1565950024279735,
1070        "memberOf" : [
1071                "wheel"
1072        ],
1073        "privileged" : {
1074                "hashedPassword" : [
1075                        "$6$WHBKvAFFT9jKPA4k$OPY4D4TczKN/jOnJzy54DDuOOagCcvxxybrwMbe1SVdm.Bbr.zOmBdATp.QrwZmvqyr8/SafbbQu.QZ2rRvDs/"
1076                ]
1077        },
1078        "signature" : [
1079                {
1080                        "data" : "LU/HeVrPZSzi3MJ0PVHwD5m/xf51XDYCrSpbDRNBdtF4fDVhrN0t2I2OqH/1yXiBidXlV0ptMuQVq8KVICdEDw==",
1081                        "key" : "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEA/QT6kQWOAMhDJf56jBmszEQQpJHqDsGDMZOdiptBgRk=\n-----END PUBLIC KEY-----\n"
1082                }
1083        ],
1084        "userName" : "grobie",
1085        "status" : {
1086                "15e19cf24e004b949ddaac60c74aa165" : {
1087                        "goodAuthenticationCounter" : 16,
1088                        "lastGoodAuthenticationUSec" : 1566309343044322,
1089                        "rateLimitBeginUSec" : 1566309342340723,
1090                        "rateLimitCount" : 1,
1091                        "state" : "inactive",
1092                        "service" : "io.systemd.Home",
1093                        "diskSize" : 161118667776,
1094                        "diskCeiling" : 190371729408,
1095                        "diskFloor" : 5242880,
1096                        "signedLocally" : true
1097                }
1098        }
1099}
1100```
1101
1102When `systemd-homed.service` manages a home directory it will also include a
1103version of the user record in the home directory itself in the `~/.identity`
1104file. This version lacks the `binding` and `status` sections which are used for
1105local management of the user, but are not intended to be portable between
1106systems. It would hence look like this:
1107
1108```json
1109{
1110        "autoLogin" : true,
1111        "disposition" : "regular",
1112        "enforcePasswordPolicy" : false,
1113        "lastChangeUSec" : 1565950024279735,
1114        "memberOf" : [
1115                "wheel"
1116        ],
1117        "privileged" : {
1118                "hashedPassword" : [
1119                        "$6$WHBKvAFFT9jKPA4k$OPY4D4TczKN/jOnJzy54DDuOOagCcvxxybrwMbe1SVdm.Bbr.zOmBdATp.QrwZmvqyr8/SafbbQu.QZ2rRvDs/"
1120                ]
1121        },
1122        "signature" : [
1123                {
1124                        "data" : "LU/HeVrPZSzi3MJ0PVHwD5m/xf51XDYCrSpbDRNBdtF4fDVhrN0t2I2OqH/1yXiBidXlV0ptMuQVq8KVICdEDw==",
1125                        "key" : "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEA/QT6kQWOAMhDJf56jBmszEQQpJHqDsGDMZOdiptBgRk=\n-----END PUBLIC KEY-----\n"
1126                }
1127        ],
1128        "userName" : "grobie",
1129}
1130```
1131