diff --git a/files/config/weblate_permissions.yaml b/files/config/weblate_permissions.yaml
index f7a4ef110a4a44782df6b6dc18a676b0563be008..775239d2509d1c8f2856c0995fe9e3a6aa8c3647 100644
--- a/files/config/weblate_permissions.yaml
+++ b/files/config/weblate_permissions.yaml
@@ -361,3 +361,4 @@ superusers:
 - drebs
 - hefee
 - intrigeri
+userdb_cache: /var/lib/weblate/userdb_cache.yml
diff --git a/files/scripts/tests/data/permissions_stage1.yml b/files/scripts/tests/data/permissions_stage1.yml
index 874bbd54544bf9f744ae666b52e7a629df494273..aac180941a95e1ad313c8d9c39e1bffd4a0b960d 100644
--- a/files/scripts/tests/data/permissions_stage1.yml
+++ b/files/scripts/tests/data/permissions_stage1.yml
@@ -15,3 +15,4 @@ roles:
   - suggestion.add
 users:
 superusers:
+userdb_cache: /tmp/userdb_cache.yml
diff --git a/files/scripts/tests/data/permissions_stage2.yml b/files/scripts/tests/data/permissions_stage2.yml
index 469c199077ecec0f939661b8e6a52998aa9d709c..3fa4cb2e7f349569f264a9a747c7906993e16ed0 100644
--- a/files/scripts/tests/data/permissions_stage2.yml
+++ b/files/scripts/tests/data/permissions_stage2.yml
@@ -19,3 +19,4 @@ users:
     groups:
     - Users
 superusers:
+userdb_cache: /tmp/userdb_cache.yml
diff --git a/files/scripts/tests/data/permissions_stage3.yml b/files/scripts/tests/data/permissions_stage3.yml
index c82d9850a9b40f21d6e6a122e936ea89db86688e..e386942cc7133baf97fa6f4e7ea626b6a11f633e 100644
--- a/files/scripts/tests/data/permissions_stage3.yml
+++ b/files/scripts/tests/data/permissions_stage3.yml
@@ -6,3 +6,4 @@ roles:
   - __deleted
 users:
 superusers:
+userdb_cache: /tmp/userdb_cache.yml
diff --git a/files/scripts/tests/data/superuser.yml b/files/scripts/tests/data/superuser.yml
index a87abf479be7fe08ddbe53578bd4ddaf6a95522a..8563f3e6a38cc510bf929a13673d915f65544bf4 100644
--- a/files/scripts/tests/data/superuser.yml
+++ b/files/scripts/tests/data/superuser.yml
@@ -13,3 +13,4 @@ users:
       - Viewers
 superusers:
 - User1
+userdb_cache: /tmp/userdb_cache.yml
diff --git a/files/scripts/tests/test_weblate_permissions.py b/files/scripts/tests/test_weblate_permissions.py
index 311b471bad56dcd47243d99549a82c2bbf0a4a45..2727bd2dbecfe9e2b34c3026b8e7a82f30a94dfe 100644
--- a/files/scripts/tests/test_weblate_permissions.py
+++ b/files/scripts/tests/test_weblate_permissions.py
@@ -41,6 +41,8 @@ class testTP(unittest.TestCase):
         for i in User.objects.all():
             if i.username not in self.existing_user:
                 i.delete()
+        userdb_cache = pathlib.Path("/tmp/userdb_cache.yml")
+        userdb_cache.unlink(missing_ok=True)
 
     def test_create_roles_and_groups(self):
         group = Group.objects.filter(name="Test Group").first()
@@ -388,3 +390,77 @@ class testTP(unittest.TestCase):
             ' - Users\n'
             ' - Viewers',
         ])
