- When defining a new user, one of [users.users._name_.isNormalUser](options.html#opt-users.users._name_.isNormalUser) and [users.users._name_.isSystemUser](options.html#opt-users.users._name_.isSystemUser) is now required. This is to prevent accidentally giving a UID above 1000 to system users, which could have unexpected consequences, like running user activation scripts for system users. Note that users defined with an explicit UID below 500 are exempted from this check, as [users.users._name_.isSystemUser](options.html#opt-users.users._name_.isSystemUser) has no effect for those.
- The `security.apparmor` module, for the [AppArmor](https://gitlab.com/apparmor/apparmor/-/wikis/Documentation) Mandatory Access Control system, has been substantially improved along with related tools, so that module maintainers can now more easily write AppArmor profiles for NixOS. The most notable change on the user-side is the new option [security.apparmor.policies](options.html#opt-security.apparmor.policies), replacing the previous `profiles` option to provide a way to disable a profile and to select whether to confine in enforce mode (default) or in complain mode (see `journalctl -b --grep apparmor`). Security-minded users may also want to enable [security.apparmor.killUnconfinedConfinables](options.html#opt-security.apparmor.killUnconfinedConfinables), at the cost of having some of their processes killed when updating to a NixOS version introducing new AppArmor profiles.
- The GNOME desktop manager once again installs gnome.epiphany by default.
- NixOS now generates empty `/etc/netgroup`. `/etc/netgroup` defines network-wide groups and may affect to setups using NIS.
- Platforms, like `stdenv.hostPlatform`, no longer have a `platform` attribute. It has been (mostly) flattened away:
- `platform.gcc` is now `gcc`
- `platform.kernel*` is now `linux-kernel.*`
Additionally, `platform.kernelArch` moved to the top level as `linuxArch` to match the other `*Arch` variables.
The `platform` grouping of these things never meant anything, and was just a historial/implementation artifact that was overdue removal.
- `services.restic` now uses a dedicated cache directory for every backup defined in `services.restic.backups`. The old global cache directory, `/root/.cache/restic`, is now unused and can be removed to free up disk space.
- `isync`: The `isync` compatibility wrapper was removed and the Master/Slave terminology has been deprecated and should be replaced with Far/Near in the configuration file.
- The nix-gc service now accepts randomizedDelaySec (default: 0) and persistent (default: true) parameters. By default nix-gc will now run immediately if it would have been triggered at least once during the time when the timer was inactive.
- The `rustPlatform.buildRustPackage` function is split into several hooks: cargoSetupHook to set up vendoring for Cargo-based projects, cargoBuildHook to build a project using Cargo, cargoInstallHook to install a project using Cargo, and cargoCheckHook to run tests in Cargo-based projects. With this change, mixed-language projects can use the relevant hooks within builders other than `buildRustPackage`. However, these changes also required several API changes to `buildRustPackage` itself:
- The `target` argument was removed. Instead, `buildRustPackage` will always use the same target as the C/C++ compiler that is used.