diff --git a/src/calng/base_calcat.py b/src/calng/base_calcat.py
index 8887e972c5d8c9371b3593fc01239d3eb8ad810d..8e1ec49d6120c335a4b8628eac569f9c7d5396d7 100644
--- a/src/calng/base_calcat.py
+++ b/src/calng/base_calcat.py
@@ -271,6 +271,17 @@ class BaseCalcatFriend:
         # Parameters which any detector would probably have (extend this in subclass)
         # TODO: probably switch to floating point for everything, including mem cells
         (
+            STRING_ELEMENT(schema)
+            .key("constantParameters.secretsFile")
+            .displayedName("CalCat secrets file")
+            .description(
+                "Path to JSON file specifying secret token and some parameters used to "
+                "access CalCat."
+            )
+            .assignmentOptional()
+            .defaultValue("~/.calcat-secrets.json")
+            .commit(),
+
             STRING_ELEMENT(schema)
             .key("constantParameters.deviceMappingSnapshotAt")
             .tags("managed")
@@ -375,23 +386,20 @@ class BaseCalcatFriend:
             .commit(),
         )
 
-    def __init__(
-        self,
-        device,
-        secrets_fn: pathlib.Path,
-    ):
+    def __init__(self, device):
         self.device = device
         self.cached_constants = {}
         self.cached_constants_lock = threading.RLock()
         # api lock used to force queries to be sequential (SSL issue on ONC)
         self.api_lock = threading.RLock()
-
-        if not secrets_fn.is_file():
-            self.device.log_status_warn(
-                f"Missing CalCat secrets file (expected {secrets_fn})"
+        secrets_fn = pathlib.Path(self._get_param("secretsFile")).expanduser()
+        try:
+            with secrets_fn.open("r") as fd:
+                calcat_secrets = json.load(fd)
+        except Exception as ex:
+            raise ValueError(
+                f"Failed to load CalCat secrets from {secrets_fn}: {ex}"
             )
-        with secrets_fn.open("r") as fd:
-            calcat_secrets = json.load(fd)
 
         self.caldb_store = pathlib.Path(calcat_secrets["caldb_store_path"])
         if not self.caldb_store.is_dir():
diff --git a/src/calng/base_correction.py b/src/calng/base_correction.py
index 414b334211ecda2b7dfaa08b83c8a1477a0d7f35..026130895b871fc93e5a3fa5f3432942799a3d9c 100644
--- a/src/calng/base_correction.py
+++ b/src/calng/base_correction.py
@@ -732,9 +732,7 @@ class BaseCorrection(PythonDevice):
             "deviceInternalsState", WarningLampType.CALCAT_CONNECTION
         ) as warn:
             try:
-                self.calcat_friend = self._calcat_friend_class(
-                    self, pathlib.Path.cwd() / "calibration-client-secrets.json"
-                )
+                self.calcat_friend = self._calcat_friend_class(self)
             except Exception as e:
                 warn(f"Failed to connect to CalCat: {e}")
                 # TODO: add raw fallback mode if CalCat fails (raw data still useful)