diff --git a/.gitignore b/.gitignore
index c1926ca2..f0ebb623 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
 
 bufferflow_tinyg_old.md
 
+/arduino-create-agent*
 /arduino-cloud-agent*
 !/arduino-cloud-agent*/
 rsrc.syso
@@ -19,3 +20,7 @@ logs/
 
 # Python
 __pycache__
+
+# Debugging
+__debug_bin*.exe*
+vendor/
\ No newline at end of file
diff --git a/updater/elevate_unix.go b/updater/elevate_unix.go
new file mode 100644
index 00000000..17e81950
--- /dev/null
+++ b/updater/elevate_unix.go
@@ -0,0 +1,17 @@
+//go:build !windows
+
+package updater
+
+import (
+	"os"
+	"os/exec"
+)
+
+func elevate() error {
+	args := append([]string{os.Args[0]}, os.Args[1:]...)
+	cmd := exec.Command("sudo", args...)
+	cmd.Stdin = os.Stdin
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+	return cmd.Run()
+}
diff --git a/updater/elevate_windows.go b/updater/elevate_windows.go
new file mode 100644
index 00000000..ab3c3493
--- /dev/null
+++ b/updater/elevate_windows.go
@@ -0,0 +1,32 @@
+package updater
+
+import (
+	"os"
+	"strings"
+	"syscall"
+
+	"golang.org/x/sys/windows"
+)
+
+func elevate() error {
+	verb := "runas"
+	exe, _ := os.Executable()
+	cwd, _ := os.Getwd()
+	args := strings.Join(os.Args[1:], " ")
+
+	verbPtr, err := syscall.UTF16PtrFromString(verb)
+	if err != nil {
+		return err
+	}
+	exePtr, err := syscall.UTF16PtrFromString(exe)
+	if err != nil {
+		return err
+	}
+	cwdPtr, err := syscall.UTF16PtrFromString(cwd)
+	if err != nil {
+		return err
+	}
+	argPtr, _ := syscall.UTF16PtrFromString(args)
+	var showCmd int32 = 1
+	return windows.ShellExecute(0, verbPtr, exePtr, argPtr, cwdPtr, showCmd)
+}
diff --git a/updater/updater.go b/updater/updater.go
index db4e5454..891ba438 100644
--- a/updater/updater.go
+++ b/updater/updater.go
@@ -83,9 +83,11 @@ func fetch(url string) (io.ReadCloser, error) {
 
 // addTempSuffixToPath adds the "-temp" suffix to the path to an executable file (a ".exe" extension is replaced with "-temp.exe")
 func addTempSuffixToPath(path string) string {
-	if filepath.Ext(path) == "exe" {
+	if filepath.Ext(path) == ".exe" {
+		// Windows
 		path = strings.Replace(path, ".exe", "-temp.exe", -1)
 	} else {
+		// Unix
 		path = path + "-temp"
 	}
 
@@ -110,3 +112,15 @@ func copyExe(from, to string) error {
 	}
 	return nil
 }
+
+// requestElevation requests this program to rerun as administrator, for when we don't have permission over the update files
+func requestElevation() {
+	log.Println("Permission denied. Requesting elevated privileges...")
+
+	var err error = elevate()
+
+	if err != nil {
+		log.Println("Failed to request elevation:", err)
+		return
+	}
+}
diff --git a/updater/updater_default.go b/updater/updater_default.go
index 2cf01b8a..c603ea1d 100644
--- a/updater/updater_default.go
+++ b/updater/updater_default.go
@@ -66,6 +66,9 @@ func start(src string) string {
 	if strings.Contains(src, "-temp") {
 		newPath := removeTempSuffixFromPath(src)
 		if err := copyExe(src, newPath); err != nil {
+			if os.IsPermission(err) {
+				requestElevation()
+			}
 			log.Println("Copy error: ", err)
 			panic(err)
 		}
@@ -74,6 +77,9 @@ func start(src string) string {
 
 	// Otherwise copy to a path with -temp suffix
 	if err := copyExe(src, addTempSuffixToPath(src)); err != nil {
+		if os.IsPermission(err) {
+			requestElevation()
+		}
 		panic(err)
 	}
 	return ""