Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Deterministic ids

# https://github.com/oddlama/nix-config/blob/main/modules/system/deteministic-ids.nix
{
  lib,
  config,
  ...
}:
let
  inherit (lib)
    concatLists
    flip
    mapAttrsToList
    mdDoc
    mkDefault
    mkIf
    mkOption
    types
    ;

  cfg = config.users.deterministicIds;
in
{
  options = {
    users.deterministicIds = mkOption {
      default = { };
      description = mdDoc ''
        Maps a user or group name to its expected uid/gid values. If a user/group is
        used on the system without specifying a uid/gid, this module will assign the
        corresponding ids defined here, or show an error if the definition is missing.
      '';
      type = types.attrsOf (
        types.submodule {
          options = {
            uid = mkOption {
              type = types.nullOr types.int;
              default = null;
              description = mdDoc "The uid to assign if it is missing in `users.users.<name>`.";
            };
            gid = mkOption {
              type = types.nullOr types.int;
              default = null;
              description = mdDoc "The gid to assign if it is missing in `users.groups.<name>`.";
            };
          };
        }
      );
    };

    users.users = mkOption {
      type = types.attrsOf (
        types.submodule (
          { name, ... }:
          {
            config.uid =
              let
                deterministicUid = cfg.${name}.uid or null;
              in
              mkIf (deterministicUid != null) (mkDefault deterministicUid);
          }
        )
      );
    };

    users.groups = mkOption {
      type = types.attrsOf (
        types.submodule (
          { name, ... }:
          {
            config.gid =
              let
                deterministicGid = cfg.${name}.gid or null;
              in
              mkIf (deterministicGid != null) (mkDefault deterministicGid);
          }
        )
      );
    };
  };

  config = {
    assertions =
      concatLists (
        flip mapAttrsToList config.users.users (
          name: user: [
            {
              assertion = user.uid != null;
              message = "non-deterministic uid detected for '${name}', please assign one via `users.deterministicIds`";
            }
            {
              assertion = !user.autoSubUidGidRange;
              message = "non-deterministic subUids/subGids detected for: ${name}";
            }
          ]
        )
      )
      ++ flip mapAttrsToList config.users.groups (
        name: group: {
          assertion = group.gid != null;
          message = "non-deterministic gid detected for '${name}', please assign one via `users.deterministicIds`";
        }
      );
  };
}