diff --git a/Makefile b/Makefile
index 092749561a1386272b842f11c59f5de044a0f0e0..c0bb4993489d8bdf18b7e69fe7d997454560bc3a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 all: coverage lint
 
 install:
-	apt-get -y install awscli python3-boto3 python3-tabulate restic yamllint
+	apt-get -y install awscli python3-boto3 python3-pydantic python3-tabulate restic yamllint
 
 install-dev:
 	apt-get -y install python3-venv snapd
diff --git a/examples/rwm-admin.conf b/examples/rwm-admin.conf
index aa438cf0653ad4286f6562a9287ef43871d65ec0..9d538726adbf57afc8f09a4e10597b76676a9ad0 100644
--- a/examples/rwm-admin.conf
+++ b/examples/rwm-admin.conf
@@ -1,5 +1,5 @@
 # rwm aws, storage
 
-rwm_s3_endpoint_url: ""
-rwm_s3_access_key: ""
-rwm_s3_secret_key: ""
+s3_endpoint_url: ""
+s3_access_key: ""
+s3_secret_key: ""
diff --git a/examples/rwm-backups.conf b/examples/rwm-backups.conf
index b2477759e6cd0b9a20700d015a2f2954faf3e270..7356ae57cb1b9e1071b9a6b5a2ab04a17201d05a 100644
--- a/examples/rwm-backups.conf
+++ b/examples/rwm-backups.conf
@@ -1,13 +1,13 @@
 # rwm aws, restic, backup, backup_all
 
-rwm_s3_endpoint_url: ""
-rwm_s3_access_key: ""
-rwm_s3_secret_key: ""
+s3_endpoint_url: ""
+s3_access_key: ""
+s3_secret_key: ""
 
-rwm_restic_bucket: "rwmbackups"
-rwm_restic_password: ""
+restic_bucket: "rwmbackups"
+restic_password: ""
 
-rwm_backups:
+backups:
   simplefs:
     filesdirs:
       - "/"
@@ -38,7 +38,7 @@ rwm_backups:
     postrun:
       - unmount
 
-rwm_retention:
+retention:
   keep-daily: "60"
   keep-within: "60d"
   keep-tag: "donotforget"
diff --git a/examples/rwm-linux.conf b/examples/rwm-linux.conf
index 89dec7c77bb9073761fcb1e341b92234be9be49f..35d4874dab77eccb4212b7bab69bac2bd6f7f0a5 100644
--- a/examples/rwm-linux.conf
+++ b/examples/rwm-linux.conf
@@ -1,13 +1,13 @@
 # rwm aws, restic, backup, backup_all
 
-rwm_s3_endpoint_url: ""
-rwm_s3_access_key: ""
-rwm_s3_secret_key: ""
+s3_endpoint_url: ""
+s3_access_key: ""
+s3_secret_key: ""
 
-rwm_restic_bucket: "rwmbackups"
-rwm_restic_password: ""
+restic_bucket: "rwmbackups"
+restic_password: ""
 
-rwm_backups:
+backups:
   linux1:
     filesdirs:
       - "/"
@@ -30,6 +30,6 @@ rwm_backups:
     postrun:
       - "mkdir -p /var/health && touch /var/health/backup"
 
-rwm_retention:
+retention:
   keep-daily: "14"
   keep-weekly: "20"
diff --git a/examples/rwm-restic.conf b/examples/rwm-restic.conf
index beeee3e905dcff057f36ee94930924f2a30317c3..fab285160046e109f1ced991ca9745499cbb8d71 100644
--- a/examples/rwm-restic.conf
+++ b/examples/rwm-restic.conf
@@ -1,8 +1,8 @@
 # rwm aws, restic
 
-rwm_s3_endpoint_url: ""
-rwm_s3_access_key: ""
-rwm_s3_secret_key: ""
+s3_endpoint_url: ""
+s3_access_key: ""
+s3_secret_key: ""
 
-rwm_restic_bucket: "rwmrestic"
-rwm_restic_password: ""
+restic_bucket: "rwmrestic"
+restic_password: ""
diff --git a/requirements.txt b/requirements.txt
index eb406a46e589fc803692de4966e98497fe9d6b7f..c187ece0cc800d2bbcb1220b3fbf9293d7dfebfd 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,5 @@
 # runtime