+
+    def test_renaming_user_causes_permission_enforcement_error(self):
+        User.objects.create(username="User2")    # referenced by superuser.yml
+        e = tp.Config([self.datapath/'superuser.yml'])
+        with self.assertLogs(level="DEBUG") as cm:
+            tp.weblate_permission(e, True)
+        user1 = User.objects.filter(username="User1").first()
+        self.assertEqual(user1.is_superuser, True)
+
+        user1.username = "NewUsername"
+        user1.save()
+        with self.assertLogs(level="DEBUG") as cm:
+            tp.weblate_permission(e, True)
+
+        print(cm.output)
+        self.assertEqual(cm.output[-4:], [
+            'WARNING:weblate_permissions:The referenced user User1 renamed itself to NewUsername. Update the config accordingly.',
+            'INFO:weblate_permissions.audit:Group mismatch for user(NewUsername)\n +++ expected\n --- actual\n - Users\n - Viewers',
+            'INFO:weblate_permissions.audit:Wrong superuser status for NewUsername (True != False)',
+            'INFO:weblate_permissions.audit:Save user(NewUsername)',
+        ])
+        self.assertEqual(User.objects.filter(username="NewUsername").first().is_superuser, False)
+
+        with self.assertLogs(level="DEBUG") as cm:
+            tp.weblate_permission(e, True)
+
+        print(cm.output)
+        self.assertEqual(cm.output[-1:], [
+            'WARNING:weblate_permissions:The referenced user User1 renamed itself to NewUsername. Update the config accordingly.',
+        ])
+        self.assertEqual(User.objects.filter(username="NewUsername").first().is_superuser, False)
+
+    def test_prevent_overtake_permissions_of_renamed_user(self):
+        user2 = User.objects.create(username="User2")    # referenced by superuser.yml
+        e = tp.Config([self.datapath/'superuser.yml'])
+        with self.assertLogs(level="DEBUG") as cm:
+            tp.weblate_permission(e, True)
+        user1 = User.objects.filter(username="User1").first()
+        self.assertEqual(user1.is_superuser, True)
+
+        user2.delete()
+        user1.username = "NewUsername"
+        user1.save()
+        user_takeover = User.objects.create(username="User1")
+        with self.assertLogs(level="DEBUG") as cm:
+            tp.weblate_permission(e, True)
+
+        print(cm.output[-8:])
+        self.assertEqual(cm.output[-8:], [
+            'WARNING:weblate_permissions:User1 was taken over by someone else.',
+            'WARNING:weblate_permissions:The referenced user User1 renamed itself to NewUsername. Update the config accordingly.',
+            'WARNING:weblate_permissions:The Referenced user User2 was deleted. Create the account again or delete user from the configuration.',
+            'INFO:weblate_permissions.audit:Group mismatch for user(NewUsername)\n +++ expected\n --- actual\n - Users\n - Viewers',
+            'INFO:weblate_permissions.audit:Wrong superuser status for NewUsername (True != False)',
+            'INFO:weblate_permissions.audit:Save user(NewUsername)',
+            'INFO:weblate_permissions.audit:Wrong superuser status for User1 (False != True)',
+            'INFO:weblate_permissions:User1 is marked (the issues are listed above): skip to save user.',
+        ])
+        self.assertEqual(User.objects.filter(username="User1").first().is_superuser, False)
+        self.assertEqual(User.objects.filter(username="NewUsername").first().is_superuser, False)
+
+        with self.assertLogs(level="DEBUG") as cm:
+            tp.weblate_permission(e, True)
+
+        print(cm.output)
+        self.assertEqual(cm.output[-5:], [
+            'WARNING:weblate_permissions:User1 was taken over by someone else.',
+            'WARNING:weblate_permissions:The referenced user User1 renamed itself to NewUsername. Update the config accordingly.',
+            'WARNING:weblate_permissions:The Referenced user User2 was deleted. Create the account again or delete user from the configuration.',
+            'INFO:weblate_permissions.audit:Wrong superuser status for User1 (False != True)',
+            'INFO:weblate_permissions:User1 is marked (the issues are listed above): skip to save user.',
+        ])
+        self.assertEqual(User.objects.filter(username="User1").first().is_superuser, False)
+        self.assertEqual(User.objects.filter(username="NewUsername").first().is_superuser, False)
diff --git a/files/scripts/weblate_permissions.py b/files/scripts/weblate_permissions.py
index 36e06aea8f575cc74a6d0f2782ca91648f15bb75..742655b36bbf9ece1fd576d0e23ef8abca761e2d 100644
--- a/files/scripts/weblate_permissions.py
+++ b/files/scripts/weblate_permissions.py
@@ -124,10 +124,14 @@ maintenance without the script interfering in the work. To run the script in
 `--enforceMaintenance` option.
 '''
 
+import datetime
+import itertools
 import logging
 import logging.config
 import operator
+import pathlib
 import yaml
+from typing import List
 import tailsWeblate    # Needed because of the side effect to setup the django application
 from weblate.auth.models import Group, Language, Permission, Project, Role, User
 
@@ -231,6 +235,80 @@ class DBQuery:
         return True
 
 
+class UserCache:
+    """
+    Usernames are unique, but changeable in Weblate.
+    The problem is that using user ids in the config is not very readable for admistrators.
+    To solve this we keep a userdb_cache, which is a dict mapping username to ids, to detect user renames.
+    """
+    def __init__(self, path: pathlib.Path):
+        self.changed = False                # userdb_cache changed (needs to be saved)
+        self.warning_users:List[str] = []   # detected a warning for users
+        self.path = pathlib.Path(path)
+        self._read()
+
+    def _read(self):
+        if self.path.exists():
+            with self.path.open() as f:
+                self.cache = yaml.safe_load(f)
+        else:
+            self.cache = {}
+
+    def _save(self):
+        with self.path.open('w') as f:
+            yaml.dump(self.cache, f, default_flow_style=False)
+        self.changed = False
+
+    def save_if_changed(self):
+        if self.changed:
+            self._save()
+
+    def add(self, user):
+        self.cache[user.username] = {
+                'id':user.id,
+                'email': user.email,
+                'added': datetime.datetime.now().isoformat(),
+                }
+        self.changed = True
+
+    def delete(self, username):
+        del self.cache[username]
+        self.changed = True
+
+    def cleanup_cache(self, usernames:List[str]):
+        to_del = set(self.cache.keys()) - usernames
+        for username in to_del:
+            self.delete(username)
+
+    def check(self, usernames:List[str]):
+        for username in usernames:
+            if username == "__default":
+                continue
+
+            user_cache = self.cache.get(username, None)
+            try:
+                user_db = User.objects.get(username=username)
+            except User.DoesNotExist:
+                user_db = None
+
+            if user_cache is None:
+                if user_db is None:
+                    logger.warning(f"Referenced user {username} does not exist. Create the account now or delete user from the configuration.")
+                    self.warning_users.append(username)
+                else:
+                    self.add(user_db)
+            elif user_db is None or user_db.id != user_cache['id']:
+                if user_db:
+                    logger.warning(f"{username} was taken over by someone else.")
+                try:
+                    renamed_user = User.objects.get(id=user_cache['id'])
+                except User.DoesNotExist:
+                    logger.warning(f"The Referenced user {username} was deleted. Create the account again or delete user from the configuration.")
+                else:
+                    logger.warning(f"The referenced user {username} renamed itself to {renamed_user.username}. Update the config accordingly.")
+                self.warning_users.append(username)
+
+
 class WeblatePermission:
 
     def __init__(self, config, enforce):
@@ -450,6 +528,18 @@ class WeblatePermission:
         check(a, self.groups, "More groups found, than defined.", logger.warning)
 
     def fix_users(self):
+        default_user = self.config.users['__default']
+        usernames = set(itertools.chain.from_iterable((self.config.users, self.config.superusers)))
+
+        # Usernames are unique, but changeable in Weblate.
+        # The UserCache class keeps track of username <-> id.
+        user_cache = UserCache(self.config.userdb_cache)
+        user_cache.cleanup_cache(usernames)
+        user_cache.check(sorted(usernames))
+        marked_users = user_cache.warning_users
+
+        user_cache.save_if_changed()
+
         for i in sorted(User.objects.all(),key=lambda i:i.username.lower()):
             changed = False
 
@@ -457,7 +547,7 @@ class WeblatePermission:
                 # Ignore inactive users, if they are not listed explictitly
                 continue
 
-            e = self.config.users.get(i.username, self.config.users['__default'])
+            e = self.config.users.get(i.username, default_user)
 
             dbquery = DBQuery(i.groups, 'name', Group.objects)
             if not self.attribute(dbquery)(e['groups'], f"Group mismatch for user({i.username})", self.logfunc):
@@ -466,7 +556,11 @@ class WeblatePermission:
                 changed = True
             if not self.check_func(i,'is_active', e.get('is_active'), f"Wrong is_active status for {i.username}", self.logfunc, False):
                 changed = True
+
             if changed and self.enforce:
+                if i.username in marked_users:
+                    logger.info(f"{i.username} is marked (the issues are listed above): skip to save user.")
+                    continue
                 auditlogger.info(f"Save user({i.username})")
                 i.save()