{ inputs, pkgs, ... }: let openclawPatched = inputs.openclaw.packages.${pkgs.system}.openclaw-gateway.overrideAttrs (old: { installPhase = old.installPhase + "\n" + '' # Point Brave web-search endpoint to local shim. # NOTE: upstream installPhase script does not run postInstall hooks, # so patch directly at the end of installPhase. if [ -d "$out/lib/openclaw/dist" ]; then # Web-search tool hardcodes Brave endpoint in bundled JS. # No runtime config option exists for Brave base URL in this OpenClaw version. grep -RIl "https://api.search.brave.com" "$out/lib/openclaw/dist" | while read -r f; do substituteInPlace "$f" \ --replace "https://api.search.brave.com/res/v1/web/search" "http://127.0.0.1:8000/res/v1/web/search" \ --replace "https://api.search.brave.com/res/v1/" "http://127.0.0.1:8000/res/v1/" \ --replace "https://api.search.brave.com/" "http://127.0.0.1:8000/" \ --replace "https://api.search.brave.com" "http://127.0.0.1:8000" done fi ''; }); in { imports = [ inputs.openclaw.nixosModules.openclaw-gateway ]; users.users.openclaw = { isSystemUser = false; isNormalUser = true; home = "/home/openclaw"; createHome = true; group = "openclaw"; extraGroups = [ "docker" ]; shell = pkgs.bash; description = "OpenClaw agent sandboxed user"; packages = [ openclawPatched (pkgs.callPackage ./gogcli.nix { }) (pkgs.callPackage ./brave-shim.nix { }) pkgs.uv pkgs.python3 ]; }; users.groups.openclaw = { }; # Keep the openclaw user's systemd --user instance running so the gateway stays up. # Using activation script because services.logind.lingerUsers isn't available in this release. system.activationScripts.enableOpenclawLinger.text = '' ${pkgs.systemd}/bin/loginctl enable-linger openclaw || true ''; # Run OpenClaw gateway as a NixOS system service under the dedicated user. services.openclaw-gateway = { enable = true; package = openclawPatched; createUser = false; user = "openclaw"; group = "openclaw"; stateDir = "/home/openclaw/.local/share/openclaw"; }; }