+pydantic
 tabulate
 
 # dev
diff --git a/rwm.py b/rwm.py
index 3bb14c418676987350dc7ce36cd4630e45b6d1cb..5cfc6cdfb556a88d28063562a653d4088a4c66fe 100755
--- a/rwm.py
+++ b/rwm.py
@@ -1,7 +1,6 @@
 #!/usr/bin/env python3
 """rwm, restic/s3 worm manager"""
 
-import dataclasses
 import gzip
 import json
 import logging
@@ -10,13 +9,16 @@ import shlex
 import subprocess
 import sys
 from argparse import ArgumentParser
+from dataclasses import dataclass
 from datetime import datetime
 from io import BytesIO
 from pathlib import Path
+from typing import List, Dict, Optional
 
 import boto3
 import yaml
 from botocore.exceptions import BotoCoreError, ClientError
+from pydantic import BaseModel, ConfigDict
 from tabulate import tabulate
 
 
@@ -34,14 +36,6 @@ def is_sublist(needle, haystack):
     return any(haystack[i:i+len(needle)] == needle for i in range(len(haystack)))
 
 
-def get_config(path):
-    """load config"""
-
-    if Path(path).exists():
-        return yaml.safe_load(Path(path).read_text(encoding='utf-8')) or {}
-    return {}
-
-
 def run_command(*args, **kwargs):
     """output capturing command executor"""
 
@@ -74,26 +68,30 @@ def size_fmt(num):
     return f'{num:0.1f} YiB'
 
 
-@dataclasses.dataclass
-class BackupResult:
-    """backup results data container"""
+class BackupConfig(BaseModel):
+    """backup config model"""
 
-    name: str
-    returncode: int
-    time_start: datetime
-    time_end: datetime
+    model_config = ConfigDict(extra='forbid')
 
-    def to_dict(self):
-        """dict serializer"""
+    filesdirs: List[str]
+    excludes: Optional[List[str]] = []
+    extras: Optional[List[str]] = []
+    prerun: Optional[List[str]] = []
+    postrun: Optional[List[str]] = []
 
-        return {
-            "ident": "RESULT",
-            "name": self.name,
-            "status": "OK" if self.returncode == 0 else "ERROR",
-            "returncode": self.returncode,
-            "backup_start": self.time_start.isoformat(),
-            "backup_time": str(self.time_end-self.time_start),
-        }
+
+class RWMConfig(BaseModel):
+    """main config model"""
+
+    model_config = ConfigDict(extra='forbid')
+
+    s3_endpoint_url: str
+    s3_access_key: str
+    s3_secret_key: str
+    restic_bucket: Optional[str] = None
+    restic_password: Optional[str] = None
+    backups: Dict[str, BackupConfig] = {}
+    retention: Dict[str, str] = {}
 
 
 class RwmJSONEncoder(json.JSONEncoder):
@@ -373,15 +371,37 @@ class StorageManager:
         return 0
 
 
+@dataclass
+class BackupResult:
+    """backup results data container"""
+
+    name: str
+    returncode: int
+    time_start: datetime
+    time_end: datetime
+
+    def to_dict(self):
+        """dict serializer"""
+
+        return {
+            "ident": "RESULT",
+            "name": self.name,
+            "status": "OK" if self.returncode == 0 else "ERROR",
+            "returncode": self.returncode,
+            "backup_start": self.time_start.isoformat(),
+            "backup_time": str(self.time_end-self.time_start),
+        }
+
+
 class RWM:
     """rwm impl"""
 
-    def __init__(self, config):
-        self.config = config
+    def __init__(self, config_dict):
+        self.config = RWMConfig(**config_dict)
         self.storage_manager = StorageManager(
-            config.get("rwm_s3_endpoint_url"),
-            config.get("rwm_s3_access_key"),
-            config.get("rwm_s3_secret_key")
+            self.config.s3_endpoint_url,
+            self.config.s3_access_key,
+            self.config.s3_secret_key
         )
 
     def aws_cmd(self, args) -> subprocess.CompletedProcess:
