From 9f6ba542cae5ef4580c3e8d87f9198727632296d Mon Sep 17 00:00:00 2001 From: Chris Moultrie <821688+tebriel@users.noreply.github.com> Date: Mon, 15 Jun 2026 15:44:54 -0400 Subject: [PATCH 1/2] homebox: 0.25.0 -> 0.26.2 changelog: https://github.com/sysadminsmedia/homebox/releases/tag/v0.26.2 --- doc/release-notes/rl-2611.section.md | 2 ++ pkgs/by-name/ho/homebox/package.nix | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/release-notes/rl-2611.section.md b/doc/release-notes/rl-2611.section.md index 33cdf427dd32..9e9d1a5dfda5 100644 --- a/doc/release-notes/rl-2611.section.md +++ b/doc/release-notes/rl-2611.section.md @@ -123,6 +123,8 @@ - `keycloak` was updated to >= 26.7.0 and includes some breaking internal (API) changes. See the [upstream migration guide](https://www.keycloak.org/docs/latest/upgrading/#migrating-to-26-7-0) for more information. +- `homebox` v0.26.0 introduced a new, required value to be set, `HBOX_AUTH_API_KEY_PEPPER`. It cannot be started without this. + - `librest` providing 0.7 ABI was removed. `librest_1_0` providing 1.0 ABI was renamed to `librest` and `librest_1_0` was kept as an alias. - `luaPackages.lrexlib-pcre` has been removed as part of the process to fully migrate from the end-of-life PRCE library to PCRE2. `luaPackages.lrexlib-pcre2` and multiple other versions of lrexlib can be used instead. diff --git a/pkgs/by-name/ho/homebox/package.nix b/pkgs/by-name/ho/homebox/package.nix index 8b68f19b72a8..3c895adea089 100644 --- a/pkgs/by-name/ho/homebox/package.nix +++ b/pkgs/by-name/ho/homebox/package.nix @@ -13,18 +13,18 @@ }: let pname = "homebox"; - version = "0.25.0"; + version = "0.26.2"; src = fetchFromGitHub { owner = "sysadminsmedia"; repo = "homebox"; tag = "v${version}"; - hash = "sha256-mAC7n8AjsSHzO+l0ILJhf4LPAuVZ5KIYO6mXftZpVbE="; + hash = "sha256-JUhRpUWbydy28Xw7j6oCKJLBmaOxcruWAdkqm+hvouY="; }; in buildGoModule { inherit pname version src; - vendorHash = "sha256-FuZEGUduKZyTuW63z3rk8g1KE8wyx55xoNSvqbvF0PA="; + vendorHash = "sha256-peQaPSbxGn8MnbZPqCi5ptW+dMh9l4W1hB6HqBLTqh4="; modRoot = "backend"; # the goModules derivation inherits our buildInputs and buildPhases # Since we do pnpm thing in those it fails if we don't explicitly remove them @@ -42,7 +42,7 @@ buildGoModule { src = "${src}/frontend"; pnpm = pnpm_10; fetcherVersion = 3; - hash = "sha256-LrK0ijH8ahmDU4t9ckmIf1TJmybLLDRRHA67djUwRBk="; + hash = "sha256-oHS2uMWyuqpiK7yWznmZ2mgxPJpWsyOZL2wz6zBu0cc="; }; pnpmRoot = "../frontend"; From cdb300c9a34d5f24b9cf2c2a582b92d42c1f5daf Mon Sep 17 00:00:00 2001 From: Chris Moultrie <821688+tebriel@users.noreply.github.com> Date: Mon, 15 Jun 2026 15:45:57 -0400 Subject: [PATCH 2/2] nixos.homebox: handle new AUTH_API_KEY_PEPPER configuration Assisted-By: GitHub Copilot:gpt-5.4 --- doc/release-notes/rl-2611.section.md | 4 +- nixos/modules/services/web-apps/homebox.nix | 164 ++++++++++++++------ nixos/tests/homebox.nix | 30 +++- 3 files changed, 148 insertions(+), 50 deletions(-) diff --git a/doc/release-notes/rl-2611.section.md b/doc/release-notes/rl-2611.section.md index 9e9d1a5dfda5..ed43b7af0412 100644 --- a/doc/release-notes/rl-2611.section.md +++ b/doc/release-notes/rl-2611.section.md @@ -123,8 +123,6 @@ - `keycloak` was updated to >= 26.7.0 and includes some breaking internal (API) changes. See the [upstream migration guide](https://www.keycloak.org/docs/latest/upgrading/#migrating-to-26-7-0) for more information. -- `homebox` v0.26.0 introduced a new, required value to be set, `HBOX_AUTH_API_KEY_PEPPER`. It cannot be started without this. - - `librest` providing 0.7 ABI was removed. `librest_1_0` providing 1.0 ABI was renamed to `librest` and `librest_1_0` was kept as an alias. - `luaPackages.lrexlib-pcre` has been removed as part of the process to fully migrate from the end-of-life PRCE library to PCRE2. `luaPackages.lrexlib-pcre2` and multiple other versions of lrexlib can be used instead. @@ -165,6 +163,8 @@ - The fwts efi-runtime kernel module was removed. +- `homebox` v0.26.0 introduced a new, required value to be set, `HBOX_AUTH_API_KEY_PEPPER`. If one is not provided the module will create one, it is recommended that you back this up as it is part of API Key generation and validation. + - Emacs loads the `early-default` library after `early-init.el`. Users can add `early-init.el` via `emacs.pkgs.withPackages` by packaging `early-init.el` into a library named `early-default`. diff --git a/nixos/modules/services/web-apps/homebox.nix b/nixos/modules/services/web-apps/homebox.nix index 901d393d86ec..86d5a22a9326 100644 --- a/nixos/modules/services/web-apps/homebox.nix +++ b/nixos/modules/services/web-apps/homebox.nix @@ -1,12 +1,14 @@ { lib, config, + options, pkgs, ... }: let cfg = config.services.homebox; inherit (lib) + literalExpression mkEnableOption mkPackageOption mkDefault @@ -17,6 +19,11 @@ let defaultUser = "homebox"; defaultGroup = "homebox"; + + pepperDefault = + (cfg.secrets ? HBOX_AUTH_API_KEY_PEPPER) + && (cfg.secrets.HBOX_AUTH_API_KEY_PEPPER == "/var/lib/homebox/api-pepper-secret"); + opts = options.services.homebox; in { options.services.homebox = { @@ -61,6 +68,37 @@ in ''; }; }; + secrets = mkOption { + type = types.submodule { + options = { + HBOX_AUTH_API_KEY_PEPPER = mkOption { + type = types.externalPath; + default = "/var/lib/homebox/api-pepper-secret"; + description = '' + Path to the API key pepper secret file (required for homebox to start). + ''; + example = "/run/secrets/homebox-api-pepper"; + }; + }; + freeformType = types.attrsOf types.externalPath; + }; + + default = { }; + description = '' + This follows the same structure as {option}`${opts.settings}` + but the value of each key is a path. + + The specified secret path is then read by systemd via [`LoadCredential=`] + and templated into {option}`${opts.settings}` for you. + + [`LoadCredential=`]: https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#Credentials + ''; + example = literalExpression '' + { + HBOX_AUTH_API_KEY_PEPPER = "/run/secrets/homebox-api-pepper"; + } + ''; + }; }; config = mkIf cfg.enable { @@ -92,7 +130,7 @@ in HBOX_DATABASE_DRIVER = "sqlite3"; HBOX_DATABASE_SQLITE_PATH = "/var/lib/homebox/data/homebox.db?_pragma=busy_timeout=999&_pragma=journal_mode=WAL&_fk=1"; HBOX_OPTIONS_ALLOW_REGISTRATION = "false"; - HBOX_OPTIONS_CHECK_GITHUB_RELEASE = "false"; + HBOX_OPTIONS_GITHUB_RELEASE_CHECK = "false"; HBOX_MODE = "production"; # Fix this startup issue: # failed to create modcache index dir: mkdir /var/empty/.cache: read-only file system @@ -121,58 +159,92 @@ in } ]; }; - systemd.services.homebox = { - requires = lib.optional cfg.database.createLocally "postgresql.target"; - after = lib.optional cfg.database.createLocally "postgresql.target"; - environment = lib.filterAttrs (_: v: v != null) cfg.settings; - preStart = '' - "${pkgs.coreutils}/bin/rm" -rf /var/lib/homebox/tmp - "${pkgs.coreutils}/bin/mkdir" -p /var/lib/homebox/tmp + systemd.services.homebox-setup = mkIf pepperDefault { + script = '' + if [ ! -r "$STATE_DIRECTORY"/api-pepper-secret ]; then + umask 0277 + openssl rand -base64 48 > "$STATE_DIRECTORY"/api-pepper-secret + fi ''; + path = [ + pkgs.openssl + ]; serviceConfig = { + Type = "oneshot"; User = cfg.user; Group = cfg.group; - ExecStart = lib.getExe cfg.package; - LimitNOFILE = "1048576"; - PrivateTmp = true; - PrivateDevices = true; - Restart = "always"; StateDirectory = "homebox"; - - # Hardening - CapabilityBoundingSet = ""; - LockPersonality = true; - MemoryDenyWriteExecute = true; - PrivateUsers = true; - ProtectClock = true; - ProtectControlGroups = true; - ProtectHome = true; - ProtectHostname = true; - ProtectKernelLogs = true; - ProtectKernelModules = true; - ProtectKernelTunables = true; - ProtectProc = "invisible"; - ProcSubset = "pid"; - ProtectSystem = "strict"; - RestrictAddressFamilies = [ - "AF_UNIX" - "AF_INET" - "AF_INET6" - "AF_NETLINK" - ]; - RestrictNamespaces = true; - RestrictRealtime = true; - SystemCallArchitectures = "native"; - SystemCallFilter = [ - "@system-service" - "@pkey" - ]; - RestrictSUIDSGID = true; - PrivateMounts = true; - UMask = "0077"; }; - wantedBy = [ "multi-user.target" ]; }; + systemd.services.homebox = + let + deps = + lib.optionals pepperDefault [ + "homebox-setup.service" + ] + ++ lib.optionals cfg.database.createLocally [ + "postgresql.target" + ]; + in + { + requires = deps; + after = deps; + environment = lib.filterAttrs (_: v: v != null) cfg.settings; + preStart = '' + "${pkgs.coreutils}/bin/rm" -rf /var/lib/homebox/tmp + "${pkgs.coreutils}/bin/mkdir" -p /var/lib/homebox/tmp + ''; + script = '' + ${lib.strings.concatLines ( + lib.mapAttrsToList (name: _: "export ${name}=$(<\"$CREDENTIALS_DIRECTORY\"/${name})") cfg.secrets + )} + + exec ${lib.getExe cfg.package} + ''; + serviceConfig = { + User = cfg.user; + Group = cfg.group; + LoadCredential = (lib.mapAttrsToList (name: path: "${name}:${path}") cfg.secrets); + LimitNOFILE = "1048576"; + PrivateTmp = true; + PrivateDevices = true; + Restart = "always"; + StateDirectory = "homebox"; + + # Hardening + CapabilityBoundingSet = ""; + LockPersonality = true; + MemoryDenyWriteExecute = true; + PrivateUsers = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + ProcSubset = "pid"; + ProtectSystem = "strict"; + RestrictAddressFamilies = [ + "AF_UNIX" + "AF_INET" + "AF_INET6" + "AF_NETLINK" + ]; + RestrictNamespaces = true; + RestrictRealtime = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "@system-service" + "@pkey" + ]; + RestrictSUIDSGID = true; + PrivateMounts = true; + UMask = "0077"; + }; + wantedBy = [ "multi-user.target" ]; + }; }; meta.maintainers = with lib.maintainers; [ patrickdag diff --git a/nixos/tests/homebox.nix b/nixos/tests/homebox.nix index 160d09f116bb..5842668479e0 100644 --- a/nixos/tests/homebox.nix +++ b/nixos/tests/homebox.nix @@ -4,8 +4,8 @@ let in { name = "homebox"; - meta = with pkgs.lib.maintainers; { - maintainers = [ patrickdag ]; + meta = { + inherit (pkgs.homebox.meta) maintainers; }; nodes = let @@ -21,6 +21,31 @@ in imports = [ self.simple ]; services.homebox.database.createLocally = true; }; + + explicitPepper = + { + config, + lib, + ... + }: + let + inherit (config.services.homebox) + user + group + ; + in + { + systemd.tmpfiles.rules = [ + "d /run/homebox 0700 ${user} ${group}" + "f /run/homebox/pepper 0400 ${user} ${group} - 0a7524fa7b4555ab793c177557b7b8db6619b47cc0574fb99716315e03b6ddf1d67961ee9bf36b19bef448ed3e530957" + ]; + imports = [ self.simple ]; + services.homebox = { + secrets = { + HBOX_AUTH_API_KEY_PEPPER = "/run/homebox/pepper"; + }; + }; + }; }; in self; @@ -37,5 +62,6 @@ in simple.send_monitor_command("quit") simple.wait_for_shutdown() test_homebox(postgres) + test_homebox(explicitPepper) ''; }