{"title":"Secure Boot NixOS UKI Installer","url":"https://seanbehan.ca/posts/nixos-uki","description":"A flake that builds a signed unified kernel image, for rescuing a Steam Deck locked out by Secure Boot.","author":"Sean Behan","published":"2025-07-06T17:57:04.000Z","updated":null,"draft":false,"tags":["nixos","secure-boot","steam-deck"],"readingMinutes":2,"image":null,"sections":[{"id":"introduction","text":"Introduction","level":3},{"id":"configuration","text":"Configuration","level":3},{"id":"building","text":"Building","level":3},{"id":"building-the-image","text":"Building the Image","level":3},{"id":"signing-for-secure-boot","text":"Signing for Secure Boot","level":3},{"id":"booting-and-repair","text":"Booting and Repair","level":3}],"content_format":"text/markdown","content_url":"https://seanbehan.ca/posts/nixos-uki.md","content":"### Introduction\n\nIn this post I simply want to share a NixOS flake that might help you in the\n\ncase you enabled secure boot on a device such as the Steam Deck OLED, still\n\nhave keys because you backed them up, and want to get back in to either disable\n\nsecure boot with sbctl, or fix your unbootable NixOS system.\n\n### Configuration\n\nFirst, here is the flake that will load your configuration:\n\n```nix\n{\n  description = \"\";\n\n  inputs = {\n    nixpkgs.url = \"github:NixOS/nixpkgs/nixos-unstable\";\n  };\n\n  outputs = { self, nixpkgs }:\n    let\n      system = \"x86_64-linux\";\n      pkgs = import nixpkgs { inherit system; };\n\n      nixosImage = nixpkgs.lib.nixosSystem {\n        inherit system;\n        modules = [\n          ./image-config.nix\n        ];\n      };\n    in\n    {\n      packages.${system}.disk-image = nixosImage.config.system.build.\"image\";\n\n      defaultPackage.${system} = self.packages.${system}.disk-image;\n    };\n}\n```\n\nNow the config that you can use to build an image.\n\n```nix\n(\n  {\n    config,\n    lib,\n    pkgs,\n    modulesPath,\n    ...\n  }:\n  {\n\n    imports = [ \"${modulesPath}/image/repart.nix\" ];\n\n    boot.loader.grub.enable = false;\n    boot.initrd.availableKernelModules = [ \"usb_storage\" ];\n    boot.supportedFilesystems = [ \"btrfs\" ];\n    hardware.enableAllHardware = true;\n    environment.systemPackages = with pkgs; [\n      btrfs-progs\n      # sbctl # if you want it to be able to disable secure boot\n     ];\n\n    fileSystems.\"/\".device = \"/dev/disk/by-label/nixos\";\n\n    networking = {\n      networkmanager = {\n        enable = true;\n        wifi.backend = \"iwd\";\n      };\n      wireless.iwd = {\n        enable = true;\n      };\n    };\n\n    users = {\n      users = {\n        codebam = {\n          isNormalUser = true;\n          home = \"/home/codebam\";\n          description = \"Sean Behan\";\n          extraGroups = [\n            \"wheel\"\n            \"networkmanager\"\n            \"libvirtd\"\n            \"video\"\n            \"uinput\"\n            \"wireshark\"\n            \"pipewire\"\n          ];\n          hashedPassword = \"$6$TIP8YR83obmkq8T2$T3lYdPbPj9wysMznNlS5J0qHo2eyTr43aF/ZWSMWHdNRob4dkBB0s3KpBLUgYRTyPZxbb1ZgeqCrrx.DEEkQX1\";\n        };\n      };\n    };\n\n    image.repart = {\n      name = \"image\";\n      partitions = {\n        \"esp\" = {\n          contents = {\n            \"/EFI/BOOT/BOOT${lib.toUpper pkgs.stdenv.hostPlatform.efiArch}.EFI\".source =\n              \"${pkgs.systemd}/lib/systemd/boot/efi/systemd-boot${pkgs.stdenv.hostPlatform.efiArch}.efi\";\n\n            \"/EFI/Linux/${config.system.boot.loader.ukiFile}\".source =\n              \"${config.system.build.uki}/${config.system.boot.loader.ukiFile}\";\n          };\n          repartConfig = {\n            Type = \"esp\";\n            Format = \"vfat\";\n            SizeMinBytes = \"96M\";\n          };\n        };\n        \"root\" = {\n          storePaths = [ config.system.build.toplevel ];\n          repartConfig = {\n            Type = \"root\";\n            Format = \"ext4\";\n            Label = \"nixos\";\n            Minimize = \"guess\";\n          };\n        };\n      };\n    };\n  }\n)\n```\n\n### Building\n\n### Building the Image\n\n```sh\nnix build\n```\n\nMake sure you change the user and password, or you won't be able to login. Also\n\nnote that if you are using a Steam Deck OLED like me, WiFi won't work so you'll\n\nneed to use either ethernet or an external wireless adapter that has support in\n\nthe kernel.\n\n### Signing for Secure Boot\n\nSo ok you burn it to your USB drive:\n\n(replace X with your USB drive letter, and add sudo or elevate)\n\n```sh\ndd if=./result/image.raw of=/dev/sdX bs=4M status=progress\n```\n\nNow you have to sign it if you want secure boot to work. Assuming you already\n\nhave keys set up you just run:\n\n(again with sudo or elevate)\n\n```sh\nmount /dev/sdX1 /mnt\nsbctl sign /mnt/EFI/BOOT/BOOTX64.EFI\nsbctl sign /mnt/EFI/Linux/nixos.efi\nsync\numount /mnt\n```\n\n### Booting and Repair\n\nNow you're ready to boot it, so plug it into your USB hub or however you planned\n\non plugging it into the Steam Deck or your device.\n\nOnce you're in you will have access to a NixOS installer, and you should know\n\nwhat to do next to repair.\n"}