@@ -390,15 +410,15 @@ class RWM:
         env = {
             "PATH": os.environ["PATH"],
             "AWS_METADATA_SERVICE_NUM_ATTEMPTS": "0",
-            "AWS_ACCESS_KEY_ID": self.config["rwm_s3_access_key"],
-            "AWS_SECRET_ACCESS_KEY": self.config["rwm_s3_secret_key"]
+            "AWS_ACCESS_KEY_ID": self.config.s3_access_key,
+            "AWS_SECRET_ACCESS_KEY": self.config.s3_secret_key
         }
         if is_sublist(["s3", "mb"], args):
             # region must be set and empty for awscil >=2.x and ?du? ceph s3
             env.update({"AWS_DEFAULT_REGION": ""})
 
         # aws cli does not have endpoint-url as env config option
-        return run_command(["aws", "--endpoint-url", self.config["rwm_s3_endpoint_url"]] + args, env=env)
+        return run_command(["aws", "--endpoint-url", self.config.s3_endpoint_url] + args, env=env)
 
     def restic_cmd(self, args) -> subprocess.CompletedProcess:
         """restic command wrapper"""
@@ -406,10 +426,10 @@ class RWM:
         env = {
             "HOME": os.environ["HOME"],
             "PATH": os.environ["PATH"],
-            "AWS_ACCESS_KEY_ID": self.config["rwm_s3_access_key"],
-            "AWS_SECRET_ACCESS_KEY": self.config["rwm_s3_secret_key"],
-            "RESTIC_PASSWORD": self.config["rwm_restic_password"],
-            "RESTIC_REPOSITORY": f"s3:{self.config['rwm_s3_endpoint_url']}/{self.config['rwm_restic_bucket']}",
+            "AWS_ACCESS_KEY_ID": self.config.s3_access_key,
+            "AWS_SECRET_ACCESS_KEY": self.config.s3_secret_key,
+            "RESTIC_PASSWORD": self.config.restic_password,
+            "RESTIC_REPOSITORY": f"s3:{self.config.s3_endpoint_url}/{self.config.restic_bucket}",
         }
         return run_command(["restic"] + args, env=env)
 
@@ -417,12 +437,11 @@ class RWM:
         """runs restic backup by name"""
 
         logger.info(f"run restic_backup {name}")
-        conf = self.config["rwm_backups"][name]
+        conf = self.config.backups[name]
         excludes = []
-        for item in conf.get("excludes", []):
+        for item in conf.excludes:
             excludes += ["--exclude", item]
-        extras = conf.get("extras", [])
-        cmd_args = ["backup"] + extras + excludes + conf["filesdirs"]
+        cmd_args = ["backup"] + conf.extras + excludes + conf.filesdirs
 
         return self.restic_cmd(cmd_args)
 
@@ -431,7 +450,7 @@ class RWM:
 
         logger.info("run restic_forget_prune")
         keeps = []
-        for key, val in self.config.get("rwm_retention", {}).items():
+        for key, val in self.config.retention.items():
             keeps += [f"--{key}", val]
         cmd_args = ["forget", "--prune"] + keeps
 
@@ -451,18 +470,16 @@ class RWM:
 
     def _prerun(self, name) -> int:
         """prerun runparts stub"""
-        return self._runparts("prerun", self.config["rwm_backups"][name].get("prerun", []))
+        return self._runparts("prerun", self.config.backups[name].prerun)
 
     def _postrun(self, name) -> int:
         """postrun runparts stub"""
-        return self._runparts("postrun", self.config["rwm_backups"][name].get("postrun", []))
+        return self._runparts("postrun", self.config.backups[name].prerun)
 
     def backup(self, name) -> int:
         """backup command"""
 
-        bucket_name = self.config["rwm_restic_bucket"]
-
-        if not self.storage_manager.storage_check_policy(bucket_name):
+        if not self.storage_manager.storage_check_policy(self.config.restic_bucket):
             logger.warning("used bucket does not have expected policy")
 
         if self._prerun(name) != 0:
