diff --git a/roles/keycloak/templates/keycloak.conf.j2 b/roles/keycloak/templates/keycloak.conf.j2
index 88add918092e3e354652c24fc1e36bfb355332b6..01d680f70472e03adc7ccbef20efc9b9f410c829 100644
--- a/roles/keycloak/templates/keycloak.conf.j2
+++ b/roles/keycloak/templates/keycloak.conf.j2
@@ -15,3 +15,5 @@ db-url=jdbc:postgresql://localhost/{{ keycloak_db_name }}
 # temporarily re-enable calling the logout endpoint with a 'redirect_uri' param
 # https://www.keycloak.org/2022/04/keycloak-1800-released#_openid_connect_logout
 spi-login-protocol-openid-connect-legacy-logout-redirect-uri=true
+
+features=declarative-user-profile
diff --git a/tf-stage2/keycloak.tf b/tf-stage2/keycloak.tf
index 87196709f136be184c99a664b6fc757b65f38196..f930c3c5d2a712480e06e31ff5e9398b85e090f0 100644
--- a/tf-stage2/keycloak.tf
+++ b/tf-stage2/keycloak.tf
@@ -128,6 +128,129 @@ resource "keycloak_realm" "archlinux" {
       failure_reset_time_seconds       = 43200
     }
   }
+
+  attributes = {
+    userProfileEnabled = true
+  }
+}
+
+resource "keycloak_realm_user_profile" "archlinux" {
+  realm_id = keycloak_realm.archlinux.id
+
+  attribute {
+    name         = "username"
+    display_name = "$${username}"
+
+    permissions {
+      view = ["admin", "user"]
+      edit = ["admin", "user"]
+    }
+
+    validator {
+      name = "length"
+      config = {
+        min = 3
+        max = 255
+      }
+    }
+
+    validator {
+      name = "username-prohibited-characters"
+    }
+
+    validator {
+      name = "up-username-not-idn-homograph"
+    }
+  }
+
+  attribute {
+    name         = "email"
+    display_name = "$${email}"
+
+    required_for_roles = ["user"]
+
+    permissions {
+      view = ["admin", "user"]
+      edit = ["admin", "user"]
+    }
+
+    validator {
+      name = "email"
+    }
+
+    validator {
+      name = "length"
+      config = {
+        max = 255
+      }
+    }
+  }
+
+  attribute {
+    name         = "firstName"
+    display_name = "$${firstName}"
+
+    required_for_roles = ["user"]
+
+    permissions {
+      view = ["admin", "user"]
+      edit = ["admin", "user"]
+    }
+
+    validator {
+      name = "length"
+      config = {
+        max = 255
+      }
+    }
+
+    validator {
+      name = "person-name-prohibited-characters"
+    }
+  }
+
+  attribute {
+    name         = "lastName"
+    display_name = "$${lastName}"
+
+    required_for_roles = ["user"]
+
+    permissions {
+      view = ["admin", "user"]
+      edit = ["admin", "user"]
+    }
+
+    validator {
+      name = "length"
+      config = {
+        max = 255
+      }
+    }
+
+    validator {
+      name = "person-name-prohibited-characters"
+    }
+  }
+
+  attribute {
+    name         = "archQuestion"
+    display_name = "What is the output of: LC_ALL=C pacman -V|tail -n3|base32|head -1 ?"
+
+    required_for_roles = ["user"]
+
+    permissions {
+      view = ["admin", "user"]
+      edit = ["admin", "user"]
+    }
+
+    validator {
+      name = "pattern"
+      config = {
+        pattern       = "^EAQCAIBAEAQCAIBAEAQCAIBAEAQCAIBAEAQCAVDINFZSA4DSN5TXEYLNEBWWC6JAMJSSAZTSMVSW$"
+        error-message = "Nope"
+      }
+    }
+  }
 }
 
 resource "keycloak_required_action" "custom-terms-and-conditions" {
@@ -187,6 +310,15 @@ resource "keycloak_required_action" "webauthn_register" {
   priority = 60
 }
 
+resource "keycloak_required_action" "verify_profile" {
+  realm_id       = "archlinux"
+  alias          = "VERIFY_PROFILE"
+  default_action = true
+  enabled        = true
+  name           = "Verify Profile"
+  priority       = 70
+}
+
 resource "keycloak_realm_events" "realm_events" {
   realm_id = "archlinux"