SYSTEMD.SYSTEM-CREDENTIALS(7)

๐ŸŽ€ SYSTEMD.SYSTEM-CREDENTIALS(7) ๐ŸŽ€

okay bestie, gather round ๐Ÿ’– this is the manual page for systemd.system-credentials โ€” aka System Credentials. It's a long one, so buckle up, we're doing this in parts.


โœจ NAME โœจ

systemd.system-credentials โ€” System Credentials ๐Ÿ—๏ธ


๐ŸŒธ DESCRIPTION ๐ŸŒธ

System and Service Credentials[1] are data objects that can get passed into booted systems or into system services as they're invoked. Think of them like lil care packages ๐Ÿ“ฆ that show up exactly when something needs them.

They can be acquired from all kinds of external sources, and they get propagated into the system and from there into system services. Credentials can optionally be encrypted with a machine-specific key and/or locked to the local TPM2 device ๐Ÿ” โ€” and they're only decrypted when the consuming service is invoked. So they stay locked up till the last possible second. Iconic behaviour honestly.

System credentials can be used to provision and configure various aspects of the system. Depending on which component is consuming them, credentials are either only used on initial invocations, or they're needed for all invocations.

Credentials can be used for any kind of data, binary or text โ€” passwords, secrets, certificates, cryptographic key material, identity information, configuration, and more. no cap, whatever you need to smuggle in there ๐Ÿ’…


๐Ÿ‘‘ WELL KNOWN SYSTEM CREDENTIALS ๐Ÿ‘‘

These are the credentials that have a defined meaning, so if you use these names, things actually happen. Let's go one by one.

  • firstboot.keymap โ€” the console key mapping to set (like "de"). Read by systemd-firstboot(1), and only honoured if no console keymap has been configured before.

Added in version 252.

  • firstboot.hostname โ€” this credential says what static system hostname to set during first boot. The user won't get prompted for the hostname. Heads up tho: this controls the static hostname, not the transient hostname, and it only has an effect on first boot โ€” unlike system.hostname (which you'll meet further down ๐Ÿ‘‡). Read by systemd-firstboot(1), and only honoured if no static hostname has been configured before. The value may use the wildcard patterns documented in hostname(5) (like "$-$" or "foo-????"). When the credential is applied on the running system (which is the usual case, done by systemd-firstboot.service on first boot), the wildcards get resolved against the machine ID and the resulting concrete name is written to /etc/hostname. So the name is persisted once at first boot and does not change on subsequent boots โ€” even if the word lists get updated later or the pattern is changed (for example to add more "?"/"$" tokens for extra entropy). And that's actually the recommended way to get a stable, per-machine generated hostname. ๐ŸŽ€ (But when systemd-firstboot(1) operates on an offline image via --root=/--image=, the target's machine ID isn't known yet, so the pattern gets written verbatim and, just like a pattern placed directly in /etc/hostname, it's re-derived on every boot instead of persisted.)

Added in version 261.

  • firstboot.locale, firstboot.locale-messages โ€” the system locale to set (like "de_DE.UTF-8"). Read by systemd-firstboot(1), and only honoured if no locale has been configured before. firstboot.locale sets "LANG", while firstboot.locale-message sets "LC_MESSAGES".

Added in version 252.

  • firstboot.timezone โ€” the system timezone to set (like "Europe/Berlin"). Read by systemd-firstboot(1), and only honoured if no system timezone has been configured before. ๐ŸŒ

Added in version 252.

  • firstboot.machine-tags โ€” the machine tags to set, as a colon-separated list (like "webserver:frontend:berlin"). Read by systemd-firstboot(1), and only honoured if /etc/machine-info hasn't been configured before. It gets written into the TAGS= field of that file โ€” see machine-info(5) for the deets.

Added in version 261.

  • login.issue โ€” the data of this credential gets written to /etc/issue.d/50-provision.conf, if that file doesn't exist yet. agetty(8) reads this file and shows its contents at the login prompt of terminal logins. See issue(5) for details.

Consumed by /usr/lib/tmpfiles.d/provision.conf, see tmpfiles.d(5).

Added in version 252.

  • login.motd โ€” the data of this credential gets written to /etc/motd.d/50-provision.conf, if that file doesn't exist yet. pam_motd(8) reads this file and shows its contents as the "message of the day" during terminal logins. See motd(5) for details.

Consumed by /usr/lib/tmpfiles.d/provision.conf, see tmpfiles.d(5).

Added in version 252.

  • network.hosts โ€” the data of this credential gets written to /etc/hosts, if that file doesn't exist yet. See hosts(5) for details.