@@ -483,7 +500,7 @@ class RWM:
             logger.error("rwm _restic_forget_prune failed")
             return 1
 
-        if self.storage_manager.storage_save_state(bucket_name) != 0:
+        if self.storage_manager.storage_save_state(self.config.restic_bucket) != 0:
             logger.error("rwm storage_save_state failed")
             return 1
 
@@ -495,7 +512,7 @@ class RWM:
         stats = []
         ret = 0
 
-        for name in self.config["rwm_backups"].keys():
+        for name in self.config.backups:
             time_start = datetime.now()
             wrap_output(backup_proc := self._restic_backup(name))
             time_end = datetime.now()
@@ -510,7 +527,7 @@ class RWM:
             stats.append(BackupResult("_forget_prune", forget_proc.returncode, time_start, time_end))
 
         time_start = datetime.now()
-        save_state_ret = self.storage_manager.storage_save_state(self.config["rwm_restic_bucket"])
+        save_state_ret = self.storage_manager.storage_save_state(self.config.restic_bucket)
         time_end = datetime.now()
         ret |= save_state_ret
         stats.append(BackupResult("_storage_save_state", save_state_ret, time_start, time_end))
@@ -636,18 +653,23 @@ def parse_arguments(argv):
     return parser.parse_args(argv)
 
 
+def load_config(path):
+    """load config dict from file"""
+
+    config = {}
+    if path:
+        config = yaml.safe_load(Path(path).read_text(encoding='utf-8'))
+    logger.debug("config, %s", config)
+    return config
+
+
 def main(argv=None):  # pylint: disable=too-many-branches
     """main"""
 
     args = parse_arguments(argv)
     configure_logging(args.debug)
 
-    config = {}
-    if args.config:
-        config.update(get_config(args.config))
-    logger.debug("config, %s", config)
-    # assert config ?
-    rwmi = RWM(config)
+    rwmi = RWM(load_config(args.config))
     ret = -1
 
     if args.command == "version":
diff --git a/tests/rwmtest.conf b/tests/rwmtest.conf
new file mode 100644
index 0000000000000000000000000000000000000000..4e9e204ce469e4f5c442512dd3924bcd64691cbe
--- /dev/null
+++ b/tests/rwmtest.conf
@@ -0,0 +1,3 @@
+s3_endpoint_url: http://dummy
+s3_access_key: dummy
+s3_secret_key: dummy
\ No newline at end of file
diff --git a/tests/test_default.py b/tests/test_default.py
index b174ee8d8df119c944bfe8f45d281b3f40e2c204..ff9c793fe68907f461b6021b126aff47d217d144 100644
--- a/tests/test_default.py
+++ b/tests/test_default.py
@@ -1,6 +1,5 @@
 """default tests"""
 
-from pathlib import Path
 from subprocess import CompletedProcess
 from unittest.mock import Mock, patch
 
@@ -29,37 +28,37 @@ def test_size_fmt():
     assert size_fmt(10**25) == "8.3 YiB"
 
 
-def test_main(tmpworkdir: str):  # pylint: disable=unused-argument
+def test_main():
     """test main"""
 
-    # optional and default config handling
-    assert rwm_main(["version"]) == 0
-    Path("rwm.conf").touch()
-    assert rwm_main(["version"]) == 0
+    def rwm_main_minconfig(args):
+        return rwm_main(["--config", "tests/rwmtest.conf"] + args)
+
+    assert rwm_main_minconfig(["version"]) == 0
 
     # command branches
     mock_proc = Mock(return_value=CompletedProcess(args='dummy', returncode=0))
     mock_ok = Mock(return_value=0)
 
     with patch.object(rwm.RWM, "aws_cmd", mock_proc):
-        assert rwm_main(["aws", "dummy"]) == 0
+        assert rwm_main_minconfig(["aws", "dummy"]) == 0
     with patch.object(rwm.RWM, "restic_cmd", mock_proc):
-        assert rwm_main(["restic", "dummy"]) == 0
+        assert rwm_main_minconfig(["restic", "dummy"]) == 0
 
     with patch.object(rwm.RWM, "backup", mock_ok):
