diff --git a/client/src/data_store.rs b/client/src/data_store.rs
index b405a91..ea46a08 100644
--- a/client/src/data_store.rs
+++ b/client/src/data_store.rs
@@ -1,4 +1,5 @@
 use crate::Error;
+use colored::*;
 use serde::{Deserialize, Serialize};
 use shared::{ensure_dirs_exist, Cidr, IoErrorContext, Peer, CLIENT_DATA_PATH};
 use std::{
@@ -23,12 +24,18 @@ pub enum Contents {
 
 impl DataStore {
     pub(self) fn open_with_path<P: AsRef<Path>>(path: P, create: bool) -> Result<Self, Error> {
+        let path = path.as_ref();
         let mut file = OpenOptions::new()
             .read(true)
             .write(true)
             .create(create)
-            .open(&path)
-            .with_path(&path)?;
+            .open(path)
+            .with_path(path)?;
+
+        if shared::chmod(&file, 0o600)? {
+            println!("{} updated permissions for {} to 0600.", "[!]".yellow(), path.display());
+        }
+
         let mut json = String::new();
         file.read_to_string(&mut json).with_path(path)?;
         let contents = serde_json::from_str(&json).unwrap_or_else(|_| Contents::V1 {
diff --git a/server/src/main.rs b/server/src/main.rs
index 899dcba..ddddd3a 100644
--- a/server/src/main.rs
+++ b/server/src/main.rs
@@ -114,6 +114,7 @@ pub struct ConfigFile {
 impl ConfigFile {
     pub fn write_to_path<P: AsRef<Path>>(&self, path: P) -> Result<(), Error> {
         let mut invitation_file = File::create(&path).with_path(&path)?;
+        shared::chmod(&invitation_file, 0o600)?;
         invitation_file
             .write_all(toml::to_string(self).unwrap().as_bytes())
             .with_path(path)?;
@@ -121,6 +122,11 @@ impl ConfigFile {
     }
 
     pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self, Error> {
+        let path = path.as_ref();
+        let file = File::open(path).with_path(path)?;
+        if shared::chmod(&file, 0o600)? {
+            println!("{} updated permissions for {} to 0600.", "[!]".yellow(), path.display());
+        }
         Ok(toml::from_slice(&std::fs::read(&path).with_path(path)?)?)
     }
 }
diff --git a/shared/src/interface_config.rs b/shared/src/interface_config.rs
index f7b2426..d0aaa2a 100644
--- a/shared/src/interface_config.rs
+++ b/shared/src/interface_config.rs
@@ -1,4 +1,5 @@
 use crate::{ensure_dirs_exist, Error, IoErrorContext, CLIENT_CONFIG_PATH};
+use colored::*;
 use indoc::writedoc;
 use ipnetwork::IpNetwork;
 use serde::{Deserialize, Serialize};
@@ -58,12 +59,16 @@ impl InterfaceConfig {
         comments: bool,
         mode: Option<u32>,
     ) -> Result<(), Error> {
+        let path = path.as_ref();
         let mut target_file = OpenOptions::new()
             .create_new(true)
             .write(true)
-            .open(&path)
-            .with_path(&path)?;
+            .open(path)
+            .with_path(path)?;
         if let Some(val) = mode {
+            if crate::chmod(&target_file, 0o600)? {
+                println!("{} updated permissions for {} to 0600.", "[!]".yellow(), path.display());
+            }
             let metadata = target_file.metadata()?;
             let mut permissions = metadata.permissions();
             permissions.set_mode(val);
@@ -106,7 +111,12 @@ impl InterfaceConfig {
     }
 
     pub fn from_interface(interface: &InterfaceName) -> Result<Self, Error> {
-        Self::from_file(Self::build_config_file_path(interface)?)
+        let path = Self::build_config_file_path(interface)?;
+        let file = File::open(&path).with_path(&path)?;
+        if crate::chmod(&file, 0o600)? {
+            println!("{} updated permissions for {} to 0600.", "[!]".yellow(), path.display());
+        }
+        Self::from_file(path)
     }
 
     fn build_config_file_path(interface: &InterfaceName) -> Result<PathBuf, Error> {
diff --git a/shared/src/lib.rs b/shared/src/lib.rs
index e7a5039..9289dab 100644
--- a/shared/src/lib.rs
+++ b/shared/src/lib.rs
@@ -1,3 +1,4 @@
+use colored::*;
 use ipnetwork::IpNetwork;
 use lazy_static::lazy_static;
 use prompts::hostname_validator;
@@ -362,21 +363,37 @@ pub static WG_DIR: &str = "/etc/wireguard";
 pub fn ensure_dirs_exist(dirs: &[&Path]) -> Result<(), Error> {
     for dir in dirs {
         match fs::create_dir(dir) {
-            Ok(()) => {
-                let target_file = File::open(dir).with_path(dir)?;
-                let metadata = target_file.metadata().with_path(dir)?;
-                let mut permissions = metadata.permissions();
-                permissions.set_mode(0o700);
-            },
             Err(e) if e.kind() != io::ErrorKind::AlreadyExists => {
                 return Err(e.into());
             },
-            _ => {},
+            _ => {
+                let target_file = File::open(dir).with_path(dir)?;
+                if chmod(&target_file, 0o700)? {
+                    println!("{} updated permissions for {} to 0700.", "[!]".yellow(), dir.display());
+                }
+            },
         }
     }
     Ok(())
 }
 
+/// Updates the permissions of a file or directory. Returns `Ok(true)` if
+/// permissions had to be changed, `Ok(false)` if permissions were already
+/// correct.
+pub fn chmod(file: &File, mode: u32) -> Result<bool, Error> {
+        let metadata = file.metadata()?;
+        let mut permissions = metadata.permissions();
+        let updated = if permissions.mode() != mode {
+            permissions.set_mode(mode);
+            file.set_permissions(permissions)?;
+            true
+        } else {
+            false
+        };
+
+        Ok(updated)
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;