diff --git a/lib/modules/rclone.nix b/lib/modules/rclone.nix
index cdb7d59..2bb38a8 100644
--- a/lib/modules/rclone.nix
+++ b/lib/modules/rclone.nix
@@ -8,22 +8,26 @@ let
   nextcloudVendor = "nextcloud";
   mkIfNotNull = value: name: lib.mkIf (value != null) { ${name} = value; };
 
+  mkFileOption = { description }: lib.mkOption {
+    type = lib.types.nullOr (lib.types.either lib.types.path lib.types.str);
+    description = "The path to a file containing ${description}";
+    default = null;
+  };
+
   mkUsernameOption = { service }: lib.mkOption {
     type = lib.types.nullOr lib.types.str;
     description = "The user name for logging in to ${service}.";
     default = null;
   };
 
-  mkPasswordOption = { service }: lib.mkOption {
+  mkPasswordOption = { service, itemKind ? "password" }: lib.mkOption {
     type = lib.types.nullOr lib.types.str;
-    description = "The password obscured using the `rclone obscure` command for logging in to ${service}.";
+    description = "The ${itemKind} obscured using the `rclone obscure` command for logging in to ${service}.";
     default = null;
   };
 
-  mkPasswordFileOption = { service }: lib.mkOption {
-    type = lib.types.nullOr (lib.types.either lib.types.path lib.types.str);
-    description = "The path to a file containing the password obscured using the `rclone obscure` command for logging in to ${service}.";
-    default = null;
+  mkPasswordFileOption = { service, itemKind ? "password" }: mkFileOption {
+    description = "the ${itemKind} obscured using the `rclone obscure` command for logging in to ${service}.";
   };
 
   mkServerUsernameOption = { service }: mkUsernameOption { service = "the ${service} server."; };
@@ -179,6 +183,90 @@ let
       };
     });
 
+  mkProtonProvider = { displayName }: (
+    { config, ... }: {
+      imports = [
+        mkProvider
+      ];
+
+      options = {
+        username = mkUsernameOption { service = displayName; };
+        obscuredPassword = mkPasswordOption { service = displayName; };
+        obscuredPasswordFile = mkPasswordFileOption { service = displayName; };
+
+        webAuthnToken = lib.mkOption {
+          type = lib.types.strMatching "[0-9]{6}";
+          description = "The 2 Factor Authentication code for logging in to ${displayName}.";
+        };
+
+        webAuthnTokenFile = mkFileOption {
+          description = "the 2 Factor Authentication code for logging in to ${displayName}.";
+        };
+
+        clientID = lib.mkOption {
+          type = lib.types.nullOr lib.types.str;
+          description = "The client key.";
+          default = null;
+        };
+
+        accessToken = lib.mkOption {
+          type = lib.types.nullOr lib.types.str;
+          description = "The access token.";
+          default = null;
+        };
+
+        refreshToken = lib.mkOption {
+          type = lib.types.nullOr lib.types.str;
+          description = "The refresh token.";
+          default = null;
+        };
+
+        saltedKeyPass = lib.mkOption {
+          type = lib.types.nullOr lib.types.str;
+          description = "The salted key pass.";
+          default = null;
+        };
+
+        enableCaching = lib.mkOption {
+          type = lib.types.nullOr lib.types.bool;
+          description = "Whether to enable ${displayName}'s integrated caching.";
+          default = null;
+        };
+
+        mailboxPassword = mkPasswordOption { service = displayName; itemKind = "mailbox password"; };
+        mailboxPasswordFile = mkPasswordFileOption { service = displayName; itemKind = "mailbox password"; };
+        clientIDFile = mkFileOption { description = "the client key."; };
+        accessTokenFile = mkFileOption { description = "the access token."; };
+        refreshTokenFile = mkFileOption { description = "the refresh token."; };
+        saltedKeyPassFile = mkFileOption { description = "the salted key pass."; };
+      };
+
+      config = {
+        config = lib.mkMerge [
+          { type = "protondrive"; }
+          (mkIfNotNull config.username "username")
+          (mkIfNotNull config.obscuredPassword "password")
+          (mkIfNotNull config.webAuthnToken "2fa")
+          (mkIfNotNull config.mailboxPassword "mailbox_password")
+          (mkIfNotNull config.clientID "client_uid")
+          (mkIfNotNull config.accessToken "client_access_token")
+          (mkIfNotNull config.refreshToken "client_refresh_token")
+          (mkIfNotNull config.saltedKeyPass "client_salted_key_pass")
+          (mkIfNotNull config.enableCaching "enable_caching")
+        ];
+
+        secrets = lib.mkMerge [
+          (mkIfNotNull config.obscuredPasswordFile "RCLONE_PROTONDRIVE_PASSWORD")
+          (mkIfNotNull config.webAuthnTokenFile "RCLONE_PROTONDRIVE_2FA")
+          (mkIfNotNull config.mailboxPasswordFile "RCLONE_PROTONDRIVE_MAILBOX_PASSWORD")
+          (mkIfNotNull config.clientIDFile "RCLONE_PROTONDRIVE_CLIENT_UID")
+          (mkIfNotNull config.accessTokenFile "RCLONE_PROTONDRIVE_CLIENT_ACCESS_TOKEN")
+          (mkIfNotNull config.refreshTokenFile "RCLONE_PROTONDRIVE_CLIENT_REFRESH_TOKEN")
+          (mkIfNotNull config.saltedKeyPassFile "RCLONE_PROTONDRIVE_CLIENT_SALTED_KEY_PASS")
+        ];
+      };
+    });
+
   syncProviders = {
     ${manualVendor} = {
       displayName = "Custom";
@@ -198,6 +286,11 @@ let
       displayName = owncloudName;
       module = mkOwncloudProvider { };
     };
+
+    proton = rec {
+      displayName = "Proton";
+      module = mkProtonProvider { inherit displayName; };
+    };
   };
 in {
   options = {
@@ -277,7 +370,7 @@ in {
                         (lib.generators.toINI { } { name = sync.config; });
                       script = pkgs.writeShellScriptBin serviceName ''
                         ${sync.secretsScript}
-                        bash -c echo hello world
+                        cat ${configFile}
                       '';
                     in
                       (lib.getExe script);