-        assert rwm_main(["backup", "dummy"]) == 0
+        assert rwm_main_minconfig(["backup", "dummy"]) == 0
     with patch.object(rwm.RWM, "backup_all", mock_ok):
-        assert rwm_main(["backup_all"]) == 0
+        assert rwm_main_minconfig(["backup_all"]) == 0
 
     with patch.object(rwm.RWM, "storage_create", mock_ok):
-        assert rwm_main(["storage_create", "bucket", "user"]) == 0
+        assert rwm_main_minconfig(["storage_create", "bucket", "user"]) == 0
     with patch.object(rwm.RWM, "storage_delete", mock_ok):
-        assert rwm_main(["storage_delete", "bucket"]) == 0
+        assert rwm_main_minconfig(["storage_delete", "bucket"]) == 0
     with patch.object(rwm.RWM, "storage_list", mock_ok):
-        assert rwm_main(["storage_list"]) == 0
+        assert rwm_main_minconfig(["storage_list"]) == 0
     with patch.object(rwm.RWM, "storage_info", mock_ok):
-        assert rwm_main(["storage_info", "dummy"]) == 0
+        assert rwm_main_minconfig(["storage_info", "dummy"]) == 0
     with patch.object(rwm.RWM, "storage_drop_versions", mock_ok):
-        assert rwm_main(["storage_drop_versions", "bucket"]) == 0
+        assert rwm_main_minconfig(["storage_drop_versions", "bucket"]) == 0
     with patch.object(rwm.RWM, "storage_restore_state", mock_ok):
-        assert rwm_main(["storage_restore_state", "bucket", "bucket", "state"]) == 0
+        assert rwm_main_minconfig(["storage_restore_state", "bucket", "bucket", "state"]) == 0
diff --git a/tests/test_rwm.py b/tests/test_rwm.py
index 8687337804b9898864920c2aa53b17d3988b67dd..de89cbed4c405cbce744b6a02e00ce9b2da36425 100644
--- a/tests/test_rwm.py
+++ b/tests/test_rwm.py
@@ -14,9 +14,9 @@ def test_aws_cmd(tmpworkdir: str, motoserver: str):  # pylint: disable=unused-ar
     """test aws command"""
 
     trwm = rwm.RWM({
-        "rwm_s3_endpoint_url": motoserver,
-        "rwm_s3_access_key": "dummy",
-        "rwm_s3_secret_key": "dummy",
+        "s3_endpoint_url": motoserver,
+        "s3_access_key": "dummy",
+        "s3_secret_key": "dummy",
     })
     test_bucket = "testbucket"
 
@@ -33,11 +33,11 @@ def test_restic_cmd(tmpworkdir: str, motoserver: str):  # pylint: disable=unused
     """test restic command"""
 
     trwm = rwm.RWM({
-        "rwm_s3_endpoint_url": motoserver,
-        "rwm_s3_access_key": "dummy",
-        "rwm_s3_secret_key": "dummy",
-        "rwm_restic_bucket": "restictest",
-        "rwm_restic_password": "dummydummydummydummy",
+        "s3_endpoint_url": motoserver,
+        "s3_access_key": "dummy",
+        "s3_secret_key": "dummy",
+        "restic_bucket": "restictest",
+        "restic_password": "dummydummydummydummy",
     })
 
     assert trwm.restic_cmd(["init"]).returncode == 0
@@ -56,13 +56,13 @@ def _restic_list_snapshot_files(trwm, snapshot_id):
     return [x["path"] for x in snapshot_ls if (x["struct_type"] == "node") and (x["type"] == "file")]
 
 
-def test_runparts(tmpworkdir: str, motoserver: str):  # pylint: disable=unused-argument
+def test_runparts(tmpworkdir: str):  # pylint: disable=unused-argument
     """test runparts"""
 
     trwm = rwm.RWM({
-        "rwm_s3_endpoint_url": motoserver,
-        "rwm_s3_access_key": "dummy",
-        "rwm_s3_secret_key": "dummy",
+        "s3_endpoint_url": "http://dummy",
+        "s3_access_key": "dummy",
+        "s3_secret_key": "dummy",
     })
 
     assert trwm._runparts("tests", ["false"]) == 1  # pylint: disable=protected-access
