diff --git a/adherents/__init__.py b/adherents/__init__.py
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..c1217d1393044627e09aa61aac0a83852299dd9e 100644
--- a/adherents/__init__.py
+++ b/adherents/__init__.py
@@ -0,0 +1,5 @@
+# -*- mode: python; coding: utf-8 -*-
+# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+default_app_config = 'adherents.apps.AdherentsConfig'
diff --git a/adherents/admin.py b/adherents/admin.py
new file mode 100644
index 0000000000000000000000000000000000000000..72b4015e2ebb2f0c5917a5cb8f825bbf82c918fd
--- /dev/null
+++ b/adherents/admin.py
@@ -0,0 +1,35 @@
+# -*- mode: python; coding: utf-8 -*-
+# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from django.contrib import admin
+from django.contrib.auth.admin import UserAdmin
+from django.contrib.auth.models import User
+
+from .forms import CustomUserChangeForm
+from .models import Profile
+
+
+class ProfileInline(admin.StackedInline):
+    """Inline user profile in user admin"""
+    model = Profile
+    can_delete = False
+
+
+class CustomUserAdmin(UserAdmin):
+    inlines = (ProfileInline,)
+    list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff')
+    list_select_related = ('profile',)
+    form = CustomUserChangeForm
+
+    def get_inline_instances(self, request, obj=None):
+        """
+        When creating a new user don't show profile one the first step
+        """
+        if not obj:
+            return list()
+        return super().get_inline_instances(request, obj)
+
+
+admin.site.unregister(User)
+admin.site.register(User, CustomUserAdmin)
diff --git a/adherents/apps.py b/adherents/apps.py
new file mode 100644
index 0000000000000000000000000000000000000000..05e36034489a50467653b592b37c5df5e67c8a58
--- /dev/null
+++ b/adherents/apps.py
@@ -0,0 +1,11 @@
+# -*- mode: python; coding: utf-8 -*-
+# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from django.apps import AppConfig
+from django.utils.translation import gettext_lazy as _
+
+
+class AdherentsConfig(AppConfig):
+    name = 'adherents'
+    verbose_name = _('adherents')
diff --git a/adherents/forms.py b/adherents/forms.py
new file mode 100644
index 0000000000000000000000000000000000000000..a387d73cb5ff147300bad4505adc68c61f2babf1
--- /dev/null
+++ b/adherents/forms.py
@@ -0,0 +1,17 @@
+# -*- mode: python; coding: utf-8 -*-
+# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from django.contrib.auth.forms import UserChangeForm
+
+
+class CustomUserChangeForm(UserChangeForm):
+    """
+    Make first name, last name and email required
+    in the default Django Auth User model
+    """
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.fields['first_name'].required = True
+        self.fields['last_name'].required = True
+        self.fields['email'].required = True
diff --git a/adherents/models.py b/adherents/models.py
index 850e91daa8ba0d69ca0a6641b35a54c42797aeb4..41277c57f562d62b569645850366efb365a82a3f 100644
--- a/adherents/models.py
+++ b/adherents/models.py
@@ -1,5 +1,5 @@
 # -*- mode: python; coding: utf-8 -*-
-# Copyright (C) 2016-2019 by BDE
+# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
 # SPDX-License-Identifier: GPL-3.0-or-later
 
 from django.conf import settings