diff --git a/docs/user/site.rst b/docs/user/site.rst
index 93eefc24324d5a52edb3eeabc3b36845f2751226..b066f8c2f507d8d0414c86f120111928cf480f66 100644
--- a/docs/user/site.rst
+++ b/docs/user/site.rst
@@ -366,6 +366,38 @@ autoupdater \: package
     All configured mirrors must be reachable from the nodes via IPv6. If you don't want to set an IPv6 address
     explicitly, but use a hostname (which is recommended), see also the :ref:`FAQ <faq-dns>`.
 
+config_mode \: optional
+    Additional configuration for the configuration web interface. All values are
+    optional.
+
+    By default, no altitude fields are shown by the *gluon-config-mode-geo-location*
+    package. If *geo_location.show_altitude* is set to *true*, the *gluon-config-mode:altitude-label*
+    and *gluon-config-mode:altitude-help* strings must be provided in the site i18n
+    data as well.
+
+    The *owner.optional* option can be set to *false* to make the contact
+    information field mandatory.
+
+    The remote login page only shows SSH key configuration by default. A
+    password form can be displayed by setting *remote_login.show_password_form*
+    to true; in this case, *remote_login.min_password_length* defines the
+    minimum password length.
+    ::
+
+        config_mode = {
+          geo_location = {
+            show_altitude = true,
+          },
+          owner = {
+            optional = false,
+          },
+          remote_login = {
+            show_password_form = true,
+            min_password_length = 10,
+          },
+        },
+
+
 roles \: optional
     Optional role definitions. Nodes will announce their role inside the mesh.
     This will allow in the backend to distinguish between normal, backbone and
diff --git a/package/gluon-config-mode-contact-info/check_site.lua b/package/gluon-config-mode-contact-info/check_site.lua
index 1e20bcb8f05e0befc415952274777b418353b79b..7dd39e38db504ef6c7ad257594f02522b326671d 100644
--- a/package/gluon-config-mode-contact-info/check_site.lua
+++ b/package/gluon-config-mode-contact-info/check_site.lua
@@ -1 +1 @@
-need_boolean(in_site({'config_mode', 'owner', 'obligatory'}), false)
+need_boolean(in_site({'config_mode', 'owner', 'optional'}), false)
diff --git a/package/gluon-config-mode-contact-info/luasrc/lib/gluon/config-mode/wizard/0500-contact-info.lua b/package/gluon-config-mode-contact-info/luasrc/lib/gluon/config-mode/wizard/0500-contact-info.lua
index 8314dd7ec6fbd9a7b39adc9a2f4819bee3ec95e2..3afff6b4bf3c7dd495d2dfc9aaab818307f10440 100644
--- a/package/gluon-config-mode-contact-info/luasrc/lib/gluon/config-mode/wizard/0500-contact-info.lua
+++ b/package/gluon-config-mode-contact-info/luasrc/lib/gluon/config-mode/wizard/0500-contact-info.lua
@@ -14,7 +14,7 @@ return function(form, uci)
 
 	local o = s:option(Value, "contact", pkg_i18n.translate("Contact info"), pkg_i18n.translate("e.g. E-mail or phone number"))
 	o.default = uci:get("gluon-node-info", owner, "contact")
-	o.optional = not site.config_mode.owner.obligatory(false)
+	o.optional = site.config_mode.owner.optional(true)
 	-- without a minimal length, an empty string will be accepted even with "optional = false"
 	o.datatype = "minlength(1)"
 	function o:write(data)