diff --git a/.env b/.env
index 9eb149b..6ee8f2b 100644
--- a/.env
+++ b/.env
@@ -10,3 +10,5 @@ APPLE_ID_PASSWORD="op://Apple/3apcadvvcojjbpxnd7m5fgh5wm/password"
 
 APP_PROF="op://Apple/Provisioning Profiles/profiles/application_base64"
 EXT_PROF="op://Apple/Provisioning Profiles/profiles/extension_base64"
+
+SPARKLE_PRIVATE_KEY="op://Apple/Private key for signing Sparkle updates/notesPlain"
\ No newline at end of file
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index c512991..adbc130 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -56,6 +56,7 @@ jobs:
           APPLE_ID_PASSWORD: ${{ secrets.APPLE_NOTARYTOOL_PASSWORD }}
           APP_PROF: ${{ secrets.CODER_DESKTOP_APP_PROVISIONPROFILE_B64 }}
           EXT_PROF: ${{ secrets.CODER_DESKTOP_EXTENSION_PROVISIONPROFILE_B64 }}
+          SPARKLE_PRIVATE_KEY: ${{ secrets.SPARKLE_PRIVATE_KEY }}
         run: make release
 
       # Upload as artifact in dry-run mode
diff --git a/Coder-Desktop/Coder-Desktop/Info.plist b/Coder-Desktop/Coder-Desktop/Info.plist
index 4712604..c1bf929 100644
--- a/Coder-Desktop/Coder-Desktop/Info.plist
+++ b/Coder-Desktop/Coder-Desktop/Info.plist
@@ -31,5 +31,7 @@
 		<key>NEMachServiceName</key>
 		<string>$(TeamIdentifierPrefix)com.coder.Coder-Desktop.VPN</string>
 	</dict>
+	<key>SUPublicEDKey</key>
+    <string>Ae2oQLTcx89/a73XrpOt+IVvqdo+fMTjo3UKEm77VdA=</string>
 </dict>
 </plist>
diff --git a/Coder-Desktop/project.yml b/Coder-Desktop/project.yml
index 9455a44..224add8 100644
--- a/Coder-Desktop/project.yml
+++ b/Coder-Desktop/project.yml
@@ -129,6 +129,9 @@ packages:
   URLRouting:
     url: https://github.com/pointfreeco/swift-url-routing
     revision: 09b155d
+  Sparkle:
+    url: https://github.com/sparkle-project/Sparkle
+    exactVersion: 2.7.0
 
 
 targets:
@@ -202,6 +205,7 @@ targets:
       - package: LaunchAtLogin
       - package: SDWebImageSwiftUI
       - package: SDWebImageSVGCoder
+      - package: Sparkle
     scheme:
       testPlans:
         - path: Coder-Desktop.xctestplan
diff --git a/Makefile b/Makefile
index a21b756..e50b060 100644
--- a/Makefile
+++ b/Makefile
@@ -106,7 +106,8 @@ release: $(KEYCHAIN_FILE) ## Create a release build of Coder Desktop
 		--app-prof-path "$$APP_PROF_PATH" \
 		--ext-prof-path "$$EXT_PROF_PATH" \
 		--version $(MARKETING_VERSION) \
-		--keychain "$(APP_SIGNING_KEYCHAIN)"; \
+		--keychain "$(APP_SIGNING_KEYCHAIN)" \
+		--sparkle-private-key "$$SPARKLE_PRIVATE_KEY"; \
 	rm "$$APP_PROF_PATH" "$$EXT_PROF_PATH"
 
 .PHONY: fmt
diff --git a/scripts/build.sh b/scripts/build.sh
index de6f34a..f6e537a 100755
--- a/scripts/build.sh
+++ b/scripts/build.sh
@@ -16,15 +16,17 @@ APP_PROF_PATH=${APP_PROF_PATH:-""}
 EXT_PROF_PATH=${EXT_PROF_PATH:-""}
 KEYCHAIN=${KEYCHAIN:-""}
 VERSION=${VERSION:-""}
+SPARKLE_PRIVATE_KEY=${SPARKLE_PRIVATE_KEY:-""}
 
 # Function to display usage
 usage() {
   echo "Usage: $0 [--app-prof-path <path>] [--ext-prof-path <path>] [--keychain <path>]"
-  echo "  --app-prof-path <path>     Set the APP_PROF_PATH variable"
-  echo "  --ext-prof-path <path>     Set the EXT_PROF_PATH variable"
-  echo "  --keychain      <path>     Set the KEYCHAIN variable"
-  echo "  --version       <version>  Set the VERSION variable to fetch and generate the cask file for"
-  echo "  -h, --help                 Display this help message"
+  echo "  --app-prof-path       <path>     Set the APP_PROF_PATH variable"
+  echo "  --ext-prof-path       <path>     Set the EXT_PROF_PATH variable"
+  echo "  --keychain            <path>     Set the KEYCHAIN variable"
+  echo "  --sparkle-private-key <path>     Set the SPARKLE_PRIVATE_KEY variable"
+  echo "  --version             <version>  Set the VERSION variable to fetch and generate the cask file for"
+  echo "  -h, --help                       Display this help message"
 }
 
 # Parse command line arguments
@@ -42,6 +44,10 @@ while [[ "$#" -gt 0 ]]; do
     KEYCHAIN="$2"
     shift 2
     ;;
+  --sparkle-private-key)
+    SPARKLE_PRIVATE_KEY="$2"
+    shift 2
+    ;;
   --version)
     VERSION="$2"
     shift 2
@@ -59,7 +65,7 @@ while [[ "$#" -gt 0 ]]; do
 done
 
 # Check if required variables are set
-if [[ -z "$APP_PROF_PATH" || -z "$EXT_PROF_PATH" || -z "$KEYCHAIN" ]]; then
+if [[ -z "$APP_PROF_PATH" || -z "$EXT_PROF_PATH" || -z "$KEYCHAIN" || -z "$SPARKLE_PRIVATE_KEY" ]]; then
   echo "Missing required values"
   echo "APP_PROF_PATH: $APP_PROF_PATH"
   echo "EXT_PROF_PATH: $EXT_PROF_PATH"
@@ -195,6 +201,9 @@ xcrun notarytool submit "$PKG_PATH" \
 xcrun stapler staple "$PKG_PATH"
 xcrun stapler staple "$BUILT_APP_PATH"
 
+signature=$(echo "$SPARKLE_PRIVATE_KEY" | ~/Library/Developer/Xcode/DerivedData/Coder-Desktop-*/SourcePackages/artifacts/sparkle/Sparkle/bin/sign_update "$PKG_PATH" --ed-key-file -)
+echo "$signature" >"$PKG_PATH.sig"
+
 # Add dsym to build artifacts
 (cd "$ARCHIVE_PATH/dSYMs" && zip -9 -r --symlinks "$DSYM_ZIPPED_PATH" ./*)