diff --git a/main.go b/main.go
index 34fa4a90432bf83e20b99a1194576f3f8d502246..ddb2b8c527ba0bc8c21fbdd099cbd4209fa059e0 100644
--- a/main.go
+++ b/main.go
@@ -7,6 +7,7 @@ import (
 	"io/ioutil"
 	"net/http"
 	"os"
+	"os/user"
 	"path/filepath"
 	"runtime"
 	"strconv"
@@ -24,6 +25,7 @@ var (
 	CertBase                  string
 	KeyBase                   string
 	GroupName                 string
+	GroupID                   int
 	RedisBaseURL              string
 	VaultBaseURL              string
 	certificateDestination    string
@@ -209,12 +211,11 @@ func GetVaultKey(vaulturl string, vaulttoken string) string {
 }
 
 // create directory structure and write certificate to file
-func WriteToFile(content string, destination string, groupname string, filemode os.FileMode, dirmode os.FileMode) {
+func WriteToFile(content string, destination string, filemode os.FileMode) {
 	baseDir := filepath.Dir(destination)
 	if _, err := os.Stat(baseDir); os.IsNotExist(err) {
 		os.MkdirAll(baseDir, 0755)
 	}
-	os.Chmod(baseDir, dirmode)
 
 	file, err := os.OpenFile(destination, os.O_WRONLY|os.O_CREATE, filemode)
 	if err != nil {
@@ -226,6 +227,27 @@ func WriteToFile(content string, destination string, groupname string, filemode
 	file.Close()
 }
 
+// move temp file to destination
+func moveFile(source string, destination string, groupid int, filemode os.FileMode, dirmode os.FileMode) {
+	baseDir := filepath.Dir(destination)
+	if _, err := os.Stat(baseDir); os.IsNotExist(err) {
+		os.MkdirAll(baseDir, 0755)
+	}
+	err := os.Rename(source, destination)
+	if err != nil {
+		fmt.Printf("[ERR] Fail to install %v: %v\n", destination, err)
+		appExit(255)
+	}
+	if runtime.GOOS != "windows" {
+		err = os.Chown(destination, 0, groupid)
+		if err != nil {
+			fmt.Printf("[ERR] Changing file owner to %v", groupid)
+			appExit(255)
+		}
+	}
+	fmt.Printf("[INFO] installed: %v\n", destination)
+}
+
 // ReadOSRelease from /etc/os-release
 func ReadOSRelease(configfile string) map[string]string {
 	ConfigParams := make(map[string]string)
@@ -283,7 +305,7 @@ Options:
   --redis-token=REDISTOKEN                      Redis access token
   --vault-token=VAULTTOKEN                      Vault access token
   --cert-name=CERTNAME                          Certificate name
-  --team-name=TEAMNAME                          Team name: swd, dream_team, it, ne, ti...
+  --team-name=TEAMNAME                          Team name: swd, it, ne, ti...
   --days=DAYS                                   Days before expiration [default: 30]
   --type=TYPE                                   Type, EV or OV [default: EV]
   --cert-destination=CERTDESTINATION            Cert Destination [default: %v/<cert-name>.crt]
@@ -304,11 +326,18 @@ Options:
 		tmpFullchainDestination = "C:\\tmp\\acme-downloader\\cert\\amce_fullchain.pem"
 		tmpCaDestination = "C:\\tmp\\acme-downloader\\cert\\amce_ca.pem"
 		tmpKeyDestination = "C:\\tmp\\acme-downloader\\key\\amce_key.pem"
+		GroupID = 0 // just a fake one
 	} else {
 		tmpCertificateDestination = "/tmp/acme-downloader/cert/amce_cert.pem"
 		tmpFullchainDestination = "/tmp/acme-downloader/cert/amce_fullchain.pem"
 		tmpCaDestination = "/tmp/acme-downloader/cert/amce_ca.pem"
 		tmpKeyDestination = "/tmp/acme-downloader/key/amce_key.pem"
+		group, groupErr := user.LookupGroup(GroupName)
+		if groupErr != nil {
+			fmt.Printf("[ERR] Fail looking up %v user user info", GroupName)
+			appExit(255)
+		}
+		GroupID, _ = strconv.Atoi(group.Gid)
 	}
 
 	VaultToken := arguments["--vault-token"].(string)
@@ -330,9 +359,7 @@ Options:
 	RedisCAURL := fmt.Sprintf("%v/%v:%v:redis_%v_chain_pem.txt", RedisBaseURL, TeamName, CertName, CertNameUndercored)
 	RedisFullChainURL := fmt.Sprintf("%v/%v:%v:redis_%v_fullchain_pem.txt", RedisBaseURL, TeamName, CertName, CertNameUndercored)
 
-	// fmt.Println(filepath.Join("a", "b", "c"))
 	if arguments["--cert-destination"] == fmt.Sprintf(filepath.Join(CertBase, "<cert-name>.crt")) {
-		// certificateDestination = fmt.Sprintf("%v/%v.crt", CertBase, CertName)
 		certificateDestination = fmt.Sprintf(filepath.Join(CertBase, fmt.Sprintf("%v.crt", CertName)))
 	} else {
 		certificateDestination = arguments["--cert-destination"].(string)
@@ -365,22 +392,18 @@ Options:
 	privKey := GetVaultKey(VaultURL, VaultToken)
 
 	// download and test certificates on a temporary location
-	WriteToFile(certificate, tmpCertificateDestination, GroupName, 0644, 0755)
-	WriteToFile(fullChain, tmpFullchainDestination, GroupName, 0644, 0755)
-	WriteToFile(ca, tmpCaDestination, GroupName, 0644, 0755)
-	WriteToFile(privKey, tmpKeyDestination, GroupName, 0640, 0750)
+	WriteToFile(certificate, tmpCertificateDestination, 0644)
+	WriteToFile(fullChain, tmpFullchainDestination, 0644)
+	WriteToFile(ca, tmpCaDestination, 0644)
+	WriteToFile(privKey, tmpKeyDestination, 0640)
 
 	checkCerificates(CertName, tmpCertificateDestination, tmpFullchainDestination, tmpCaDestination, tmpKeyDestination, Days, true)
 
-	WriteToFile(certificate, certificateDestination, GroupName, 0644, 0755)
-	WriteToFile(fullChain, fullchainDestination, GroupName, 0644, 0755)
-	WriteToFile(ca, caDestination, GroupName, 0644, 0755)
-	WriteToFile(privKey, keyDestination, GroupName, 0640, 0750)
-
-	fmt.Printf("[INFO] installed: %v\n", certificateDestination)
-	fmt.Printf("[INFO] installed: %v\n", caDestination)
-	fmt.Printf("[INFO] installed: %v\n", fullchainDestination)
-	fmt.Printf("[INFO] installed: %v\n", keyDestination)
+	// move certificates in place
+	moveFile(tmpCertificateDestination, certificateDestination, GroupID, 0644, 0755)
+	moveFile(tmpFullchainDestination, fullchainDestination, GroupID, 0644, 0755)
+	moveFile(tmpCaDestination, caDestination, GroupID, 0644, 0755)
+	moveFile(tmpKeyDestination, keyDestination, GroupID, 0640, 0750)
 
 	// Exit 1 means application needs to be reloaded
 	appExit(1)