]> git.ipfire.org Git - thirdparty/systemd.git/blame - docs/USER_RECORD.md
Merge pull request #31173 from yuwata/network-route-check-conflict
[thirdparty/systemd.git] / docs / USER_RECORD.md
CommitLineData
812862db
LP
1---
2title: JSON User Records
5fe63895 3category: Users, Groups and Home Directories
812862db 4layout: default
0aff7b75 5SPDX-License-Identifier: LGPL-2.1-or-later
812862db
LP
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
5c90c67a
BF
17 directly in the home directory images
18 (see [Home Directories](HOME_DIRECTORY.md) for details).
812862db
LP
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
5c90c67a
BF
74Similar to JSON User Records there are also
75[JSON Group Records](GROUP_RECORD.md) that encapsulate UNIX groups.
812862db
LP
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
5c90c67a
BF
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
f2147ed5
LP
81[`nss-systemd(8)`](https://www.freedesktop.org/software/systemd/man/nss-systemd.html)
82for details.
812862db
LP
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
a21e88d4
LP
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
812862db
LP
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)
cd990847 192does not need to be concerned with the `secret` section of user records, as
812862db
LP
193the fields included therein are only useful when executing authentication
194operations natively against JSON user records.
195
58345a23 196The `systemd-homed` manager uses all seven sections for various
812862db
LP
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
30fd9a2d 215optional. Corresponds with the `pw_name` field of `struct passwd` and the
812862db 216`sp_namp` field of `struct spwd` (i.e. the shadow user record stored in
5c90c67a 217`/etc/shadow`). See [User/Group Name Syntax](USER_NAMES.md) for
887a8fa3 218the (relaxed) rules the various systemd components enforce on user/group names.
812862db
LP
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
072779f0
LP
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.
812862db
LP
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
da890466 272`lastChangeUSec` → An unsigned 64-bit integer value, referring to a timestamp in µs
812862db
LP
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
da890466 278`lastPasswordChangeUSec` → Similar, also an unsigned 64-bit integer value,
812862db
LP
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
e2285c57 300[`putenv()`](https://man7.org/linux/man-pages/man3/putenv.3.html). Any
812862db
LP
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
49e55abb
AV
313user. It is combined with the `additionalLanguages` field to initialize the `$LANG`
314and `$LANGUAGE` environment variables on login; see below for more details. This string
315should be in a format compatible with the `$LANG` environment variable, for example:
316`de_DE.UTF-8`.
317
318`additionalLanguages` → An array of strings indicating the preferred languages/locales
319that should be used in the event that translations for the `preferredLanguage` are
320missing, listed in order of descending priority. This allows multi-lingual users to
321specify all the languages that they know, so software lacking translations in the user's
322primary language can try another language that the user knows rather than falling back to
323the default English. All entries in this field must be valid locale names, compatible with
324the `$LANG` variable, for example: `de_DE.UTF-8`. When logging in
812862db 325[`pam_systemd`](https://www.freedesktop.org/software/systemd/man/pam_systemd.html)
49e55abb
AV
326will prepend `preferredLanguage` (if set) to this list (if set), remove duplicates,
327and then automatically initialize the `$LANGUAGE` variable with the resulting list.
328It will also initialize `$LANG` variable with the first entry in the resulting list.
812862db
LP
329
330`niceLevel` → An integer value in the range -20…19. When logging in
331[`pam_systemd`](https://www.freedesktop.org/software/systemd/man/pam_systemd.html)
332will automatically initialize the login process' nice level to this value with,
333which is then inherited by all the user's processes, see
e2285c57 334[`setpriority()`](https://man7.org/linux/man-pages/man2/setpriority.2.html) for
812862db
LP
335more information.
336
337`resourceLimits` → An object, where each key refers to a Linux resource limit
338(such as `RLIMIT_NOFILE` and similar). Their values should be an object with
339two keys `cur` and `max` for the soft and hard resource limit. When logging in
340[`pam_systemd`](https://www.freedesktop.org/software/systemd/man/pam_systemd.html)
341will automatically initialize the login process' resource limits to these
342values, which is then inherited by all the user's processes, see
e2285c57 343[`setrlimit()`](https://man7.org/linux/man-pages/man2/setrlimit.2.html) for more
812862db
LP
344information.
345
f223fd6a 346`locked` → A boolean value. If true, the user account is locked, the user may
812862db
LP
347not log in. If this field is missing it should be assumed to be false,
348i.e. logins are permitted. This field corresponds to the `sp_expire` field of
349`struct spwd` (i.e. the `/etc/shadow` data for a user) being set to zero or
350one.
351
da890466 352`notBeforeUSec` → An unsigned 64-bit integer value, indicating a time in µs since
812862db
LP
353the UNIX epoch (1970) before which the record should be considered invalid for
354the purpose of logging in.
355
356`notAfterUSec` → Similar, but indicates the point in time *after* which logins
357shall not be permitted anymore. This corresponds to the `sp_expire` field of
358`struct spwd`, when it is set to a value larger than one, but provides finer
359granularity.
360
361`storage` → A string, one of `classic`, `luks`, `directory`, `subvolume`,
362`fscrypt`, `cifs`. Indicates the storage mechanism for the user's home
363directory. If `classic` the home directory is a plain directory as in classic
364UNIX. When `directory`, the home directory is a regular directory, but the
365`~/.identity` file in it contains the user's user record, so that the directory
366is self-contained. Similar, `subvolume` is a `btrfs` subvolume that also
367contains a `~/.identity` user record; `fscrypt` is an `fscrypt`-encrypted
368directory, also containing the `~/.identity` user record; `luks` is a per-user
369LUKS volume that is mounted as home directory, and `cifs` a home directory
370mounted from a Windows File Share. The five latter types are primarily used by
371`systemd-homed` when managing home directories, but may be used if other
f223fd6a 372managers are used too. If this is not set, `classic` is the implied default.
812862db 373
da890466 374`diskSize` → An unsigned 64-bit integer, indicating the intended home directory
812862db 375disk space in bytes to assign to the user. Depending on the selected storage
f223fd6a 376type this might be implemented differently: for `luks` this is the intended size
812862db
LP
377of the file system and LUKS volume, while for the others this likely translates
378to classic file system quota settings.
379
380`diskSizeRelative` → Similar to `diskSize` but takes a relative value, but
381specifies a fraction of the available disk space on the selected storage medium
382to assign to the user. This unsigned integer value is normalized to 2^32 =
383100%.
384
385`skeletonDirectory` → Takes a string with the absolute path to the skeleton
386directory to populate a new home directory from. This is only used when a home
387directory is first created, and defaults to `/etc/skel` if not defined.
388
389`accessMode` → Takes an unsigned integer in the range 0…511 indicating the UNIX
390access mask for the home directory when it is first created.
391
da890466 392`tasksMax` → Takes an unsigned 64-bit integer indicating the maximum number of
8dc647fd
ZJS
393tasks the user may start in parallel during system runtime. This counts
394all tasks (i.e. threads, where each process is at least one thread) the user starts or that are
395forked from these processes even if the user identity is changed (for example
396by setuid binaries/`su`/`sudo` and similar).
397[`systemd-logind.service`](https://www.freedesktop.org/software/systemd/man/systemd-logind.service.html)
812862db
LP
398enforces this by setting the `TasksMax` slice property for the user's slice
399`user-$UID.slice`.
400
da890466 401`memoryHigh`/`memoryMax` → These take unsigned 64-bit integers indicating upper
812862db
LP
402memory limits for all processes of the user (plus all processes forked off them
403that might have changed user identity), in bytes. Enforced by
404[`systemd-logind.service`](https://www.freedesktop.org/software/systemd/man/systemd-logind.service.html),
405similar to `tasksMax`.
406
8b51950f
MK
407`cpuWeight`/`ioWeight` → These take unsigned integers in the range 1…10000
408(defaults to 100) and configure the CPU and IO scheduling weights for the
409user's processes as a whole. Also enforced by
812862db
LP
410[`systemd-logind.service`](https://www.freedesktop.org/software/systemd/man/systemd-logind.service.html),
411similar to `tasksMax`, `memoryHigh` and `memoryMax`.
412
413`mountNoDevices`/`mountNoSuid`/`mountNoExecute` → Three booleans that control
414the `nodev`, `nosuid`, `noexec` mount flags of the user's home
415directories. Note that these booleans are only honored if the home directory
416is managed by a subsystem such as `systemd-homed.service` that automatically
417mounts home directories on login.
418
419`cifsDomain` → A string indicating the Windows File Sharing domain (CIFS) to
420use. This is generally useful, but particularly when `cifs` is used as storage
421mechanism for the user's home directory, see above.
422
423`cifsUserName` → A string indicating the Windows File Sharing user name (CIFS)
424to associate this user record with. This is generally useful, but particularly
425useful when `cifs` is used as storage mechanism for the user's home directory,
426see above.
427
428`cifsService` → A string indicating the Windows File Share service (CIFS) to
bf15879b
LP
429mount as home directory of the user on login. Should be in format
430`//<host>/<service>/<directory/…>`. The directory part is optional. If missing
431the top-level directory of the CIFS share is used.
812862db 432
4c2ee5c7
LP
433`cifsExtraMountOptions` → A string with additional mount options to pass to
434`mount.cifs` when mounting the home directory CIFS share.
435
812862db
LP
436`imagePath` → A string with an absolute file system path to the file, directory
437or block device to use for storage backing the home directory. If the `luks`
f223fd6a 438storage is used, this refers to the loopback file or block device node to store
812862db
LP
439the LUKS volume on. For `fscrypt`, `directory`, `subvolume` this refers to the
440directory to bind mount as home directory on login. Not defined for `classic`
441or `cifs`.
442
443`homeDirectory` → A string with an absolute file system path to the home
444directory. This is where the image indicated in `imagePath` is mounted to on
445login and thus indicates the application facing home directory while the home
446directory is active, and is what the user's `$HOME` environment variable is set
447to during log-in. It corresponds to the `pw_dir` field of `struct passwd`.
448
449`uid` → An unsigned integer in the range 0…4294967295: the numeric UNIX user ID (UID) to
450use for the user. This corresponds to the `pw_uid` field of `struct passwd`.
451
452`gid` → An unsigned integer in the range 0…4294967295: the numeric UNIX group
453ID (GID) to use for the user. This corresponds to the `pw_gid` field of
454`struct passwd`.
455
456`memberOf` → An array of strings, each indicating a UNIX group this user shall
457be a member of. The listed strings must be valid group names, but it is not
458required that all groups listed exist in all contexts: any entry for which no
459group exists should be silently ignored.
460
461`fileSystemType` → A string, one of `ext4`, `xfs`, `btrfs` (possibly others) to
462use as file system for the user's home directory. This is primarily relevant
463when the storage mechanism used is `luks` as a file system to use inside the
464LUKS container must be selected.
465
466`partitionUuid` → A string containing a lower-case, text-formatted UUID, referencing
467the GPT partition UUID the home directory is located in. This is primarily
468relevant when the storage mechanism used is `luks`.
469
470`luksUuid` → A string containing a lower-case, text-formatted UUID, referencing
471the LUKS volume UUID the home directory is located in. This is primarily
472relevant when the storage mechanism used is `luks`.
473
474`fileSystemUuid` → A string containing a lower-case, text-formatted UUID,
475referencing the file system UUID the home directory is located in. This is
476primarily relevant when the storage mechanism used is `luks`.
477
f223fd6a 478`luksDiscard` → A boolean. If true and `luks` storage is used, controls whether
812862db
LP
479the loopback block devices, LUKS and the file system on top shall be used in
480`discard` mode, i.e. erased sectors should always be returned to the underlying
481storage. If false and `luks` storage is used turns this behavior off. In
482addition, depending on this setting an `FITRIM` or `fallocate()` operation is
483executed to make sure the image matches the selected option.
484
c0440512
LP
485`luksOfflineDiscard` → A boolean. Similar to `luksDiscard`, it controls whether
486to trim/allocate the file system/backing file when deactivating the home
487directory.
488
5dd57a00
LP
489`luksExtraMountOptions` → A string with additional mount options to append to
490the default mount options for the file system in the LUKS volume.
491
812862db
LP
492`luksCipher` → A string, indicating the cipher to use for the LUKS storage mechanism.
493
494`luksCipherMode` → A string, selecting the cipher mode to use for the LUKS storage mechanism.
495
496`luksVolumeKeySize` → An unsigned integer, indicating the volume key length in
497bytes to use for the LUKS storage mechanism.
498
499`luksPbkdfHashAlgorithm` → A string, selecting the hash algorithm to use for
500the PBKDF operation for the LUKS storage mechanism.
501
502`luksPbkdfType` → A string, indicating the PBKDF type to use for the LUKS storage mechanism.
503
da890466 504`luksPbkdfForceIterations` → An unsigned 64-bit integer, indicating the intended
b04ff66b
AD
505number of iterations for the PBKDF operation, when LUKS storage is used.
506
da890466 507`luksPbkdfTimeCostUSec` → An unsigned 64-bit integer, indicating the intended
812862db 508time cost for the PBKDF operation, when the LUKS storage mechanism is used, in
b04ff66b 509µs. Ignored when `luksPbkdfForceIterations` is set.
812862db 510
da890466 511`luksPbkdfMemoryCost` → An unsigned 64-bit integer, indicating the intended
812862db
LP
512memory cost for the PBKDF operation, when LUKS storage is used, in bytes.
513
da890466 514`luksPbkdfParallelThreads` → An unsigned 64-bit integer, indicating the intended
812862db
LP
515required parallel threads for the PBKDF operation, when LUKS storage is used.
516
da890466 517`luksSectorSize` → An unsigned 64-bit integer, indicating the sector size to
fd83c98e
AD
518use for the LUKS storage mechanism, in bytes. Must be a power of two between
519512 and 4096.
520
2f09e2ee
LP
521`autoResizeMode` → A string, one of `off`, `grow`, `shrink-and-grow`. Unless
522set to `off`, controls whether the home area shall be grown automatically to
523the size configured in `diskSize` automatically at login time. If set to
524`shrink-and-grown` the home area is also shrunk to the minimal size possible
525(as dictated by used disk space and file system constraints) on logout.
526
9aa3e5eb
LP
527`rebalanceWeight` → An unsigned integer, `null` or a boolean. Configures the
528free disk space rebalancing weight for the home area. The integer must be in
529the range 1…10000 to configure an explicit weight. If unset, or set to `null`
530or `true` the default weight of 100 is implied. If set to 0 or `false`
531rebalancing is turned off for this home area.
532
812862db
LP
533`service` → A string declaring the service that defines or manages this user
534record. It is recommended to use reverse domain name notation for this. For
535example, if `systemd-homed` manages a user a string of `io.systemd.Home` is
536used for this.
537
da890466 538`rateLimitIntervalUSec` → An unsigned 64-bit integer that configures the
812862db
LP
539authentication rate limiting enforced on the user account. This specifies a
540timer interval (in µs) within which to count authentication attempts. When the
541counter goes above the value configured n `rateLimitIntervalBurst` log-ins are
542temporarily refused until the interval passes.
543
da890466 544`rateLimitIntervalBurst` → An unsigned 64-bit integer, closely related to
812862db
LP
545`rateLimitIntervalUSec`, that puts a limit on authentication attempts within
546the configured time interval.
547
548`enforcePasswordPolicy` → A boolean. Configures whether to enforce the system's
549password policy when creating the home directory for the user or changing the
550user's password. By default the policy is enforced, but if this field is false
551it is bypassed.
552
553`autoLogin` → A boolean. If true the user record is marked as suitable for
554auto-login. Systems are supposed to automatically log in a user marked this way
555during boot, if there's exactly one user on it defined this way.
556
da890466 557`stopDelayUSec` → An unsigned 64-bit integer, indicating the time in µs the
812862db
LP
558per-user service manager is kept around after the user fully logged out. This
559value is honored by
560[`systemd-logind.service`](https://www.freedesktop.org/software/systemd/man/systemd-logind.service.html). If
561set to zero the per-user service manager is immediately terminated when the
562user logs out, and longer values optimize high-frequency log-ins as the
563necessary work to set up and tear down a log-in is reduced if the service
564manager stays running.
565
566`killProcesses` → A boolean. If true all processes of the user are
567automatically killed when the user logs out. This is enforced by
568[`systemd-logind.service`](https://www.freedesktop.org/software/systemd/man/systemd-logind.service.html). If
569false any processes left around when the user logs out are left running.
570
da890466 571`passwordChangeMinUSec`/`passwordChangeMaxUSec` → An unsigned 64-bit integer,
812862db
LP
572encoding how much time has to pass at least/at most between password changes of
573the user. This corresponds with the `sp_min` and `sp_max` fields of `struct
574spwd` (i.e. the `/etc/shadow` entries of the user), but offers finer
575granularity.
576
da890466 577`passwordChangeWarnUSec` → An unsigned 64-bit integer, encoding how much time to
812862db
LP
578warn the user before their password expires, in µs. This corresponds with the
579`sp_warn` field of `struct spwd`.
580
da890466 581`passwordChangeInactiveUSec` → An unsigned 64-bit integer, encoding how much
812862db
LP
582time has to pass after the password expired that the account is
583deactivated. This corresponds with the `sp_inact` field of `struct spwd`.
584
585`passwordChangeNow` → A boolean. If true the user has to change their password
586on next login. This corresponds with the `sp_lstchg` field of `struct spwd`
587being set to zero.
588
589`pkcs11TokenUri` → An array of strings, each with an RFC 7512 compliant PKCS#11
590URI referring to security token (or smart card) of some form, that shall be
591associated with the user and may be used for authentication. The URI is used to
592search for an X.509 certificate and associated private key that may be used to
593decrypt an encrypted secret key that is used to unlock the user's account (see
594below). It's undefined how precise the URI is: during log-in it is tested
595against all plugged in security tokens and if there's exactly one matching
596private key found with it it is used.
597
fe2520fb 598`fido2HmacCredential` → An array of strings, each with a Base64-encoded FIDO2
f223fd6a 599credential ID that shall be used for authentication with FIDO2 devices that
fe2520fb
LP
600implement the `hmac-secret` extension. The salt to pass to the FIDO2 device is
601found in `fido2HmacSalt`.
602
64abd37a
LP
603`recoveryKeyType` → An array of strings, each indicating the type of one
604recovery key. The only supported recovery key type at the moment is `modhex64`,
605for details see the description of `recoveryKey` below. An account may have any
606number of recovery keys defined, and the array should have one entry for each.
607
e1ef1e5d 608`privileged` → An object, which contains the fields of the `privileged` section
812862db
LP
609of the user record, see below.
610
611`perMachine` → An array of objects, which contain the `perMachine` section of
612the user record, and thus fields to apply on specific systems only, see below.
613
614`binding` → An object, keyed by machine IDs formatted as strings, pointing
615to objects that contain the `binding` section of the user record,
616i.e. additional fields that bind the user record to a specific machine, see
617below.
618
619`status` → An object, keyed by machine IDs formatted as strings, pointing to
620objects that contain the `status` section of the user record, i.e. additional
621runtime fields that expose the current status of the user record on a specific
622system, see below.
623
624`signature` → An array of objects, which contain cryptographic signatures of
625the user record, i.e. the fields of the `signature` section of the user record,
626see below.
627
628`secret` → An object, which contains the fields of the `secret` section of the
629user record, see below.
630
631## Fields in the `privileged` section
632
633As mentioned, the `privileged` section is encoded in a sub-object of the user
634record top-level object, in the `privileged` field. Any data included in this
635object shall only be visible to the administrator and the user themselves, and
636be suppressed implicitly when other users get access to a user record. It thus
637takes the role of the `/etc/shadow` records for each user, which has similarly
638restrictive access semantics. The following fields are currently defined:
639
640`passwordHint` → A user-selected password hint in free-form text. This should
641be a string like "What's the name of your first pet?", but is entirely for the
642user to choose.
643
ffc8eeae 644`hashedPassword` → An array of strings, each containing a hashed UNIX password
812862db 645string, in the format
e2285c57 646[`crypt(3)`](https://man7.org/linux/man-pages/man3/crypt.3.html) generates. This
812862db
LP
647corresponds with `sp_pwdp` field of `struct spwd` (and in a way the `pw_passwd`
648field of `struct passwd`).
649
650`sshAuthorizedKeys` → An array of strings, each listing an SSH public key that
651is authorized to access the account. The strings should follow the same format
13bf3216 652as the lines in the traditional `~/.ssh/authorized_keys` file.
812862db
LP
653
654`pkcs11EncryptedKey` → An array of objects. Each element of the array should be
655an object consisting of three string fields: `uri` shall contain a PKCS#11
fe2520fb 656security token URI, `data` shall contain a Base64-encoded encrypted key and
812862db
LP
657`hashedPassword` shall contain a UNIX password hash to test the key
658against. Authenticating with a security token against this account shall work
659as follows: the encrypted secret key is converted from its Base64
660representation into binary, then decrypted with the PKCS#11 `C_Decrypt()`
661function of the PKCS#11 module referenced by the specified URI, using the
662private key found on the same token. The resulting decrypted key is then
663Base64-encoded and tested against the specified UNIX hashed password. The
fe2520fb 664Base64-encoded decrypted key may also be used to unlock further resources
812862db
LP
665during log-in, for example the LUKS or `fscrypt` storage backend. It is
666generally recommended that for each entry in `pkcs11EncryptedKey` there's also
667a matching one in `pkcs11TokenUri` and vice versa, with the same URI, appearing
668in the same order, but this should not be required by applications processing
669user records.
670
fe2520fb
LP
671`fido2HmacSalt` → An array of objects, implementing authentication support with
672FIDO2 devices that implement the `hmac-secret` extension. Each element of the
673array should be an object consisting of three string fields: `credential`,
17e7561a
LP
674`salt`, `hashedPassword`, and three boolean fields: `up`, `uv` and
675`clientPin`. The first two string fields shall contain Base64-encoded binary
fe2520fb
LP
676data: the FIDO2 credential ID and the salt value to pass to the FIDO2
677device. During authentication this salt along with the credential ID is sent to
678the FIDO2 token, which will HMAC hash the salt with its internal secret key and
679return the result. This resulting binary key should then be Base64-encoded and
680used as string password for the further layers of the stack. The
681`hashedPassword` field of the `fido2HmacSalt` field shall be a UNIX password
17e7561a
LP
682hash to test this derived secret key against for authentication. The `up`, `uv`
683and `clientPin` booleans map to the FIDO2 concepts of the same name and encode
684whether the `uv`/`up` options are enabled during the authentication, and
685whether a PIN shall be required. It is generally recommended that for each
686entry in `fido2HmacSalt` there's also a matching one in `fido2HmacCredential`,
687and vice versa, with the same credential ID, appearing in the same order, but
688this should not be required by applications processing user records.
fe2520fb 689
64abd37a
LP
690`recoveryKey`→ An array of objects, each defining a recovery key. The object
691has two mandatory fields: `type` indicates the type of recovery key. The only
692currently permitted value is the string `modhex64`. The `hashedPassword` field
693contains a UNIX password hash of the normalized recovery key. Recovery keys are
694in most ways similar to regular passwords, except that they are generated by
695the computer, not chosen by the user, and are longer. Currently, the only
696supported recovery key format is `modhex64`, which consists of 64
697[modhex](https://developers.yubico.com/yubico-c/Manuals/modhex.1.html)
698characters (i.e. 256bit of information), in groups of 8 chars separated by
699dashes,
700e.g. `lhkbicdj-trbuftjv-tviijfck-dfvbknrh-uiulbhui-higltier-kecfhkbk-egrirkui`. Recovery
701keys should be accepted wherever regular passwords are. The `recoveryKey` field
702should always be accompanied by a `recoveryKeyType` field (see above), and each
703entry in either should map 1:1 to an entry in the other, in the same order and
704matching the type. When accepting a recovery key it should be brought
705automatically into normalized form, i.e. the dashes inserted when missing, and
706converted into lowercase before tested against the UNIX password hash, so that
707recovery keys are effectively case-insensitive.
708
812862db
LP
709## Fields in the `perMachine` section
710
711As mentioned, the `perMachine` section contains settings that shall apply to
712specific systems only. This is primarily interesting for resource management
713properties as they tend to require a per-system focus, however they may be used
714for other purposes too.
715
716The `perMachine` field in the top-level object is an array of objects. When
717processing the user record first the various fields on the top-level object
7480859a
LP
718should be parsed. Then, the `perMachine` array should be iterated in order, and
719the various settings within each contained object should be applied that match
720either the indicated machine ID or host name, overriding any corresponding
721settings previously parsed from the top-level object. There may be multiple
722array entries that match a specific system, in which case all settings should
723be applied. If the same option is set in the top-level object as in a
724per-machine object then the per-machine setting wins and entirely undoes the
725setting in the top-level object (i.e. no merging of properties that are arrays
726is done). If the same option is set in multiple per-machine objects the one
727specified later in the array wins (and here too no merging of individual fields
728is done, the later field always wins in full). To summarize, the order of
729application is (last one wins):
730
7311. Settings in the top-level object
7322. Settings in the first matching `perMachine` array entry
7333. Settings in the second matching `perMachine` array entry
7344. …
7355. Settings in the last matching `perMachine` array entry
812862db
LP
736
737The following fields are defined in this section:
738
da890466 739`matchMachineId` → An array of strings that are formatted 128-bit IDs in
812862db 740hex. If any of the specified IDs match the system's local machine ID
7480859a
LP
741(i.e. matches `/etc/machine-id`) the fields in this object are honored. (As a
742special case, if only a single machine ID is listed this field may be a single
743string rather than an array of strings.)
812862db 744
7480859a
LP
745`matchHostname` → An array of strings that are valid hostnames. If any of the
746specified hostnames match the system's local hostname, the fields in this
812862db
LP
747object are honored. If both `matchHostname` and `matchMachineId` are used
748within the same array entry, the object is honored when either match succeeds,
7480859a 749i.e. the two match types are combined in OR, not in AND. (As a special case, if
a15b9768 750only a single hostname is listed this field may be a single string rather
7480859a 751than an array of strings.)
812862db
LP
752
753These two are the only two fields specific to this section. All other fields
754that may be used in this section are identical to the equally named ones in the
755`regular` section (i.e. at the top-level object). Specifically, these are:
756
757`iconName`, `location`, `shell`, `umask`, `environment`, `timeZone`,
49e55abb 758`preferredLanguage`, `additionalLanguages`, `niceLevel`, `resourceLimits`, `locked`, `notBeforeUSec`,
812862db
LP
759`notAfterUSec`, `storage`, `diskSize`, `diskSizeRelative`, `skeletonDirectory`,
760`accessMode`, `tasksMax`, `memoryHigh`, `memoryMax`, `cpuWeight`, `ioWeight`,
761`mountNoDevices`, `mountNoSuid`, `mountNoExecute`, `cifsDomain`,
4c2ee5c7
LP
762`cifsUserName`, `cifsService`, `cifsExtraMountOptions`, `imagePath`, `uid`,
763`gid`, `memberOf`, `fileSystemType`, `partitionUuid`, `luksUuid`,
764`fileSystemUuid`, `luksDiscard`, `luksOfflineDiscard`, `luksCipher`,
765`luksCipherMode`, `luksVolumeKeySize`, `luksPbkdfHashAlgorithm`,
b04ff66b 766`luksPbkdfType`, `luksPbkdfForceIterations`, `luksPbkdfTimeCostUSec`, `luksPbkdfMemoryCost`,
fd83c98e 767`luksPbkdfParallelThreads`, `luksSectorSize`, `autoResizeMode`, `rebalanceWeight`,
9aa3e5eb
LP
768`rateLimitIntervalUSec`, `rateLimitBurst`, `enforcePasswordPolicy`,
769`autoLogin`, `stopDelayUSec`, `killProcesses`, `passwordChangeMinUSec`,
770`passwordChangeMaxUSec`, `passwordChangeWarnUSec`,
4c2ee5c7
LP
771`passwordChangeInactiveUSec`, `passwordChangeNow`, `pkcs11TokenUri`,
772`fido2HmacCredential`.
812862db
LP
773
774## Fields in the `binding` section
775
776As mentioned, the `binding` section contains additional fields about the user
777record, that bind it to the local system. These fields are generally used by a
778local user manager (such as `systemd-homed.service`) to add in fields that make
779sense in a local context but not necessarily in a global one. For example, a
780user record that contains no `uid` field in the regular section is likely
781extended with one in the `binding` section to assign a local UID if no global
782UID is defined.
783
784All fields in the `binding` section only make sense in a local context and are
785suppressed when the user record is ported between systems. The `binding` section
786is generally persisted on the system but not in the home directories themselves
787and the home directory is supposed to be fully portable and thus not contain
788the information that `binding` is supposed to contain that binds the portable
789record to a specific system.
790
791The `binding` sub-object on the top-level user record object is keyed by the
792machine ID the binding is intended for, which point to an object with the
793fields of the bindings. These fields generally match fields that may also be
794defined in the `regular` and `perMachine` sections, however override
795both. Usually, the `binding` value should not contain settings different from
796those set via `regular` or `perMachine`, however this might happen if some
797settings are not supported locally (think: `fscrypt` is recorded as intended
798storage mechanism in the `regular` section, but the local kernel does not
799support `fscrypt`, hence `directory` was chosen as implicit fallback), or have
800been changed in the `regular` section through updates (e.g. a home directory
801was created with `luks` as storage mechanism but later the user record was
802updated to prefer `subvolume`, which however doesn't change the actual storage
803used already which is pinned in the `binding` section).
804
805The following fields are defined in the `binding` section. They all have an
806identical format and override their equally named counterparts in the `regular`
807and `perMachine` sections:
808
809`imagePath`, `homeDirectory`, `partitionUuid`, `luksUuid`, `fileSystemUuid`,
810`uid`, `gid`, `storage`, `fileSystemType`, `luksCipher`, `luksCipherMode`,
811`luksVolumeKeySize`.
812
813## Fields in the `status` section
814
815As mentioned, the `status` section contains additional fields about the user
816record that are exclusively acquired during runtime, and that expose runtime
817metrics of the user and similar metadata that shall not be persisted but are
818only acquired "on-the-fly" when requested.
819
820This section is arranged similarly to the `binding` section: the `status`
821sub-object of the top-level user record object is keyed by the machine ID,
822which points to the object with the fields defined here. The following fields
823are defined:
824
da890466 825`diskUsage` → An unsigned 64-bit integer. The currently used disk space of the
812862db
LP
826home directory in bytes. This value might be determined in different ways,
827depending on the selected storage mechanism. For LUKS storage this is the file
828size of the loopback file or block device size. For the
829directory/subvolume/fscrypt storage this is the current disk space used as
830reported by the file system quota subsystem.
831
da890466 832`diskFree` → An unsigned 64-bit integer, denoting the number of "free" bytes in
812862db
LP
833the disk space allotment, i.e. usually the difference between the disk size as
834reported by `diskSize` and the used already as reported in `diskFree`, but
835possibly skewed by metadata sizes, disk compression and similar.
836
da890466 837`diskSize` → An unsigned 64-bit integer, denoting the disk space currently
812862db
LP
838allotted to the user, in bytes. Depending on the storage mechanism this can mean
839different things (see above). In contrast to the top-level field of the same
840(or the one in the `perMachine` section), this field reports the current size
841allotted to the user, not the intended one. The values may differ when user
842records are updated without the home directory being re-sized.
843
da890466 844`diskCeiling`/`diskFloor` → Unsigned 64-bit integers indicating upper and lower
812862db
LP
845bounds when changing the `diskSize` value, in bytes. These values are typically
846derived from the underlying data storage, and indicate in which range the home
847directory may be re-sized in, i.e. in which sensible range the `diskSize` value
848should be kept.
849
850`state` → A string indicating the current state of the home directory. The
851precise set of values exposed here are up to the service managing the home
852directory to define (i.e. are up to the service identified with the `service`
853field below). However, it is recommended to stick to a basic vocabulary here:
854`inactive` for a home directory currently not mounted, `absent` for a home
855directory that cannot be mounted currently because it does not exist on the
856local system, `active` for a home directory that is currently mounted and
857accessible.
858
859`service` → A string identifying the service that manages this user record. For
860example `systemd-homed.service` sets this to `io.systemd.Home` to all user
861records it manages. This is particularly relevant to define clearly the context
862in which `state` lives, see above. Note that this field also exists on the
863top-level object (i.e. in the `regular` section), which it overrides. The
864`regular` field should be used if conceptually the user record can only be
865managed by the specified service, and this `status` field if it can
866conceptually be managed by different managers, but currently is managed by the
867specified one.
868
869`signedLocally` → A boolean. If true indicates that the user record is signed
870by a public key for which the private key is available locally. This means that
871the user record may be modified locally as it can be re-signed with the private
872key. If false indicates that the user record is signed by a public key
873recognized by the local manager but whose private key is not available
874locally. This means the user record cannot be modified locally as it couldn't
875be signed afterwards.
876
da890466 877`goodAuthenticationCounter` → An unsigned 64-bit integer. This counter is
812862db
LP
878increased by one on every successful authentication attempt, i.e. an
879authentication attempt where a security token of some form was presented and it
880was correct.
881
da890466 882`badAuthenticationCounter` → An unsigned 64-bit integer. This counter is
812862db
LP
883increased by one on every unsuccessfully authentication attempt, i.e. an
884authentication attempt where a security token of some form was presented and it
885was incorrect.
886
da890466 887`lastGoodAuthenticationUSec` → An unsigned 64-bit integer, indicating the time
812862db
LP
888of the last successful authentication attempt in µs since the UNIX epoch (1970).
889
890`lastBadAuthenticationUSec` → Similar, but the timestamp of the last
891unsuccessfully authentication attempt.
892
da890466 893`rateLimitBeginUSec` → An unsigned 64-bit integer: the µs timestamp since the
812862db
LP
894UNIX epoch (1970) where the most recent rate limiting interval has been
895started, as configured with `rateLimitIntervalUSec`.
896
da890466 897`rateLimitCount` → An unsigned 64-bit integer, counting the authentication
812862db
LP
898attempts in the current rate limiting interval, see above. If this counter
899grows beyond the value configured in `rateLimitBurst` authentication attempts
900are temporarily refused.
901
902`removable` → A boolean value. If true the manager of this user record
903determined the home directory being on removable media. If false it was
904determined the home directory is in internal built-in media. (This is used by
905`systemd-logind.service` to automatically pick the right default value for
906`stopDelayUSec` if the field is not explicitly specified: for home directories
907on removable media the delay is selected very low to minimize the chance the
908home directory remains in unclean state if the storage device is removed from
909the system by the user).
910
a6f44d61
YW
911`accessMode` → The access mode currently in effect for the home directory
912itself.
67a6d399
LP
913
914`fileSystemType` → The file system type backing the home directory: a short
915string, such as "btrfs", "ext4", "xfs".
916
46c60f72
LP
917`fallbackShell`, `fallbackHomeDirectory` → These fields have the same contents
918and format as the `shell` and `homeDirectory` fields (see above). When the
919`useFallback` field (see below) is set to true, the data from these fields
920should override the fields of the same name without the `fallback` prefix.
921
922`useFallback` → A boolean that allows choosing between the regular `shell` and
923`homeDirectory` fields or the fallback fields of the same name (see above). If
924`true` the fallback fields should be used in place of the regular fields, if
925`false` or unset the regular fields should be used. This mechanism is used for
926enable subsystems such as SSH to allow logins into user accounts, whose homed
927directories need further unlocking (because the SSH native authentication
928cannot release a suitabable disk encryption key), which the fallback shell
929provides.
930
812862db
LP
931## Fields in the `signature` section
932
933As mentioned, the `signature` section of the user record may contain one or
934more cryptographic signatures of the user record. Like all others, this section
935is optional, and only used when cryptographic validation of user records shall
936be used. Specifically, all user records managed by `systemd-homed.service` will
937carry such signatures and the service refuses managing user records that come
938without signature or with signatures not recognized by any locally defined
939public key.
940
941The `signature` field in the top-level user record object is an array of
942objects. Each object encapsulates one signature and has two fields: `data` and
943`key` (both are strings). The `data` field contains the actual signature,
fe2520fb 944encoded in Base64, the `key` field contains a copy of the public key whose
812862db
LP
945private key was used to make the signature, in PEM format. Currently only
946signatures with Ed25519 keys are defined.
947
948Before signing the user record should be brought into "normalized" form,
949i.e. the keys in all objects should be sorted alphabetically. All redundant
950white-space and newlines should be removed and the JSON text then signed.
951
952The signatures only cover the `regular`, `perMachine` and `privileged` sections
953of the user records, all other sections (include `signature` itself), are
954removed before the signature is calculated.
955
956Rationale for signing and threat model: while a multi-user operating system
957like Linux strives for being sufficiently secure even after a user acquired a
958local login session reality tells us this is not the case. Hence it is
959essential to restrict carefully which users may gain access to a system and
960which ones shall not. A minimal level of trust must be established between
961system, user record and the user themselves before a log-in request may be
962permitted. In particular if the home directory is provided in its own LUKS2
963encapsulated file system it is essential this trust is established before the
964user logs in (and hence the file system mounted), since file system
965implementations on Linux are well known to be relatively vulnerable to rogue
966disk images. User records and home directories in many context are expected to
967be something shareable between multiple systems, and the transfer between them
968might not happen via exclusively trusted channels. Hence it's essential that
969the user record is not manipulated between uses. Finally, resource management
970(which may be done by the various fields of the user record) is security
971sensitive, since it should forcefully lock the user into the assigned resource
972usage and not allow them to use more. The requirement of being able to trust
973the user record data combined with the potential transfer over untrusted
974channels suggest a cryptographic signature mechanism where only user records
975signed by a recognized key are permitted to log in locally.
976
977Note that other mechanisms for establishing sufficient trust exist too, and are
978perfectly valid as well. For example, systems like LDAP/ActiveDirectory
979generally insist on user record transfer from trusted servers via encrypted TLS
980channels only. Or traditional UNIX users created locally in `/etc/passwd` never
981exist outside of the local trusted system, hence transfer and trust in the
982source are not an issue. The major benefit of operating with signed user
983records is that they are self-sufficiently trusted, not relying on a secure
984channel for transfer, and thus being compatible with a more distributed model
985of home directory transfer, including on USB sticks and such.
986
987## Fields in the `secret` section
988
989As mentioned, the `secret` section of the user record should never be persisted
990nor transferred across machines. It is only defined in short-lived operations,
991for example when a user record is first created or registered, as the secret
992key data needs to be available to derive encryption keys from and similar.
993
994The `secret` field of the top-level user record contains the following fields:
995
996`password` → an array of strings, each containing a plain text password.
997
c0bde0d2
LP
998`tokenPin` → an array of strings, each containing a plain text PIN, suitable
999for unlocking security tokens that require that. (The field `pkcs11Pin` should
1000be considered a compatibility alias for this field, and merged with `tokenPin`
1001in case both are set.)
812862db
LP
1002
1003`pkcs11ProtectedAuthenticationPathPermitted` → a boolean. If set to true allows
1004the receiver to use the PKCS#11 "protected authentication path" (i.e. a
1005physical button/touch element on the security token) for authenticating the
fe2520fb
LP
1006user. If false or unset, authentication this way shall not be attempted.
1007
1008`fido2UserPresencePermitted` → a boolean. If set to true allows the receiver to
1009use the FIDO2 "user presence" flag. This is similar to the concept of
17e7561a
LP
1010`pkcs11ProtectedAuthenticationPathPermitted`, but exposes the FIDO2 "up"
1011concept behind it. If false or unset authentication this way shall not be
1012attempted.
1013
1014`fido2UserVerificationPermitted` → a boolean. If set to true allows the
1015receiver to use the FIDO2 "user verification" flag. This is similar to the
1016concept of `pkcs11ProtectedAuthenticationPathPermitted`, but exposes the FIDO2
1017"uv" concept behind it. If false or unset authentication this way shall not be
1018attempted.
812862db
LP
1019
1020## Mapping to `struct passwd` and `struct spwd`
1021
1022When mapping classic UNIX user records (i.e. `struct passwd` and `struct spwd`)
1023to JSON user records the following mappings should be applied:
1024
1025| Structure | Field | Section | Field | Condition |
1026|-----------------|-------------|--------------|------------------------------|----------------------------|
1027| `struct passwd` | `pw_name` | `regular` | `userName` | |
1028| `struct passwd` | `pw_passwd` | `privileged` | `password` | (See notes below) |
1029| `struct passwd` | `pw_uid` | `regular` | `uid` | |
1030| `struct passwd` | `pw_gid` | `regular` | `gid` | |
1031| `struct passwd` | `pw_gecos` | `regular` | `realName` | |
1032| `struct passwd` | `pw_dir` | `regular` | `homeDirectory` | |
1033| `struct passwd` | `pw_shell` | `regular` | `shell` | |
1034| `struct spwd` | `sp_namp` | `regular` | `userName` | |
1035| `struct spwd` | `sp_pwdp` | `privileged` | `password` | (See notes below) |
1036| `struct spwd` | `sp_lstchg` | `regular` | `lastPasswordChangeUSec` | (if `sp_lstchg` > 0) |
1037| `struct spwd` | `sp_lstchg` | `regular` | `passwordChangeNow` | (if `sp_lstchg` == 0) |
1038| `struct spwd` | `sp_min` | `regular` | `passwordChangeMinUSec` | |
1039| `struct spwd` | `sp_max` | `regular` | `passwordChangeMaxUSec` | |
1040| `struct spwd` | `sp_warn` | `regular` | `passwordChangeWarnUSec` | |
1041| `struct spwd` | `sp_inact` | `regular` | `passwordChangeInactiveUSec` | |
1042| `struct spwd` | `sp_expire` | `regular` | `locked` | (if `sp_expire` in [0, 1]) |
1043| `struct spwd` | `sp_expire` | `regular` | `notAfterUSec` | (if `sp_expire` > 1) |
1044
1045At this time almost all Linux machines employ shadow passwords, thus the
1046`pw_passwd` field in `struct passwd` is set to `"x"`, and the actual password
1047is stored in the shadow entry `struct spwd`'s field `sp_pwdp`.
1048
1049## Extending These Records
1050
1051User records following this specifications are supposed to be extendable for
1052various applications. In general, subsystems are free to introduce their own
1053keys, as long as:
1054
1055* Care should be taken to place the keys in the right section, i.e. the most
1056 appropriate for the data field.
1057
1058* Care should be taken to avoid namespace clashes. Please prefix your fields
1059 with a short identifier of your project to avoid ambiguities and
1060 incompatibilities.
1061
1062* This specification is supposed to be a living specification. If you need
1063 additional fields, please consider submitting them upstream for inclusion in
1064 this specification. If they are reasonably universally useful, it would be
1065 best to list them here.
1066
1067## Examples
1068
1069The shortest valid user record looks like this:
1070
1071```json
1072{
1073 "userName" : "u"
1074}
1075```
1076
1077A reasonable user record for a system user might look like this:
1078
1079```json
1080{
1081 "userName" : "httpd",
1082 "uid" : 473,
1083 "gid" : 473,
1084 "disposition" : "system",
1085 "locked" : true
1086}
1087```
1088
1089A fully featured user record associated with a home directory managed by
1090`systemd-homed.service` might look like this:
1091
1092```json
1093{
1094 "autoLogin" : true,
1095 "binding" : {
1096 "15e19cf24e004b949ddaac60c74aa165" : {
1097 "fileSystemType" : "ext4",
1098 "fileSystemUuid" : "758e88c8-5851-4a2a-b88f-e7474279c111",
1099 "gid" : 60232,
1100 "homeDirectory" : "/home/grobie",
1101 "imagePath" : "/home/grobie.home",
1102 "luksCipher" : "aes",
1103 "luksCipherMode" : "xts-plain64",
1104 "luksUuid" : "e63581ba-79fb-4226-b9de-1888393f7573",
1105 "luksVolumeKeySize" : 32,
1106 "partitionUuid" : "41f9ce04-c827-4b74-a981-c669f93eb4dc",
1107 "storage" : "luks",
1108 "uid" : 60232
1109 }
1110 },
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 "status" : {
1130 "15e19cf24e004b949ddaac60c74aa165" : {
1131 "goodAuthenticationCounter" : 16,
1132 "lastGoodAuthenticationUSec" : 1566309343044322,
1133 "rateLimitBeginUSec" : 1566309342340723,
1134 "rateLimitCount" : 1,
1135 "state" : "inactive",
1136 "service" : "io.systemd.Home",
1137 "diskSize" : 161118667776,
1138 "diskCeiling" : 190371729408,
1139 "diskFloor" : 5242880,
1140 "signedLocally" : true
1141 }
1142 }
1143}
1144```
1145
1146When `systemd-homed.service` manages a home directory it will also include a
1147version of the user record in the home directory itself in the `~/.identity`
1148file. This version lacks the `binding` and `status` sections which are used for
1149local management of the user, but are not intended to be portable between
1150systems. It would hence look like this:
1151
1152```json
1153{
1154 "autoLogin" : true,
1155 "disposition" : "regular",
1156 "enforcePasswordPolicy" : false,
1157 "lastChangeUSec" : 1565950024279735,
1158 "memberOf" : [
1159 "wheel"
1160 ],
1161 "privileged" : {
1162 "hashedPassword" : [
1163 "$6$WHBKvAFFT9jKPA4k$OPY4D4TczKN/jOnJzy54DDuOOagCcvxxybrwMbe1SVdm.Bbr.zOmBdATp.QrwZmvqyr8/SafbbQu.QZ2rRvDs/"
1164 ]
1165 },
1166 "signature" : [
1167 {
1168 "data" : "LU/HeVrPZSzi3MJ0PVHwD5m/xf51XDYCrSpbDRNBdtF4fDVhrN0t2I2OqH/1yXiBidXlV0ptMuQVq8KVICdEDw==",
1169 "key" : "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEA/QT6kQWOAMhDJf56jBmszEQQpJHqDsGDMZOdiptBgRk=\n-----END PUBLIC KEY-----\n"
1170 }
1171 ],
1172 "userName" : "grobie",
1173}
1174```