@@ -72,19 +72,19 @@ def test_backup(tmpworkdir: str, motoserver: str):  # pylint: disable=unused-arg
     """test backup"""
 
     trwm = rwm.RWM({
-        "rwm_s3_endpoint_url": motoserver,
-        "rwm_s3_access_key": "dummy",
-        "rwm_s3_secret_key": "dummy",
-        "rwm_restic_bucket": "restictest",
-        "rwm_restic_password": "dummydummydummydummy",
-        "rwm_backups": {
+        "s3_endpoint_url": motoserver,
+        "s3_access_key": "dummy",
+        "s3_secret_key": "dummy",
+        "restic_bucket": "restictest",
+        "restic_password": "dummydummydummydummy",
+        "backups": {
             "testcfg": {
                 "filesdirs": ["testdatadir/"],
                 "excludes": ["testfile_to_be_ignored"],
                 "extras": ["--tag", "dummytag"],
             }
         },
-        "rwm_retention": {
+        "retention": {
             "keep-daily": "1"
         }
     })
@@ -106,12 +106,12 @@ def test_backup_excludes(tmpworkdir: str, motoserver: str):  # pylint: disable=u
     """test backu"""
 
     trwm = rwm.RWM({
-        "rwm_s3_endpoint_url": motoserver,
-        "rwm_s3_access_key": "dummy",
-        "rwm_s3_secret_key": "dummy",
-        "rwm_restic_bucket": "restictest",
-        "rwm_restic_password": "dummydummydummydummy",
-        "rwm_backups": {
+        "s3_endpoint_url": motoserver,
+        "s3_access_key": "dummy",
+        "s3_secret_key": "dummy",
+        "restic_bucket": "restictest",
+        "restic_password": "dummydummydummydummy",
+        "backups": {
             "testcfg": {
                 "filesdirs": ["testdatadir/"],
                 "excludes": ["testdatadir/proc/*", "*.ignored"],
@@ -145,16 +145,16 @@ def test_backup_excludes(tmpworkdir: str, motoserver: str):  # pylint: disable=u
     assert "/testdatadir/var/proc/data" in snapshot_files
 
 
-def test_backup_runparts(tmpworkdir: str, motoserver: str):  # pylint: disable=unused-argument
+def test_backup_runparts(tmpworkdir: str):  # pylint: disable=unused-argument
     """test backup"""
 
     trwm = rwm.RWM({
-        "rwm_s3_endpoint_url": motoserver,
-        "rwm_s3_access_key": "dummy",
-        "rwm_s3_secret_key": "dummy",
-        "rwm_restic_bucket": "restictest",
-        "rwm_restic_password": "dummydummydummydummy",
-        "rwm_backups": {
+        "s3_endpoint_url": "http://dummy",
+        "s3_access_key": "dummy",
+        "s3_secret_key": "dummy",
+        "restic_bucket": "restictest",
+        "restic_password": "dummydummydummydummy",
+        "backups": {
             "testcfg": {
                 "filesdirs": ["testdatadir/"],
                 "prerun": ["false || true"],
@@ -175,12 +175,15 @@ def test_backup_runparts(tmpworkdir: str, motoserver: str):  # pylint: disable=u
         assert trwm.backup("testcfg") == 0
 
 
-def test_backup_error_handling(tmpworkdir: str, motoserver: str):  # pylint: disable=unused-argument
+def test_backup_error_handling(tmpworkdir: str):  # pylint: disable=unused-argument
     """test backup command err cases"""
 
     rwm_conf = {
-        "rwm_restic_bucket": "restictest",
-        "rwm_backups": {
+        "s3_endpoint_url": "http://dummy",
+        "s3_access_key": "dummy",
+        "s3_secret_key": "dummy",
+        "restic_bucket": "restictest",
+        "backups": {
             "dummycfg": {"filesdirs": ["dummydir"]}
         }
     }
@@ -229,8 +232,11 @@ def test_backup_all(tmpworkdir: str):  # pylint: disable=unused-argument
     """test backup_all"""
 
     rwm_conf = {
-        "rwm_restic_bucket": "restictest",
-        "rwm_backups": {
+        "s3_endpoint_url": "http://dummy",
+        "s3_access_key": "dummy",
+        "s3_secret_key": "dummy",
+        "restic_bucket": "restictest",
+        "backups": {
             "dummycfg": {"filesdirs": ["dummydir"]}
         }
     }
@@ -249,9 +255,9 @@ def test_storage_create(tmpworkdir: str, microceph: str, radosuser_admin: rwm.St
     """test_storage_create"""
 
     trwm = rwm.RWM({
-        "rwm_s3_endpoint_url": radosuser_admin.url,
-        "rwm_s3_access_key": radosuser_admin.access_key,
-        "rwm_s3_secret_key": radosuser_admin.secret_key,
+        "s3_endpoint_url": radosuser_admin.url,
+        "s3_access_key": radosuser_admin.access_key,
+        "s3_secret_key": radosuser_admin.secret_key,
     })
 
     bucket_name = "testbuck"
@@ -264,18 +270,17 @@ def test_storage_delete(tmpworkdir: str, microceph: str, radosuser_admin: rwm.St
     """test_storage_delete"""
 
     trwm = rwm.RWM({
-        "rwm_s3_endpoint_url": radosuser_admin.url,
-        "rwm_s3_access_key": radosuser_admin.access_key,
-        "rwm_s3_secret_key": radosuser_admin.secret_key,
-
-        "rwm_restic_bucket": "testbuck",
-        "rwm_restic_password": "dummydummydummydummy",
-        "rwm_backups": {
+        "s3_endpoint_url": radosuser_admin.url,
+        "s3_access_key": radosuser_admin.access_key,
+        "s3_secret_key": radosuser_admin.secret_key,
+        "restic_bucket": "testbuck",
+        "restic_password": "dummydummydummydummy",
+        "backups": {
             "testcfg": {"filesdirs": ["testdatadir/"]}
         }
     })
 
-    bucket_name = trwm.config["rwm_restic_bucket"]
+    bucket_name = trwm.config.restic_bucket
     Path("testdatadir").mkdir()
     Path("testdatadir/testdata1.txt").write_text("dummydata", encoding="utf-8")
 
@@ -296,7 +301,11 @@ def test_storage_delete(tmpworkdir: str, microceph: str, radosuser_admin: rwm.St
 def test_storage_list(tmpworkdir: str):  # pylint: disable=unused-argument
     """test storage_list"""
 
-    trwm = rwm.RWM({})
+    trwm = rwm.RWM({
+        "s3_endpoint_url": "http://dummy",
+        "s3_access_key": "dummy",
+        "s3_secret_key": "dummy"
+    })
 
     mock = Mock(return_value=[])
     with patch.object(rwm.StorageManager, "storage_list", mock):
@@ -307,9 +316,9 @@ def test_storage_info(tmpworkdir: str, microceph: str, radosuser_admin: rwm.Stor
     """test storage_list"""
 
     trwm = rwm.RWM({
-        "rwm_s3_endpoint_url": radosuser_admin.url,
-        "rwm_s3_access_key": radosuser_admin.access_key,
-        "rwm_s3_secret_key": radosuser_admin.secret_key,
+        "s3_endpoint_url": radosuser_admin.url,
+        "s3_access_key": radosuser_admin.access_key,
+        "s3_secret_key": radosuser_admin.secret_key,
     })
 
     trwm.storage_create("dummy", "dummy")
@@ -319,7 +328,11 @@ def test_storage_info(tmpworkdir: str, microceph: str, radosuser_admin: rwm.Stor
 def test_storage_drop_versions(tmpworkdir: str):  # pylint: disable=unused-argument
     """test storage drop versions"""
 
-    trwm = rwm.RWM({})
+    trwm = rwm.RWM({
+        "s3_endpoint_url": "http://dummy",
+        "s3_access_key": "dummy",
+        "s3_secret_key": "dummy"
+    })
 
     mock = Mock(return_value=0)
     with patch.object(rwm.StorageManager, "storage_drop_versions", mock):
@@ -330,12 +343,12 @@ def test_storage_restore_state_restic(tmpworkdir: str, radosuser_admin: rwm.Stor
     """test restore bucket from previous saved state"""
 
     trwm = rwm.RWM({
-        "rwm_s3_endpoint_url": radosuser_admin.url,
-        "rwm_s3_access_key": radosuser_admin.access_key,
-        "rwm_s3_secret_key": radosuser_admin.secret_key,
-        "rwm_restic_bucket": "restictest",
-        "rwm_restic_password": "dummydummydummydummy",
-        "rwm_backups": {
+        "s3_endpoint_url": radosuser_admin.url,
+        "s3_access_key": radosuser_admin.access_key,
+        "s3_secret_key": radosuser_admin.secret_key,
+        "restic_bucket": "restictest",
+        "restic_password": "dummydummydummydummy",
+        "backups": {
             "testcfg": {
                 "filesdirs": ["testdatadir/"],
             }
@@ -343,7 +356,7 @@ def test_storage_restore_state_restic(tmpworkdir: str, radosuser_admin: rwm.Stor
     })
 
     # create and initialize storage
-    assert trwm.storage_create(trwm.config["rwm_restic_bucket"], "dummy") == 0
+    assert trwm.storage_create(trwm.config.restic_bucket, "dummy") == 0
     assert trwm.restic_cmd(["init"]).returncode == 0
 
     # do backups
@@ -360,17 +373,17 @@ def test_storage_restore_state_restic(tmpworkdir: str, radosuser_admin: rwm.Stor
     assert len(snapshots) == 2
     assert len(snapshot_files) == 1
     assert "/testdatadir/testdata2.txt" == snapshot_files[0]
-    states = sorted([x.key for x in trwm.storage_manager.s3.Bucket(trwm.config["rwm_restic_bucket"]).object_versions.filter(Prefix="rwm")])
+    states = sorted([x.key for x in trwm.storage_manager.s3.Bucket(trwm.config.restic_bucket).object_versions.filter(Prefix="rwm")])
     assert len(states) == 2
 
     # create restore bucket
-    restore_bucket_name = f'{trwm.config["rwm_restic_bucket"]}-restore'
-    trwm.storage_restore_state(trwm.config["rwm_restic_bucket"], restore_bucket_name, states[0])
+    restore_bucket_name = f"{trwm.config.restic_bucket}-restore"
+    trwm.storage_restore_state(trwm.config.restic_bucket, restore_bucket_name, states[0])
 
     # check restore bucket contents
     trwm_restore = rwm.RWM({
-        **trwm.config,
-        "rwm_restic_bucket": restore_bucket_name
+        **dict(trwm.config),
+        "restic_bucket": restore_bucket_name
     })
     snapshots = _restic_list_snapshots(trwm_restore)
     snapshot_files = _restic_list_snapshot_files(trwm_restore, snapshots[0]["id"])
diff --git a/tests/test_storage.py b/tests/test_storage.py
index 12bbd19435f42ab488fb9cb2715e7e8ea81d28d6..30f0213393a10345581b98dad1ef3b930b3d0057 100644
--- a/tests/test_storage.py
+++ b/tests/test_storage.py
@@ -129,12 +129,12 @@ def test_storage_backup_usage(
     Path("testdir/testdata").write_text('dummy', encoding="utf-8")
 
     trwm = rwm.RWM({
-        "rwm_s3_endpoint_url": radosuser_test1.url,
-        "rwm_s3_access_key": radosuser_test1.access_key,
-        "rwm_s3_secret_key": radosuser_test1.secret_key,
-        "rwm_restic_bucket": bucket_name,
-        "rwm_restic_password": "dummydummydummydummy",
-        "rwm_backups": {
+        "s3_endpoint_url": radosuser_test1.url,
+        "s3_access_key": radosuser_test1.access_key,
+        "s3_secret_key": radosuser_test1.secret_key,
+        "restic_bucket": bucket_name,
+        "restic_password": "dummydummydummydummy",
+        "backups": {
             "dummy": {"filesdirs": ["testdir"]}
         }
     })