Consumed by /usr/lib/tmpfiles.d/provision.conf, see tmpfiles.d(5).

Added in version 252.

  • network.dns, network.search_domains โ€” DNS server information and search domains. Read by systemd-resolved.service(8). ๐Ÿฆ‹

Added in version 253.

Heads up bestie โš ๏ธ the resulting files are created world-readable, so it's recommended to not put secrets in these credentials. Instead, supply those via separate credentials directly to systemd-networkd.service, e.g. network.wireguard.* as described below.

Added in version 256.

Added in version 256.

  • passwd.hashed-password.root, passwd.plaintext-password.root โ€” may contain the password (either in UNIX hashed format, or in plaintext) for the root users. Read by both systemd-firstboot(1) and systemd-sysusers(8), and only honoured if no root password has been configured before.

Added in version 252.

  • passwd.shell.root โ€” the path to the shell program (like "/bin/bash") for the root user. Read by both systemd-firstboot(1) and systemd-sysusers(8), and only honoured if no root shell has been configured before.

Added in version 252.

  • ssh.ephemeral-authorized_keys-all โ€” provides additional public keys, given in the customary authorized_keys format, for all users, for incoming connections via the generated AF_VSOCK and AF_UNIX socket units.

The intended use of this is for a host system (in either VM or container configurations) to generate a keypair and inject the public key into the guest, using the private key to connect to any user account on the guest via ssh, without further authentication. ๐Ÿ”‘

Consumed by systemd-ssh-generator(8).

Added in version 256.

  • ssh.authorized_keys.root โ€” the data of this credential gets written to /root/.ssh/authorized_keys, if that file doesn't exist yet. This lets you provision SSH access for the system's root user.

Consumed by /usr/lib/tmpfiles.d/provision.conf, see tmpfiles.d(5).

Added in version 252.

  • ssh.listen โ€” may be used to configure the SSH sockets the system shall be reachable on. See systemd-ssh-generator(8) for details.

Added in version 256.

  • sysusers.extra โ€” additional sysusers.d(5) lines to process during boot.

Added in version 252.

  • sysctl.extra โ€” additional sysctl.d(5) lines to process during boot.

Added in version 252.

  • tmpfiles.extra โ€” additional tmpfiles.d(5) lines to process during boot.

Added in version 252.

Added in version 254.

  • vconsole.keymap, vconsole.keymap_toggle, vconsole.font, vconsole.font_map, vconsole.font_unimap, vconsole.font_scale โ€” console settings to apply, see systemd-vconsole-setup.service(8) for details.

vconsole.font_scale was added in version 262.

Added in version 253.

  • getty.auto โ€” used for controlling the execution mode of systemd-getty-generator. See systemd-getty-generator(8) for details.

Added in version 258.

  • getty.ttys.serial, getty.ttys.container โ€” used for spawning additional login prompts, see systemd-getty-generator(8) for details.

Added in version 254.

Added in version 256.

Added in version 256.

  • vmm.notify_socket โ€” configures an sd_notify(3) compatible AF_VSOCK socket that the service manager will report status information, ready notification and exit status on. For details see systemd(1).

Added in version 253.

  • shell.prompt.prefix, shell.prompt.suffix โ€” defines strings to prefix and suffix any interactive UNIX shell prompt with. For details see pam_systemd(8). โœจ

Added in version 257.

  • shell.welcome โ€” defines a string to print when an interactive UNIX shell initializes. For details see pam_systemd(8).

