</code></pre></div></details><p>Below you will find sections like <ahref=#core><code>core</code></a>, <ahref=#backend><code>backend</code></a>, <ahref=#advanced><code>advanced</code></a>, <ahref=#database><code>database</code></a>, <ahref=#statistics><code>statistics</code></a>, <ahref=#mail><code>mail</code></a>, <ahref=#auth><code>auth</code></a>, <ahref=#web><code>web</code></a> and <ahref=#webhook><code>webhook</code></a>.<br> Each section describes the individual configuration keys, their default values, and a brief explanation of their purpose.</p><hr><h2id=core>Core</h2><p>These are the primary configuration options that control fundamental WireGuard Portal behavior. More advanced options are found in the subsequent <code>Advanced</code> section.</p><h3id=admin_user><code>admin_user</code></h3><ul><li><strong>Default:</strong><code>admin@wgportal.local</code></li><li><strong>Environment Variable:</strong><code>WG_PORTAL_CORE_ADMIN_USER</code></li><li><strong>Description:</strong> The administrator user. This user will be created as a default admin if it does not yet exist.</li></ul><h3id=admin_password><code>admin_password</code></h3><ul><li><strong>Default:</strong><code>wgportal-default</code></li><li><strong>Environment Variable:</strong><code>WG_PORTAL_CORE_ADMIN_PASSWORD</code></li><li><strong>Description:</strong> The administrator password. The default password should be changed immediately!</li><li><strong>Important:</strong> The password should be strong and secure. The minimum password length is specified in <ahref=#min_password_length>auth.min_password_length</a>. By default, it is 16 characters.</li></ul><h3id=disable_admin_user><code>disable_admin_user</code></h3><ul><li><strong>Default:</strong><code>false</code></li><li><strong>Environment Variable:</strong><code>WG_PORTAL_CORE_DISABLE_ADMIN_USER</code></li><li><strong>Description:</strong> If <code>true</code>, no admin user is created. This is useful if you plan to manage users exclusively through external authentication providers such as LDAP or OAuth.</li></ul><h3id=admin_api_token><code>admin_api_token</code></h3><ul><li><strong>Default:</strong><em>(empty)</em></li><li><strong>Environment Variable:</strong><code>WG_PORTAL_CORE_ADMIN_API_TOKEN</code></li><li><strong>Description:</strong> An API token for the admin user. If a token is provided, the REST API can be accessed using this token. If empty, the API is initially disabled for the admin user.</li></ul><h3id=editable_keys><code>editable_keys</code></h3><ul><li><strong>Default:</strong><code>true</code></li><li><strong>Environment Variable:</strong><code>WG_PORTAL_CORE_EDITABLE_KEYS</code></li><li><strong>Description:</strong> Allow editing of WireGuard key-pairs directly in the UI.</li></ul><h3id=create_default_peer-deprecated><code>create_default_peer</code> (deprecated)</h3><ul><li><strong>Default:</strong><code>false</code></li><li><strong>Environment Variable:</strong><code>WG_PORTAL_CORE_CREATE_DEFAULT_PEER</code></li><li><strong>Description:</strong><strong>DEPRECATED</strong> in favor of <ahref=#create_default_peer_on_login>create_default_peer_on_login</a>. If set to <code>true</code>, this option is equivalent to enabling <code>create_default_peer_on_login</code>. It will be removed in a future release (2.4).</li></ul><h3id=create_default_peer_on_creation-deprecated><code>create_default_peer_on_creation</code> (deprecated)</h3><ul><li><strong>Default:</strong><code>false</code></li><li><strong>Environment Variable:</strong><code>WG_PORTAL_CORE_CREATE_DEFAULT_PEER_ON_CREATION</code></li><li><strong>Description:</strong><strong>DEPRECATED</strong> in favor of <ahref=#create_default_peer_on_user_creation>create_default_peer_on_user_creation</a> and <ahref=#create_default_peer_on_interface_creation>create_default_peer_on_interface_creation</a>. If set to <code>true</code>, both of those options are enabled. It will be removed in a future release (2.4).</li></ul><h3id=create_default_peer_on_login><co
</code></pre></div></li></ul><h3id=encryption_passphrase><code>encryption_passphrase</code></h3><ul><li><strong>Default:</strong><em>(empty)</em></li><li><strong>Environment Variable:</strong><code>WG_PORTAL_DATABASE_ENCRYPTION_PASSPHRASE</code></li><li><strong>Description:</strong> Passphrase for encrypting sensitive values such as private keys in the database. Encryption is only applied if this passphrase is set. <strong>Important:</strong> Once you enable encryption by setting this passphrase, you cannot disable it or change it afterward. New or updated records will be encrypted; existing data remains in plaintext until it’s next modified.</li></ul><hr><h2id=statistics>Statistics</h2><p>Controls how WireGuard Portal collects and reports usage statistics, including ping checks and Prometheus metrics.</p><h3id=use_ping_checks><code>use_ping_checks</code></h3><ul><li><strong>Default:</strong><code>true</code></li><li><strong>Environment Variable:</strong><code>WG_PORTAL_STATISTICS_USE_PING_CHECKS</code></li><li><strong>Description:</strong> Enable periodic ping checks to verify that peers remain responsive.</li></ul><h3id=ping_check_workers><code>ping_check_workers</code></h3><ul><li><strong>Default:</strong><code>10</code></li><li><strong>Environment Variable:</strong><code>WG_PORTAL_STATISTICS_PING_CHECK_WORKERS</code></li><li><strong>Description:</strong> Number of parallel worker processes for ping checks.</li></ul><h3id=ping_unprivileged><code>ping_unprivileged</code></h3><ul><li><strong>Default:</strong><code>false</code></li><li><strong>Environment Variable:</strong><code>WG_PORTAL_STATISTICS_PING_UNPRIVILEGED</code></li><li><strong>Description:</strong> If <code>false</code>, ping checks run without root privileges. This is currently considered BETA.</li></ul><h3id=ping_check_interval><code>ping_check_interval</code></h3><ul><li><strong>Default:</strong><code>1m</code></li><li><strong>Environment Variable:</strong><code>WG_PORTAL_STATISTICS_PING_CHECK_INTERVAL</code></li><li><strong>Description:</strong> Interval between consecutive ping checks for all peers. Format uses <code>s</code>, <code>m</code>, <code>h</code>, <code>d</code> for seconds, minutes, hours, days, see <ahref=https://golang.org/pkg/time/#ParseDuration>time.ParseDuration</a>.</li></ul><h3id=data_collection_interval><code>data_collection_interval</code></h3><ul><li><strong>Default:</strong><code>1m</code></li><li><strong>Environment Variable:</strong><code>WG_PORTAL_STATISTICS_DATA_COLLECTION_INTERVAL</code></li><li><strong>Description:</strong> Interval between data collection cycles (bytes sent/received, handshake times, etc.). Format uses <code>s</code>, <code>m</code>, <code>h</code>, <code>d</code> for seconds, minutes, hours, days, see <ahref=https://golang.org/pkg/time/#ParseDuration>time.ParseDuration</a>.</li></ul><h3id=collect_interface_data><code>collect_interface_data</code></h3><ul><li><strong>Default:</strong><code>true</code></li><li><strong>Environment Variable:</strong><code>WG_PORTAL_STATISTICS_COLLECT_INTERFACE_DATA</code></li><li><strong>Description:</strong> If <code>true</code>, collects interface-level data (bytes in/out) for monitoring and statistics.</li></ul><h3id=collect_peer_data><code>collect_peer_data</code></h3><ul><li><strong>Default:</strong><code>true</code></li><li><strong>Environment Variable:</strong><code>WG_PORTAL_STATISTICS_COLLECT_PEER_DATA</code></li><li><strong>Description:</strong> If <code>true</code>, collects peer-level data (bytes, last handshake, endpoint, etc.).</li></ul><h3id=collect_audit_data><code>collect_audit_data</code></h3><ul><li><strong>Default:</strong><code>true</code></li><li><strong>Environment Variable:</strong><code>WG_PORTAL_STATISTICS_COLLECT_AUDIT_DATA</code></li><li><strong>Description:</strong> If <code>true</code>, logs certain portal events (such as user logins) to the database.</li></ul><h3id=listening_address><code>listening_address</code></h3><ul><li><strong>Default:</strong><c
</code></pre></div></li><li><strong>Important</strong>: The <code>login_filter</code> must always be a valid LDAP filter. It should at most return one user. If the filter returns multiple or no users, the login will fail.</li></ul><h4id=interface_filter><code>interface_filter</code></h4><ul><li><strong>Default:</strong><em>(empty)</em></li><li><strong>Description:</strong> A map of LDAP filters to restrict access to specific WireGuard interfaces. The map keys are the interface identifiers (e.g., <code>wg0</code>), and the values are LDAP filters. Only users matching the filter will be allowed to provision peers for the respective interface. For example: <divclass=highlight><pre><span></span><code><spanclass=nt>interface_filter</span><spanclass=p>:</span>
</code></pre></div></li></ul><h4id=admin_group><code>admin_group</code></h4><ul><li><strong>Default:</strong><em>(empty)</em></li><li><strong>Description:</strong> A specific LDAP group whose members are considered administrators in WireGuard Portal. For example: <divclass=highlight><pre><span></span><code>CN=WireGuardAdmins,OU=Some-OU,DC=YOURDOMAIN,DC=LOCAL
</code></pre></div></li></ul><h4id=sync_interval><code>sync_interval</code></h4><ul><li><strong>Default:</strong><em>(empty)</em></li><li><strong>Description:</strong> How frequently (in duration, e.g. <code>30m</code>) to synchronize users from LDAP. Empty or <code>0</code> disables sync. Format uses <code>s</code>, <code>m</code>, <code>h</code>, <code>d</code> for seconds, minutes, hours, days, see <ahref=https://golang.org/pkg/time/#ParseDuration>time.ParseDuration</a>. Only users that match the <code>sync_filter</code> are synchronized, if <code>disable_missing</code> is <code>true</code>, users not found in LDAP are disabled.</li></ul><h4id=sync_filter><code>sync_filter</code></h4><ul><li><strong>Default:</strong><em>(empty)</em></li><li><strong>Description:</strong> An LDAP filter to select which users get synchronized into WireGuard Portal. For example: <divclass=highlight><pre><span></span><code>(&(objectClass=organizationalPerson)(!userAccountControl:1.2.840.113556.1.4.803:=2)(mail=*))
</code></pre></div></li></ul><h4id=sync_log_user_info><code>sync_log_user_info</code></h4><ul><li><strong>Default:</strong><code>false</code></li><li><strong>Description:</strong> If <code>true</code>, logs LDAP user data at the trace level during synchronization.</li></ul><h4id=disable_missing><code>disable_missing</code></h4><ul><li><strong>Default:</strong><code>false</code></li><li><strong>Description:</strong> If <code>true</code>, any user <strong>not</strong> found in LDAP (during sync) is disabled in WireGuard Portal.</li><li><strong>Important</strong>: As a safeguard, a synchronization that returns no usable user identifiers at all disables nobody. LDAP cannot distinguish a directory that legitimately holds no matching users from a wrong <code>base_dn</code>, a <code>sync_filter</code> whose group was renamed, a replica that is reachable but not yet populated, or a bind account that has lost read access — all of them answer with success and zero entries. Disabling every user on that signal would lock administrators out of a portal they may only reach over the VPN, so the sync logs an error and skips the disable step instead. If you intend to empty a group, keep one account matching <code>sync_filter</code>: the remaining users are then disabled normally, and the account doubles as a canary, since its disappearance means the query itself is broken.</li></ul><h4id=auto_re_enable><code>auto_re_enable</code></h4><ul><li><strong>Default:</strong><code>false</code></li><li><strong>Description:</strong> If <code>true</code>, users that where disabled because they were missing (see <code>disable_missing</code>) will be re-enabled once they are found again.</li></ul><h4id=registration_enabled_2><code>registration_enabled</code></h4><ul><li><strong>Default:</strong><code>false</code></li><li><strong>Description:</strong> If <code>true</code>, new user accounts are created in WireGuard Portal upon first login.</li></ul><h4id=log_user_info_2><code>log_user_info</code></h4><ul><li><strong>Default:</strong><code>false</code></li><li><strong>Description:</strong> If <code>true</code>, logs LDAP user data at the trace level upon login.</li></ul><hr><h3id=webauthn-passkeys>WebAuthn (Passkeys)</h3><p>The <code>webauthn</code> section contains configuration options for WebAuthn authentication (passkeys).</p><h4id=enabled><code>enabled</code></h4><ul><li><strong>Default:</strong><code>true</code></li><li><strong>Environment Variable:</strong><code>WG_PORTAL_AUTH_WEBAUTHN_ENABLED</code></li><li><strong>Description:</strong> If <code>true</code>, Passkey authentication is enabled. If <code>false</code>, WebAuthn is disabled. Users are encouraged to use Passkeys for secure authentication instead of passwords. If a passkey is registered, the password login is still available as a fallback. Ensure that the password is strong and secure.</li></ul><h2id=web>Web</h2><p>The web section contains configuration options for the web server, including the listening address, session management, and CSRF protection. It is important to specify a valid <code>external_url</code> for the web server, especially if you are using a reverse proxy. Without a valid <code>external_url</code>, the login process may fail due to CSRF protection.</p><h3id=listening_address_1><code>listening_address</code></h3><ul><li><strong>Default:</strong><code>:8888</code></li><li><strong>Environment Variable:</strong><code>WG_PORTAL_WEB_LISTENING_ADDRESS</code></li><li><strong>Description:</strong> The listening address and port for the web server (e.g., <code>:8888</code> to bind on all interfaces or <code>127.0.0.1:8888</code> to bind only on the loopback interface). Ensure that access to WireGuard Portal is protected against unauthorized access, especially if binding to all interfaces.</li></ul><h3id=external_url><code>external_url</code></h3><ul><li><strong>Default:</strong><code>http://localhost:8888</code></li><li><strong>Environment Variable:</strong><code>WG_PORTAL_WEB_EXTERNAL_URL</code></li><l