diff --git a/flake.nix b/flake.nix
index f8a1ac7..8e35887 100644
--- a/flake.nix
+++ b/flake.nix
@@ -15,13 +15,19 @@
     flake-utils.lib.eachDefaultSystem (
       system:
       let
-        version = "0.0.1";
-        secureBoot = "false";
-        microcode = "intel";
-        updateUrl = "http://10.0.2.2:8000/";
+        buildParams = {
+          revision = self.shortRev or self.dirtyShortRev or "dirty";
+          updateUrl = builtins.getEnv "PATOS_UPDATE_URL";
+          secureBoot = builtins.getEnv "PATOS_ENABLE_SECURE_BOOT";
+          version = "0.0.1";
+        };
 
-        overlay = import ./overlays { inherit version; };
-        pkgs = import nixpkgs { inherit system; overlays = [ overlay ]; };
+        overlay = import ./overlays (buildParams // { });
+
+        pkgs = import nixpkgs {
+          inherit system;
+          overlays = [ overlay ];
+        };
         pkgsCross = import nixpkgs {
           inherit system;
           overlays = [ overlay ];
@@ -34,18 +40,18 @@
         packages = {
           default = self.packages.${system}.image;
 
-          image = pkgs.callPackage ./pkgs/image { inherit version updateUrl microcode secureBoot; };
-          image-aarch64 = pkgsCross.callPackage ./pkgs/image { inherit version updateUrl secureBoot; };
+          image = pkgs.callPackage ./pkgs/image (buildParams // { microcode = "intel"; });
+          image-aarch64 = pkgsCross.callPackage ./pkgs/image (buildParams // { });
 
           qemu-uefi-tpm = pkgs.callPackage ./utils/qemu-uefi-tpm.nix { };
           qemu-aarch64-uefi-tpm = pkgs.callPackage ./utils/qemu-aarch64-uefi-tpm.nix { };
 
           # systemd sysext packages
-          debug-tools = pkgs.callPackage ./pkgs/sysext/debug-tools.nix { };
-          debug-tools-aarch64 = pkgsCross.callPackage ./pkgs/sysext/debug-tools.nix { };
+          debug-tools = pkgs.callPackage ./pkgs/sysext/debug-tools.nix (buildParams // { });
+          debug-tools-aarch64 = pkgsCross.callPackage ./pkgs/sysext/debug-tools.nix (buildParams // { });
 
-          firewall-tools = pkgs.callPackage ./pkgs/sysext/firewall-tools.nix { };
-          firewall-tools-aarch64 = pkgsCross.callPackage ./pkgs/sysext/firewall-tools.nix { };
+          firewall-tools = pkgs.callPackage ./pkgs/sysext/firewall-tools.nix (buildParams // { });
+          firewall-tools-aarch64 = pkgsCross.callPackage ./pkgs/sysext/firewall-tools.nix (buildParams // { });
 
           linux-firmware = pkgs.callPackage ./pkgs/linux-firmware { };
         };
diff --git a/lib/make-sysext.nix b/lib/make-sysext.nix
index 09f2172..ab8359b 100644
--- a/lib/make-sysext.nix
+++ b/lib/make-sysext.nix
@@ -17,9 +17,7 @@ let
     VERSION_ID = osId;
     IMAGE_ID = name;
     IMAGE_VERSION = version;
-    EXTENSION_RELOAD_MANAGER = "1";
-    SYSEXT_LEVEL="1.0";
-  };
+  } // lib.optionalAttrs (services != []) { EXTENSION_RELOAD_MANAGER = "1"; };
 
   metadataFile = lib.concatStringsSep "\n" (
     lib.mapAttrsToList (k: v: "${k}=${v}") (lib.filterAttrs (_: v: v != null) metadata)
@@ -122,6 +120,11 @@ runCommand name
     # TODO: pcks7 signature
     # openssl smime -sign -nocerts -noattr -binary -in ${name}.roothash \
     #   -inkey key.pem -signer cert.pem -outform der -out ${name}.roothash.p7s
+
+    pushd tree
+    find . -ls > $out/"$name"_contents.txt
+    popd
+
     rm -rf tree
     sha256sum * > SHA256SUMS
     # TODO: add gpg signature
diff --git a/overlays/default.nix b/overlays/default.nix
index 2c2cdce..22eeafa 100644
--- a/overlays/default.nix
+++ b/overlays/default.nix
@@ -1,5 +1,7 @@
 {
-  version
+  version,
+  revision,
+  ...
 }:
 
 final: prev: {
@@ -15,7 +17,7 @@ final: prev: {
     systemd = final.callPackage ../pkgs/systemd { };
     dbus-broker = final.callPackage ../pkgs/dbus-broker { };
 
-    rootfs = final.callPackage ../pkgs/rootfs/mkrootfs.nix { inherit version; };
-    initrd = final.callPackage ../pkgs/rootfs/mkinitrd.nix { inherit version; };
+    rootfs = final.callPackage ../pkgs/rootfs/mkrootfs.nix { inherit version revision; };
+    initrd = final.callPackage ../pkgs/rootfs/mkinitrd.nix { };
   });
 }
diff --git a/pkgs/image/default.nix b/pkgs/image/default.nix
index af47696..d79b9b9 100644
--- a/pkgs/image/default.nix
+++ b/pkgs/image/default.nix
@@ -3,6 +3,7 @@
   stdenv,
   pkgs,
   version,
+  revision,
   runCommand,
   updateUrl,
   microcode ? "",
@@ -12,13 +13,13 @@ let
   pname = "patos-image";
 in
 runCommand pname {
-  inherit version microcode updateUrl secureBoot;
+  versionString = "${version}+${revision}-${stdenv.system}";
 
   mcode = lib.optionalString (microcode == "amd") "--microcode ${pkgs.microcode-amd}/amd-ucode.img"
       + lib.optionalString (microcode == "intel") "--microcode ${pkgs.microcode-intel}/intel-ucode.img";
 
   # aarch64 doesn't support compressed kernel images
-  kernelImage = lib.optionalString (stdenv.hostPlatform.isAarch64 == true) "Image" 
+  kernelImage = lib.optionalString (stdenv.hostPlatform.isAarch64 == true) "Image"
       + lib.optionalString (stdenv.hostPlatform.isx86_64 == true) "bzImage";
 
   nativeBuildInputs = with pkgs; [
@@ -196,9 +197,9 @@ ${pkgs.patos.systemd}/usr/bin/systemd-repart \
   --split=true \
   --json=pretty \
   --root=$out \
-  patos_$version.raw > init-repart-output.json
+  patos_$versionString.raw > init-repart-output.json
 
-rm -f patos_$version.raw
+rm -f patos_$versionString.raw
 
 roothash=$(jq -r '.[0].roothash' init-repart-output.json)
 rootPart=$(jq -r '.[0].split_path' init-repart-output.json)
@@ -207,8 +208,8 @@ rootUuid=$(jq -r '.[0].uuid' init-repart-output.json)
 verityPart=$(jq -r '.[1].split_path' init-repart-output.json)
 verityUuid=$(jq -r '.[1].uuid' init-repart-output.json)
 
-ln -sf patos_$version.verity.raw patos_${version}_$verityUuid.verity
-ln -sf patos_$version.root.raw patos_${version}_$rootUuid.root
+ln -sf patos_$versionString.verity.raw patos_$versionString_$verityUuid.verity
+ln -sf patos_$versionString.root.raw patos_$versionString_$rootUuid.root
 
 ${pkgs.patos.systemd}/usr/bin/ukify build \
   --linux ${pkgs.patos.kernel}/$kernelImage \
@@ -216,7 +217,7 @@ ${pkgs.patos.systemd}/usr/bin/ukify build \
   $mcode \
   --os-release @rootfs/etc/os-release \
   --cmdline "$kernelCmdLine roothash=$roothash" \
-  -o patos_${version}.efi
+  -o patos_$versionString.efi
 
 # install ESP
 SYSTEMD_RELAX_ESP_CHECKS=1 ${pkgs.patos.systemd}/usr/bin/bootctl install --root ./rootfs --esp-path /boot
@@ -240,7 +241,7 @@ EOF
 echo "timeout 2" > rootfs/boot/loader/loader.conf
 
 # install UKI
-cp patos_${version}.efi rootfs/boot/EFI/Linux
+cp patos_$versionString.efi rootfs/boot/EFI/Linux
 
 # Final partitioning
 cat <<EOF > final.repart.d/10-esp.conf
@@ -255,7 +256,7 @@ EOF
 cat <<EOF > final.repart.d/20-root.conf
 [Partition]
 Type=root
-Label=root-${version}
+Label=root-$versionString
 CopyBlocks=$out/$rootPart
 UUID=$rootUuid
 SizeMinBytes=64M
@@ -266,7 +267,7 @@ EOF
 cat <<EOF > final.repart.d/22-root-verity.conf
 [Partition]
 Type=root-verity
-Label=verity-${version}
+Label=verity-$versionString
 CopyBlocks=$out/$verityPart
 UUID=$verityUuid
 ReadOnly=1
@@ -278,7 +279,7 @@ ${pkgs.patos.systemd}/usr/bin/systemd-repart \
   --empty=create \
   --size=auto \
   --definitions=./final.repart.d \
-  patos_${version}.img > final-repart-output.json
+  patos_$versionString.img > final-repart-output.json
 
 rm -rf rootfs init.repart.d final.repart.d *.json
 sha256sum *.root *.verity *.efi *.tar.xz > SHA256SUMS
diff --git a/pkgs/rootfs/mkrootfs.nix b/pkgs/rootfs/mkrootfs.nix
index 0bbc525..6b00c8c 100644
--- a/pkgs/rootfs/mkrootfs.nix
+++ b/pkgs/rootfs/mkrootfs.nix
@@ -1,6 +1,7 @@
 {
   pkgs,
   version,
+  revision,
   runCommand,
 }:
 let
@@ -53,11 +54,11 @@ ID=patos
 IMAGE_VERSION=${version}
 VERSION=${version}
 VERSION_ID=patos
-BUILD_ID=somehash
+BUILD_ID=${revision}
 EOF
 
 cat <<EOF > $out/etc/issue
-<<< Welcome to PatOS v${version} (Pre-Alpha) (\m) - \l >>>
+<<< Welcome to PatOS v${version}-${revision} (Pre-Alpha) (\m) - \l >>>
 
 EOF
 
diff --git a/pkgs/sysext/debug-tools.nix b/pkgs/sysext/debug-tools.nix
index 92c0b57..d801d1e 100644
--- a/pkgs/sysext/debug-tools.nix
+++ b/pkgs/sysext/debug-tools.nix
@@ -1,7 +1,7 @@
-{ pkgs }:
+{ pkgs, version, revision,... }:
 pkgs.callPackage ../../lib/make-sysext.nix {
-  name = "debug-tools";
-  version = "0.0.1";
+  name = "patos-debug-tools";
+  version = "${version}-${revision}";
   packages = [
     { drv = pkgs.curl; path = "bin/"; }
     { drv = pkgs.bash; path = "bin/"; }
@@ -27,6 +27,8 @@ pkgs.callPackage ../../lib/make-sysext.nix {
     { drv = pkgs.patos.openssl; path = "bin/openssl"; }
     # shared lib required for mkfs.erofs
     { drv = pkgs.lz4.lib; path = "lib/"; }
+    { drv = pkgs.xxHash; path = "lib/"; }
+    { drv = pkgs.libdeflate; path = "lib/"; }
     # shared lib required for cryptsetup
     { drv = pkgs.popt; path = "lib/"; }
     # shared lib required for strace
diff --git a/pkgs/sysext/firewall-tools.nix b/pkgs/sysext/firewall-tools.nix
index 875a179..1a88362 100644
--- a/pkgs/sysext/firewall-tools.nix
+++ b/pkgs/sysext/firewall-tools.nix
@@ -1,7 +1,7 @@
-{ pkgs }:
+{ pkgs, version, revision, ... }:
 pkgs.callPackage ../../lib/make-sysext.nix {
-  name = "firewall-tools";
-  version = "0.0.1";
+  name = "patos-firewall-tools";
+  version = "${version}-${revision}";
   packages = [
     # network/firewalling
     { drv = pkgs.iproute2; path = "bin/"; }