Added in version 257.

  • system.machine_id โ€” takes a 128bit ID to initialize the machine ID from (if it isn't set yet). Interpreted by the service manager (PID 1). For details see systemd(1).

Added in version 254.

  • system.hostname โ€” accepts a (transient) hostname to configure during early boot. The static hostname specified in /etc/hostname, if configured, takes precedence over this setting. Interpreted by the service manager (PID 1). For details see systemd(1). Also see firstboot.hostname above. The value may use the wildcard patterns documented in hostname(5) ("?" and "$"), which are expanded deterministically from the machine ID when the credential is applied. Since this is a transient hostname that gets re-applied on every boot, a wildcard value is re-derived each boot (and may change if the word lists change) and is never persisted โ€” so pass an already-resolved name if you need a stable hostname. Note also that the word-list tokens require the word lists to be present, which is generally not the case in the initrd, so during initrd the default hostname is used and in late boot the resolved one becomes available. ๐Ÿ’ซ

Added in version 254.

  • home.add-signing-key.* โ€” drops a brand new signing key for user records into the system. The credential contents should hold a user signing key, like the one you'd get back from homectl get-signing-key. You can pass multiple keys, and they all get put in place under the name of the credential-name suffix โ€” and that suffix must itself carry the .public suffix, no exceptions bestie. Full details are in homectl(1).
    • Added in version 258.
  • home.create.* โ€” makes a whole new home area for the user you specify, using the user record data you pass in. The tea is in homectl(1).
    • Added in version 256.
  • home.register.* โ€” registers a home area that already exists for the user you specify, with the user record data you pass in. Again, homectl(1) has the lore.
    • Added in version 258.
  • cryptsetup.passphrase, cryptsetup.tpm2-pin, cryptsetup.fido2-pin, cryptsetup.pkcs11-pin, cryptsetup.luks2-pin โ€” the passphrase/PINs used to unlock encrypted storage volumes ๐Ÿ”โœจ. Details over in systemd-cryptsetup(8).
    • Added in version 256.
  • systemd.extra-unit.*, systemd.unit-dropin.* โ€” extra units and drop-ins you wanna add to the system. systemd-debug-generator(8) has the whole rundown.
    • Added in version 256.
  • udev.conf.*, udev.rules.* โ€” configures the udev configuration file and udev rules ๐Ÿ“ฆ. These get read by systemd-udev-load-credentials.service, which invokes udevadm control --load-credentials. Every one of these credentials translates directly into a matching udev.conf(5) or udev(7) rules file. Example, since examples ate: the contents of a credential udev.conf.50-foobar get copied into a file /run/udev/udev.conf.d/50-foobar.conf, and udev.rules.50-foobar gets copied into a file /run/udev/rules.d/50-foobar.rules. Peep udev(7), udev.conf(5), and udevadm(8) for the details.
    • Added in version 256.
  • import.pull โ€” the disk images (tarballs and DDIs) you want to automatically download and install at boot ๐Ÿซถ. Details in systemd-import-generator(8).
    • Added in version 257.
  • userdb.user.*, userdb.group.*, userdb.transient.user.*, userdb.transient.group.* โ€” configures JSON user and group records ๐Ÿ‘‘. Read by systemd-userdb-load-credentials.service, which invokes userdbctl load-credentials. Each of these credentials translates directly into a matching JSON User[2] and JSON Group[3] record. Example: the contents of a credential userdb.user.foobar get copied into a file /etc/userdb/foobar.user, and userdb.group.foobar gets copied into a file /etc/userdb/foobar.group. Symlinks for the uid/gid also get created in /etc/userdb/, plus the corresponding .membership files. See systemd-userdbd.service(8), nss-systemd(8), and userdbctl(1) for the details.
    • Any user records you pass must contain uid and gid fields. Any group records you pass must contain a gid field. For both user and group records, the credential suffix (for "userdb.user.foobar" the suffix is "foobar") has to match the user or group name field from the user or group record.
    • Lowkey important: records created for userdb.user.* and userdb.group.* credentials land in /etc/userdb/, while records created for userdb.transient.user.* and userdb.transient.group.* land in /run/userdb/. And no, /etc/passwd and /etc/group do not get modified ๐Ÿ™ˆ.
    • Added in version 258.
  • fsck.* โ€” read by systemd-fsck@.service, systemd-fsck-root.service, and systemd-fsck-usr.service. systemd-fsck@.service(8) has more for you.
    • Added in version 258.
  • quotacheck.* โ€” read by systemd-quotacheck@.service and systemd-quotacheck-root.service. More details in systemd-quotacheck(8).
    • Added in version 258.
  • imds.* โ€” read by systemd-imdsd@.service(8) โœจ.
    • Added in version 261.

๐Ÿ” SEE ALSO ๐Ÿ”

systemd(1), kernel-command-line(7), smbios-type-11(7)


๐Ÿ“ NOTES ๐Ÿ“

  1. System and Service Credentials โ€” https://systemd.io/CREDENTIALS
  2. JSON User โ€” https://systemd.io/USER_RECORD
  3. JSON Group โ€” https://systemd.io/GROUP_RECORD

And that's the whole page bestie, we did it ๐Ÿ’… This was the SYSTEMD.SYSTEM-CREDENTIALS(7) manual, and the footer told us it came from systemd 262.1 โ€” so if you're running something way older, some of these credentials literally didn't exist yet, iykyk. Go credential responsibly ๐ŸŽ€๐Ÿฆ‹๐ŸŒธ

๐Ÿ“ฆ where this page comes from
  • arch rolling: systemd 262.1-1 ยท LGPL-2.1-or-later AND CC0-1.0 AND GPL-2.0-or-later AND MIT-0
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms