From f2e79bad1d24a6238bde38131c83c7c24d6585c8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 26 Jun 2025 18:18:31 +0000 Subject: [PATCH] Deployed f0be66a to master with MkDocs 1.6.1 and mike 2.1.3 --- master/documentation/configuration/overview/index.html | 5 +++-- master/search/search_index.json | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/master/documentation/configuration/overview/index.html b/master/documentation/configuration/overview/index.html index 8dc72af..0d5dc3d 100644 --- a/master/documentation/configuration/overview/index.html +++ b/master/documentation/configuration/overview/index.html @@ -1,4 +1,4 @@ - Overview - WireGuard Portal
Skip to content

Overview

This page provides an overview of all available configuration options for WireGuard Portal.

You can supply these configurations in a YAML file when starting the Portal. The path of the configuration file defaults to config/config.yaml (or config/config.yml) in the working directory of the executable.
It is possible to override the configuration filepath using the environment variable WG_PORTAL_CONFIG. For example: WG_PORTAL_CONFIG=/etc/wg-portal/config.yaml ./wg-portal.
Also, environment variable substitution in the config file is supported. Refer to the syntax.

Configuration examples are available on the Examples page.

Default configuration
core:
+ Overview - WireGuard Portal      

Overview

This page provides an overview of all available configuration options for WireGuard Portal.

You can supply these configurations in a YAML file when starting the Portal. The path of the configuration file defaults to config/config.yaml (or config/config.yml) in the working directory of the executable.
It is possible to override the configuration filepath using the environment variable WG_PORTAL_CONFIG. For example: WG_PORTAL_CONFIG=/etc/wg-portal/config.yaml ./wg-portal.
Also, environment variable substitution in the config file is supported. Refer to the syntax.

Configuration examples are available on the Examples page.

Default configuration
core:
   admin_user: admin@wgportal.local
   admin_password: wgportal-default
   admin_api_token: ""
@@ -24,6 +24,7 @@
   rule_prio_offset: 20000
   route_table_offset: 20000
   api_admin_only: true
+  limit_additional_user_peers: 0
 
 database:
   debug: false
@@ -79,7 +80,7 @@
   url: ""
   authentication: ""
   timeout: 10s
-

Below you will find sections like core, advanced, database, statistics, mail, auth, web and webhook.
Each section describes the individual configuration keys, their default values, and a brief explanation of their purpose.


Core

These are the primary configuration options that control fundamental WireGuard Portal behavior. More advanced options are found in the subsequent Advanced section.

admin_user

  • Default: admin@wgportal.local
  • Description: The administrator user. This user will be created as a default admin if it does not yet exist.

admin_password

  • Default: wgportal-default
  • Description: The administrator password. The default password should be changed immediately!
  • Important: The password should be strong and secure. The minimum password length is specified in auth.min_password_length. By default, it is 16 characters.

admin_api_token

  • Default: (empty)
  • Description: 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.

editable_keys

  • Default: true
  • Description: Allow editing of WireGuard key-pairs directly in the UI.

create_default_peer

  • Default: false
  • Description: If a user logs in for the first time with no existing peers, automatically create a new WireGuard peer for all server interfaces.

create_default_peer_on_creation

  • Default: false
  • Description: If an LDAP user is created (e.g., through LDAP sync) and has no peers, automatically create a new WireGuard peer for all server interfaces.

re_enable_peer_after_user_enable

  • Default: true
  • Description: Re-enable all peers that were previously disabled if the associated user is re-enabled.

delete_peer_after_user_deleted

  • Default: false
  • Description: If a user is deleted, remove all linked peers. Otherwise, peers remain but are disabled.

self_provisioning_allowed

  • Default: false
  • Description: Allow registered (non-admin) users to self-provision peers from their profile page.

import_existing

  • Default: true
  • Description: On startup, import existing WireGuard interfaces and peers into WireGuard Portal.

restore_state

  • Default: true
  • Description: Restore the WireGuard interface states (up/down) that existed before WireGuard Portal started.

Advanced

Additional or more specialized configuration options for logging and interface creation details.

log_level

  • Default: info
  • Description: The log level used by the application. Valid options are: trace, debug, info, warn, error.

log_pretty

  • Default: false
  • Description: If true, log messages are colorized and formatted for readability (pretty-print).

log_json

  • Default: false
  • Description: If true, log messages are structured in JSON format.

start_listen_port

  • Default: 51820
  • Description: The first port to use when automatically creating new WireGuard interfaces.

start_cidr_v4

  • Default: 10.11.12.0/24
  • Description: The initial IPv4 subnet to use when automatically creating new WireGuard interfaces.

start_cidr_v6

  • Default: fdfd:d3ad:c0de:1234::0/64
  • Description: The initial IPv6 subnet to use when automatically creating new WireGuard interfaces.

use_ip_v6

  • Default: true
  • Description: Enable or disable IPv6 support.

config_storage_path

  • Default: (empty)
  • Description: Path to a directory where wg-quick style configuration files will be stored (if you need local filesystem configs).

expiry_check_interval

  • Default: 15m
  • Description: Interval after which existing peers are checked if they are expired. Format uses s, m, h, d for seconds, minutes, hours, days, see time.ParseDuration.

rule_prio_offset

  • Default: 20000
  • Description: Offset for IP route rule priorities when configuring routing.

route_table_offset

  • Default: 20000
  • Description: Offset for IP route table IDs when configuring routing.

api_admin_only

  • Default: true
  • Description: If true, the public REST API is accessible only to admin users. The API docs live at /api/v1/doc.html.

Database

Configuration for the underlying database used by WireGuard Portal. Supported databases include SQLite, MySQL, Microsoft SQL Server, and Postgres.

If sensitive values (like private keys) should be stored in an encrypted format, set the encryption_passphrase option.

debug

  • Default: false
  • Description: If true, logs all database statements (verbose).

slow_query_threshold

  • Default: "0"
  • Description: A time threshold (e.g., 100ms) above which queries are considered slow and logged as warnings. If zero, slow query logging is disabled. Format uses s, ms for seconds, milliseconds, see time.ParseDuration. The value must be a string.

type

  • Default: sqlite
  • Description: The database type. Valid options: sqlite, mssql, mysql, postgres.

dsn

  • Default: data/sqlite.db
  • Description: The Data Source Name (DSN) for connecting to the database.
    For example:
    user:pass@tcp(1.2.3.4:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local
    +

Below you will find sections like core, advanced, database, statistics, mail, auth, web and webhook.
Each section describes the individual configuration keys, their default values, and a brief explanation of their purpose.


Core

These are the primary configuration options that control fundamental WireGuard Portal behavior. More advanced options are found in the subsequent Advanced section.

admin_user

  • Default: admin@wgportal.local
  • Description: The administrator user. This user will be created as a default admin if it does not yet exist.

admin_password

  • Default: wgportal-default
  • Description: The administrator password. The default password should be changed immediately!
  • Important: The password should be strong and secure. The minimum password length is specified in auth.min_password_length. By default, it is 16 characters.

admin_api_token

  • Default: (empty)
  • Description: 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.

editable_keys

  • Default: true
  • Description: Allow editing of WireGuard key-pairs directly in the UI.

create_default_peer

  • Default: false
  • Description: If a user logs in for the first time with no existing peers, automatically create a new WireGuard peer for all server interfaces.

create_default_peer_on_creation

  • Default: false
  • Description: If an LDAP user is created (e.g., through LDAP sync) and has no peers, automatically create a new WireGuard peer for all server interfaces.

re_enable_peer_after_user_enable

  • Default: true
  • Description: Re-enable all peers that were previously disabled if the associated user is re-enabled.

delete_peer_after_user_deleted

  • Default: false
  • Description: If a user is deleted, remove all linked peers. Otherwise, peers remain but are disabled.

self_provisioning_allowed

  • Default: false
  • Description: Allow registered (non-admin) users to self-provision peers from their profile page.

import_existing

  • Default: true
  • Description: On startup, import existing WireGuard interfaces and peers into WireGuard Portal.

restore_state

  • Default: true
  • Description: Restore the WireGuard interface states (up/down) that existed before WireGuard Portal started.

Advanced

Additional or more specialized configuration options for logging and interface creation details.

log_level

  • Default: info
  • Description: The log level used by the application. Valid options are: trace, debug, info, warn, error.

log_pretty

  • Default: false
  • Description: If true, log messages are colorized and formatted for readability (pretty-print).

log_json

  • Default: false
  • Description: If true, log messages are structured in JSON format.

start_listen_port

  • Default: 51820
  • Description: The first port to use when automatically creating new WireGuard interfaces.

start_cidr_v4

  • Default: 10.11.12.0/24
  • Description: The initial IPv4 subnet to use when automatically creating new WireGuard interfaces.

start_cidr_v6

  • Default: fdfd:d3ad:c0de:1234::0/64
  • Description: The initial IPv6 subnet to use when automatically creating new WireGuard interfaces.

use_ip_v6

  • Default: true
  • Description: Enable or disable IPv6 support.

config_storage_path

  • Default: (empty)
  • Description: Path to a directory where wg-quick style configuration files will be stored (if you need local filesystem configs).

expiry_check_interval

  • Default: 15m
  • Description: Interval after which existing peers are checked if they are expired. Format uses s, m, h, d for seconds, minutes, hours, days, see time.ParseDuration.

rule_prio_offset

  • Default: 20000
  • Description: Offset for IP route rule priorities when configuring routing.

route_table_offset

  • Default: 20000
  • Description: Offset for IP route table IDs when configuring routing.

api_admin_only

  • Default: true
  • Description: If true, the public REST API is accessible only to admin users. The API docs live at /api/v1/doc.html.

limit_additional_user_peers

  • Default: 0
  • Description: Limit additional peers a normal user can create. 0 means unlimited.

Database

Configuration for the underlying database used by WireGuard Portal. Supported databases include SQLite, MySQL, Microsoft SQL Server, and Postgres.

If sensitive values (like private keys) should be stored in an encrypted format, set the encryption_passphrase option.

debug

  • Default: false
  • Description: If true, logs all database statements (verbose).

slow_query_threshold

  • Default: "0"
  • Description: A time threshold (e.g., 100ms) above which queries are considered slow and logged as warnings. If zero, slow query logging is disabled. Format uses s, ms for seconds, milliseconds, see time.ParseDuration. The value must be a string.

type

  • Default: sqlite
  • Description: The database type. Valid options: sqlite, mssql, mysql, postgres.

dsn

  • Default: data/sqlite.db
  • Description: The Data Source Name (DSN) for connecting to the database.
    For example:
    user:pass@tcp(1.2.3.4:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local
     

encryption_passphrase

  • Default: (empty)
  • Description: Passphrase for encrypting sensitive values such as private keys in the database. Encryption is only applied if this passphrase is set. Important: 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.

Statistics

Controls how WireGuard Portal collects and reports usage statistics, including ping checks and Prometheus metrics.

use_ping_checks

  • Default: true
  • Description: Enable periodic ping checks to verify that peers remain responsive.

ping_check_workers

  • Default: 10
  • Description: Number of parallel worker processes for ping checks.

ping_unprivileged

  • Default: false
  • Description: If false, ping checks run without root privileges. This is currently considered BETA.

ping_check_interval

  • Default: 1m
  • Description: Interval between consecutive ping checks for all peers. Format uses s, m, h, d for seconds, minutes, hours, days, see time.ParseDuration.

data_collection_interval

  • Default: 1m
  • Description: Interval between data collection cycles (bytes sent/received, handshake times, etc.). Format uses s, m, h, d for seconds, minutes, hours, days, see time.ParseDuration.

collect_interface_data

  • Default: true
  • Description: If true, collects interface-level data (bytes in/out) for monitoring and statistics.

collect_peer_data

  • Default: true
  • Description: If true, collects peer-level data (bytes, last handshake, endpoint, etc.).

collect_audit_data

  • Default: true
  • Description: If true, logs certain portal events (such as user logins) to the database.

listening_address

  • Default: :8787
  • Description: Address and port for the integrated Prometheus metric server (e.g., :8787 or 127.0.0.1:8787).

Mail

Options for configuring email notifications or sending peer configurations via email.

host

  • Default: 127.0.0.1
  • Description: Hostname or IP of the SMTP server.

port

  • Default: 25
  • Description: Port number for the SMTP server.

encryption

  • Default: none
  • Description: SMTP encryption type. Valid values: none, tls, starttls.

cert_validation

  • Default: true
  • Description: If true, validate the SMTP server certificate (relevant if encryption = tls).

username

  • Default: (empty)
  • Description: Optional SMTP username for authentication.

password

  • Default: (empty)
  • Description: Optional SMTP password for authentication.

auth_type

  • Default: plain
  • Description: SMTP authentication type. Valid values: plain, login, crammd5.

from

  • Default: Wireguard Portal <noreply@wireguard.local>
  • Description: The default "From" address when sending emails.
  • Default: false
  • Description: If true, emails only contain a link to WireGuard Portal, rather than attaching the full configuration.

Auth

WireGuard Portal supports multiple authentication strategies, including OpenID Connect (oidc), OAuth (oauth), Passkeys (webauthn) and LDAP (ldap). Each can have multiple providers configured. Below are the relevant keys.

Some core authentication options are shared across all providers, while others are specific to each provider type.

min_password_length

  • Default: 16
  • Description: Minimum password length for local authentication. This is not enforced for LDAP authentication. The default admin password strength is also enforced by this setting.
  • Important: The password should be strong and secure. It is recommended to use a password with at least 16 characters, including uppercase and lowercase letters, numbers, and special characters.

OIDC

The oidc array contains a list of OpenID Connect providers. Below are the properties for each OIDC provider entry inside auth.oidc:

provider_name

  • Default: (empty)
  • Description: A unique name for this provider. Must not conflict with other providers.

display_name

  • Default: (empty)
  • Description: A user-friendly name shown on the login page (e.g., "Login with Google").

base_url

  • Default: (empty)
  • Description: The OIDC provider’s base URL (e.g., https://accounts.google.com).

client_id

  • Default: (empty)
  • Description: The OAuth client ID from the OIDC provider.

client_secret

  • Default: (empty)
  • Description: The OAuth client secret from the OIDC provider.

extra_scopes

  • Default: (empty)
  • Description: A list of additional OIDC scopes (e.g., profile, email).

allowed_domains

  • Default: (empty)
  • Description: A list of allowlisted domains. Only users with email addresses in these domains can log in or register. This is useful for restricting access to specific organizations or groups.

field_map

  • Default: (empty)
  • Description: Maps OIDC claims to WireGuard Portal user fields.
  • Available fields: user_identifier, email, firstname, lastname, phone, department, is_admin, user_groups.

    Field Typical OIDC Claim Explanation
    user_identifier sub or preferred_username A unique identifier for the user. Often the OIDC sub claim is used because it’s guaranteed to be unique for the user within the IdP. Some providers also support preferred_username if it’s unique.
    email email The user’s email address as provided by the IdP. Not always verified, depending on IdP settings.
    firstname given_name The user’s first name, typically provided by the IdP in the given_name claim.
    lastname family_name The user’s last (family) name, typically provided by the IdP in the family_name claim.
    phone phone_number The user’s phone number. This may require additional scopes/permissions from the IdP to access.
    department Custom claim (e.g., department) If the IdP can provide organizational data, it may store it in a custom claim. Adjust accordingly (e.g., department, org, or another attribute).
    is_admin Custom claim or derived role If the IdP returns a role or admin flag, you can map that to is_admin. Often this is managed through custom claims or group membership.
    user_groups groups or another custom claim A list of group memberships for the user. Some IdPs provide groups out of the box; others require custom claims or directory lookups.

admin_mapping

  • Default: (empty)
  • Description: WgPortal can grant a user admin rights by matching the value of the is_admin claim against a regular expression. Alternatively, a regular expression can be used to check if a user is member of a specific group listed in the user_group claim. The regular expressions are defined in admin_value_regex and admin_group_regex.
    • admin_value_regex: A regular expression to match the is_admin claim. By default, this expression matches the string "true" (^true$).
    • admin_group_regex: A regular expression to match the user_groups claim. Each entry in the user_groups claim is checked against this regex.

registration_enabled

  • Default: (empty)
  • Description: If true, a new user will be created in WireGuard Portal if not already present.

log_user_info

  • Default: (empty)
  • Description: If true, OIDC user data is logged at the trace level upon login (for debugging).

OAuth

The oauth array contains a list of plain OAuth2 providers. Below are the properties for each OAuth provider entry inside auth.oauth:

provider_name

  • Default: (empty)
  • Description: A unique name for this provider. Must not conflict with other providers.

display_name

  • Default: (empty)
  • Description: A user-friendly name shown on the login page.

client_id

  • Default: (empty)
  • Description: The OAuth client ID for the provider.

client_secret

  • Default: (empty)
  • Description: The OAuth client secret for the provider.

auth_url

  • Default: (empty)
  • Description: URL of the authentication endpoint.

token_url

  • Default: (empty)
  • Description: URL of the token endpoint.

user_info_url

  • Default: (empty)
  • Description: URL of the user information endpoint.

scopes

  • Default: (empty)
  • Description: A list of OAuth scopes.

allowed_domains

  • Default: (empty)
  • Description: A list of allowlisted domains. Only users with email addresses in these domains can log in or register. This is useful for restricting access to specific organizations or groups.

field_map

  • Default: (empty)
  • Description: Maps OAuth attributes to WireGuard Portal fields.
  • Available fields: user_identifier, email, firstname, lastname, phone, department, is_admin, user_groups.

    Field Typical Claim Explanation
    user_identifier sub or preferred_username A unique identifier for the user. Often the OIDC sub claim is used because it’s guaranteed to be unique for the user within the IdP. Some providers also support preferred_username if it’s unique.
    email email The user’s email address as provided by the IdP. Not always verified, depending on IdP settings.
    firstname given_name The user’s first name, typically provided by the IdP in the given_name claim.
    lastname family_name The user’s last (family) name, typically provided by the IdP in the family_name claim.
    phone phone_number The user’s phone number. This may require additional scopes/permissions from the IdP to access.
    department Custom claim (e.g., department) If the IdP can provide organizational data, it may store it in a custom claim. Adjust accordingly (e.g., department, org, or another attribute).
    is_admin Custom claim or derived role If the IdP returns a role or admin flag, you can map that to is_admin. Often this is managed through custom claims or group membership.
    user_groups groups or another custom claim A list of group memberships for the user. Some IdPs provide groups out of the box; others require custom claims or directory lookups.

admin_mapping

  • Default: (empty)
  • Description: WgPortal can grant a user admin rights by matching the value of the is_admin claim against a regular expression. Alternatively, a regular expression can be used to check if a user is member of a specific group listed in the user_group claim. The regular expressions are defined in admin_value_regex and admin_group_regex.
  • admin_value_regex: A regular expression to match the is_admin claim. By default, this expression matches the string "true" (^true$).
  • admin_group_regex: A regular expression to match the user_groups claim. Each entry in the user_groups claim is checked against this regex.

registration_enabled

  • Default: (empty)
  • Description: If true, new users are created automatically on successful login.

log_user_info

  • Default: (empty)
  • Description: If true, logs user info at the trace level upon login.

LDAP

The ldap array contains a list of LDAP authentication providers. Below are the properties for each LDAP provider entry inside auth.ldap:

provider_name

  • Default: (empty)
  • Description: A unique name for this provider. Must not conflict with other providers.

url

  • Default: (empty)
  • Description: The LDAP server URL (e.g., ldap://srv-ad01.company.local:389).

start_tls

  • Default: (empty)
  • Description: If true, use STARTTLS to secure the LDAP connection.

cert_validation

  • Default: (empty)
  • Description: If true, validate the LDAP server’s TLS certificate.

tls_certificate_path

  • Default: (empty)
  • Description: Path to a TLS certificate if needed for LDAP connections.

tls_key_path

  • Default: (empty)
  • Description: Path to the corresponding TLS certificate key.

base_dn

  • Default: (empty)
  • Description: The base DN for user searches (e.g., DC=COMPANY,DC=LOCAL).

bind_user

  • Default: (empty)
  • Description: The bind user for LDAP (e.g., company\\ldap_wireguard or ldap_wireguard@company.local).

bind_pass

  • Default: (empty)
  • Description: The bind password for LDAP authentication.

field_map

  • Default: (empty)
  • Description: Maps LDAP attributes to WireGuard Portal fields.

    • Available fields: user_identifier, email, firstname, lastname, phone, department, memberof.
    WireGuard Portal Field Typical LDAP Attribute Short Description
    user_identifier sAMAccountName / uid Uniquely identifies the user within the LDAP directory.
    email mail / userPrincipalName Stores the user's primary email address.
    firstname givenName Contains the user's first (given) name.
    lastname sn Contains the user's last (surname) name.
    phone telephoneNumber / mobile Holds the user's phone or mobile number.
    department departmentNumber / ou Specifies the department or organizational unit of the user.
    memberof memberOf Lists the groups and roles to which the user belongs.

login_filter

  • Default: (empty)
  • Description: An LDAP filter to restrict which users can log in. Use {{login_identifier}} to insert the username. For example:
    (&(objectClass=organizationalPerson)(mail={{login_identifier}})(!userAccountControl:1.2.840.113556.1.4.803:=2))
     
  • Important: The login_filter 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.

admin_group

  • Default: (empty)
  • Description: A specific LDAP group whose members are considered administrators in WireGuard Portal. For example:
    CN=WireGuardAdmins,OU=Some-OU,DC=YOURDOMAIN,DC=LOCAL
     

sync_interval

  • Default: (empty)
  • Description: How frequently (in duration, e.g. 30m) to synchronize users from LDAP. Empty or 0 disables sync. Format uses s, m, h, d for seconds, minutes, hours, days, see time.ParseDuration. Only users that match the sync_filter are synchronized, if disable_missing is true, users not found in LDAP are disabled.

sync_filter

  • Default: (empty)
  • Description: An LDAP filter to select which users get synchronized into WireGuard Portal. For example:
    (&(objectClass=organizationalPerson)(!userAccountControl:1.2.840.113556.1.4.803:=2)(mail=*))
    diff --git a/master/search/search_index.json b/master/search/search_index.json
    index e41e340..04768a9 100644
    --- a/master/search/search_index.json
    +++ b/master/search/search_index.json
    @@ -1 +1 @@
    -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"documentation/overview/","title":"Overview","text":"

    WireGuard Portal is a simple, web-based configuration portal for WireGuard server management. The portal uses the WireGuard wgctrl library to manage existing VPN interfaces. This allows for the seamless activation or deactivation of new users without disturbing existing VPN connections.

    The configuration portal supports using a database (SQLite, MySQL, MsSQL, or Postgres), OAuth or LDAP (Active Directory or OpenLDAP) as a user source for authentication and profile data.

    "},{"location":"documentation/overview/#features","title":"Features","text":"
    • Self-hosted - the whole application is a single binary
    • Responsive multi-language web UI written in Vue.js
    • Automatically selects IP from the network pool assigned to the client
    • QR-Code for convenient mobile client configuration
    • Sends email to the client with QR-code and client config
    • Enable / Disable clients seamlessly
    • Generation of wg-quick configuration file (wgX.conf) if required
    • User authentication (database, OAuth, or LDAP), Passkey support
    • IPv6 ready
    • Docker ready
    • Can be used with existing WireGuard setups
    • Support for multiple WireGuard interfaces
    • Peer Expiry Feature
    • Handles route and DNS settings like wg-quick does
    • Exposes Prometheus metrics for monitoring and alerting
    • REST API for management and client deployment
    • Webhook for custom actions on peer, interface, or user updates
    "},{"location":"documentation/configuration/examples/","title":"Examples","text":"

    Below are some sample YAML configurations demonstrating how to override some default values.

    "},{"location":"documentation/configuration/examples/#basic","title":"Basic","text":"
    core:\n  admin_user: test@example.com\n  admin_password: password\n  admin_api_token: super-s3cr3t-api-token-or-a-UUID\n  import_existing: false\n  create_default_peer: true\n  self_provisioning_allowed: true\n\nweb:\n  site_title: My WireGuard Server\n  site_company_name: My Company\n  listening_address: :8080\n  external_url: https://my.external-domain.com\n  csrf_secret: super-s3cr3t-csrf\n  session_secret: super-s3cr3t-session\n  request_logging: true\n\nadvanced:\n  log_level: trace\n  log_pretty: true\n  log_json: false\n  config_storage_path: /etc/wireguard\n  expiry_check_interval: 5m\n\ndatabase:\n  debug: true\n  type: sqlite\n  dsn: data/sqlite.db\n  encryption_passphrase: change-this-s3cr3t-encryption-passphrase\n\nauth:\n  webauthn:\n    enabled: true\n
    "},{"location":"documentation/configuration/examples/#ldap-authentication-and-synchronization","title":"LDAP Authentication and Synchronization","text":"
    # ... (basic configuration)\n\nauth:\n  ldap:\n    # a sample LDAP provider with user sync enabled\n    - id: ldap\n      provider_name: Active Directory\n      url: ldap://srv-ad1.company.local:389\n      bind_user: ldap_wireguard@company.local\n      bind_pass: super-s3cr3t-ldap\n      base_dn: DC=COMPANY,DC=LOCAL\n      login_filter: (&(objectClass=organizationalPerson)(mail={{login_identifier}})(!userAccountControl:1.2.840.113556.1.4.803:=2))\n      sync_interval: 15m\n      sync_filter: (&(objectClass=organizationalPerson)(!userAccountControl:1.2.840.113556.1.4.803:=2)(mail=*))\n      disable_missing: true\n      field_map:\n        user_identifier: sAMAccountName\n        email: mail\n        firstname: givenName\n        lastname: sn\n        phone: telephoneNumber\n        department: department\n        memberof: memberOf\n      admin_group: CN=WireGuardAdmins,OU=Some-OU,DC=COMPANY,DC=LOCAL\n      registration_enabled: true\n      log_user_info: true\n
    "},{"location":"documentation/configuration/examples/#openid-connect-oidc-authentication","title":"OpenID Connect (OIDC) Authentication","text":"
    # ... (basic configuration)\n\nauth:\n  oidc:\n    # A sample Entra ID provider with environment variable substitution.\n    # Only users with an @outlook.com email address are allowed to register or login.\n    - id: azure\n      provider_name: azure\n      display_name: Login with</br>Entra ID\n      registration_enabled: true\n      base_url: \"https://login.microsoftonline.com/${AZURE_TENANT_ID}/v2.0\"\n      client_id: \"${AZURE_CLIENT_ID}\"\n      client_secret: \"${AZURE_CLIENT_SECRET}\"\n      allowed_domains:\n        - \"outlook.com\"\n      extra_scopes:\n        - profile\n        - email\n\n    # a sample provider where users with the attribute `wg_admin` set to `true` are considered as admins\n    - id: oidc-with-admin-attribute\n      provider_name: google\n      display_name: Login with</br>Google\n      base_url: https://accounts.google.com\n      client_id: the-client-id-1234.apps.googleusercontent.com\n      client_secret: A_CLIENT_SECRET\n      extra_scopes:\n        - https://www.googleapis.com/auth/userinfo.email\n        - https://www.googleapis.com/auth/userinfo.profile\n      field_map:\n        user_identifier: sub\n        email: email\n        firstname: given_name\n        lastname: family_name\n        phone: phone_number\n        department: department\n        is_admin: wg_admin\n      admin_mapping:\n        admin_value_regex: ^true$\n      registration_enabled: true\n      log_user_info: true\n\n    # a sample provider where users in the group `the-admin-group` are considered as admins\n    - id: oidc-with-admin-group\n      provider_name: google2\n      display_name: Login with</br>Google2\n      base_url: https://accounts.google.com\n      client_id: another-client-id-1234.apps.googleusercontent.com\n      client_secret: A_CLIENT_SECRET\n      extra_scopes:\n        - https://www.googleapis.com/auth/userinfo.email\n        - https://www.googleapis.com/auth/userinfo.profile\n      field_map:\n        user_identifier: sub\n        email: email\n        firstname: given_name\n        lastname: family_name\n        phone: phone_number\n        department: department\n        user_groups: groups\n      admin_mapping:\n        admin_group_regex: ^the-admin-group$\n      registration_enabled: true\n      log_user_info: true\n
    "},{"location":"documentation/configuration/examples/#plain-oauth2-authentication","title":"Plain OAuth2 Authentication","text":"
    # ... (basic configuration)\n\nauth:\n  oauth:\n    # a sample provider where users with the attribute `this-attribute-must-be-true` set to `true` or `True`\n    # are considered as admins\n    - id: google_plain_oauth-with-admin-attribute\n      provider_name: google3\n      display_name: Login with</br>Google3\n      client_id: another-client-id-1234.apps.googleusercontent.com\n      client_secret: A_CLIENT_SECRET\n      auth_url: https://accounts.google.com/o/oauth2/v2/auth\n      token_url: https://oauth2.googleapis.com/token\n      user_info_url: https://openidconnect.googleapis.com/v1/userinfo\n      scopes:\n        - openid\n        - email\n        - profile\n      field_map:\n        user_identifier: sub\n        email: email\n        firstname: name\n        is_admin: this-attribute-must-be-true\n      admin_mapping:\n        admin_value_regex: ^(True|true)$\n      registration_enabled: true\n\n    # a sample provider where either users with the attribute `this-attribute-must-be-true` set to `true` or \n    # users in the group `admin-group-name` are considered as admins\n    - id: google_plain_oauth_with_groups\n      provider_name: google4\n      display_name: Login with</br>Google4\n      client_id: another-client-id-1234.apps.googleusercontent.com\n      client_secret: A_CLIENT_SECRET\n      auth_url: https://accounts.google.com/o/oauth2/v2/auth\n      token_url: https://oauth2.googleapis.com/token\n      user_info_url: https://openidconnect.googleapis.com/v1/userinfo\n      scopes:\n        - openid\n        - email\n        - profile\n        - i-want-some-groups\n      field_map:\n        email: email\n        firstname: name\n        user_identifier: sub\n        is_admin: this-attribute-must-be-true\n        user_groups: groups\n      admin_mapping:\n        admin_value_regex: ^true$\n        admin_group_regex: ^admin-group-name$\n      registration_enabled: true\n      log_user_info: true\n
    "},{"location":"documentation/configuration/overview/","title":"Overview","text":"

    This page provides an overview of all available configuration options for WireGuard Portal.

    You can supply these configurations in a YAML file when starting the Portal. The path of the configuration file defaults to config/config.yaml (or config/config.yml) in the working directory of the executable. It is possible to override the configuration filepath using the environment variable WG_PORTAL_CONFIG. For example: WG_PORTAL_CONFIG=/etc/wg-portal/config.yaml ./wg-portal. Also, environment variable substitution in the config file is supported. Refer to the syntax.

    Configuration examples are available on the Examples page.

    Default configuration
    core:\n  admin_user: admin@wgportal.local\n  admin_password: wgportal-default\n  admin_api_token: \"\"\n  editable_keys: true\n  create_default_peer: false\n  create_default_peer_on_creation: false\n  re_enable_peer_after_user_enable: true\n  delete_peer_after_user_deleted: false\n  self_provisioning_allowed: false\n  import_existing: true\n  restore_state: true\n\nadvanced:\n  log_level: info\n  log_pretty: false\n  log_json: false\n  start_listen_port: 51820\n  start_cidr_v4: 10.11.12.0/24\n  start_cidr_v6: fdfd:d3ad:c0de:1234::0/64\n  use_ip_v6: true\n  config_storage_path: \"\"\n  expiry_check_interval: 15m\n  rule_prio_offset: 20000\n  route_table_offset: 20000\n  api_admin_only: true\n\ndatabase:\n  debug: false\n  slow_query_threshold: \"0\"\n  type: sqlite\n  dsn: data/sqlite.db\n  encryption_passphrase: \"\"\n\nstatistics:\n  use_ping_checks: true\n  ping_check_workers: 10\n  ping_unprivileged: false\n  ping_check_interval: 1m\n  data_collection_interval: 1m\n  collect_interface_data: true\n  collect_peer_data: true\n  collect_audit_data: true\n  listening_address: :8787\n\nmail:\n  host: 127.0.0.1\n  port: 25\n  encryption: none\n  cert_validation: true\n  username: \"\"\n  password: \"\"\n  auth_type: plain\n  from: Wireguard Portal <noreply@wireguard.local>\n  link_only: false\n\nauth:\n  oidc: []\n  oauth: []\n  ldap: []\n  webauthn:\n    enabled: true\n  min_password_length: 16\n\nweb:\n  listening_address: :8888\n  external_url: http://localhost:8888\n  site_company_name: WireGuard Portal\n  site_title: WireGuard Portal\n  session_identifier: wgPortalSession\n  session_secret: very_secret\n  csrf_secret: extremely_secret\n  request_logging: false\n  expose_host_info: false\n  cert_file: \"\"\n  key_File: \"\"\n\nwebhook:\n  url: \"\"\n  authentication: \"\"\n  timeout: 10s\n

    Below you will find sections like core, advanced, database, statistics, mail, auth, web and webhook. Each section describes the individual configuration keys, their default values, and a brief explanation of their purpose.

    "},{"location":"documentation/configuration/overview/#core","title":"Core","text":"

    These are the primary configuration options that control fundamental WireGuard Portal behavior. More advanced options are found in the subsequent Advanced section.

    "},{"location":"documentation/configuration/overview/#admin_user","title":"admin_user","text":"
    • Default: admin@wgportal.local
    • Description: The administrator user. This user will be created as a default admin if it does not yet exist.
    "},{"location":"documentation/configuration/overview/#admin_password","title":"admin_password","text":"
    • Default: wgportal-default
    • Description: The administrator password. The default password should be changed immediately!
    • Important: The password should be strong and secure. The minimum password length is specified in auth.min_password_length. By default, it is 16 characters.
    "},{"location":"documentation/configuration/overview/#admin_api_token","title":"admin_api_token","text":"
    • Default: (empty)
    • Description: 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.
    "},{"location":"documentation/configuration/overview/#editable_keys","title":"editable_keys","text":"
    • Default: true
    • Description: Allow editing of WireGuard key-pairs directly in the UI.
    "},{"location":"documentation/configuration/overview/#create_default_peer","title":"create_default_peer","text":"
    • Default: false
    • Description: If a user logs in for the first time with no existing peers, automatically create a new WireGuard peer for all server interfaces.
    "},{"location":"documentation/configuration/overview/#create_default_peer_on_creation","title":"create_default_peer_on_creation","text":"
    • Default: false
    • Description: If an LDAP user is created (e.g., through LDAP sync) and has no peers, automatically create a new WireGuard peer for all server interfaces.
    "},{"location":"documentation/configuration/overview/#re_enable_peer_after_user_enable","title":"re_enable_peer_after_user_enable","text":"
    • Default: true
    • Description: Re-enable all peers that were previously disabled if the associated user is re-enabled.
    "},{"location":"documentation/configuration/overview/#delete_peer_after_user_deleted","title":"delete_peer_after_user_deleted","text":"
    • Default: false
    • Description: If a user is deleted, remove all linked peers. Otherwise, peers remain but are disabled.
    "},{"location":"documentation/configuration/overview/#self_provisioning_allowed","title":"self_provisioning_allowed","text":"
    • Default: false
    • Description: Allow registered (non-admin) users to self-provision peers from their profile page.
    "},{"location":"documentation/configuration/overview/#import_existing","title":"import_existing","text":"
    • Default: true
    • Description: On startup, import existing WireGuard interfaces and peers into WireGuard Portal.
    "},{"location":"documentation/configuration/overview/#restore_state","title":"restore_state","text":"
    • Default: true
    • Description: Restore the WireGuard interface states (up/down) that existed before WireGuard Portal started.
    "},{"location":"documentation/configuration/overview/#advanced","title":"Advanced","text":"

    Additional or more specialized configuration options for logging and interface creation details.

    "},{"location":"documentation/configuration/overview/#log_level","title":"log_level","text":"
    • Default: info
    • Description: The log level used by the application. Valid options are: trace, debug, info, warn, error.
    "},{"location":"documentation/configuration/overview/#log_pretty","title":"log_pretty","text":"
    • Default: false
    • Description: If true, log messages are colorized and formatted for readability (pretty-print).
    "},{"location":"documentation/configuration/overview/#log_json","title":"log_json","text":"
    • Default: false
    • Description: If true, log messages are structured in JSON format.
    "},{"location":"documentation/configuration/overview/#start_listen_port","title":"start_listen_port","text":"
    • Default: 51820
    • Description: The first port to use when automatically creating new WireGuard interfaces.
    "},{"location":"documentation/configuration/overview/#start_cidr_v4","title":"start_cidr_v4","text":"
    • Default: 10.11.12.0/24
    • Description: The initial IPv4 subnet to use when automatically creating new WireGuard interfaces.
    "},{"location":"documentation/configuration/overview/#start_cidr_v6","title":"start_cidr_v6","text":"
    • Default: fdfd:d3ad:c0de:1234::0/64
    • Description: The initial IPv6 subnet to use when automatically creating new WireGuard interfaces.
    "},{"location":"documentation/configuration/overview/#use_ip_v6","title":"use_ip_v6","text":"
    • Default: true
    • Description: Enable or disable IPv6 support.
    "},{"location":"documentation/configuration/overview/#config_storage_path","title":"config_storage_path","text":"
    • Default: (empty)
    • Description: Path to a directory where wg-quick style configuration files will be stored (if you need local filesystem configs).
    "},{"location":"documentation/configuration/overview/#expiry_check_interval","title":"expiry_check_interval","text":"
    • Default: 15m
    • Description: Interval after which existing peers are checked if they are expired. Format uses s, m, h, d for seconds, minutes, hours, days, see time.ParseDuration.
    "},{"location":"documentation/configuration/overview/#rule_prio_offset","title":"rule_prio_offset","text":"
    • Default: 20000
    • Description: Offset for IP route rule priorities when configuring routing.
    "},{"location":"documentation/configuration/overview/#route_table_offset","title":"route_table_offset","text":"
    • Default: 20000
    • Description: Offset for IP route table IDs when configuring routing.
    "},{"location":"documentation/configuration/overview/#api_admin_only","title":"api_admin_only","text":"
    • Default: true
    • Description: If true, the public REST API is accessible only to admin users. The API docs live at /api/v1/doc.html.
    "},{"location":"documentation/configuration/overview/#database","title":"Database","text":"

    Configuration for the underlying database used by WireGuard Portal. Supported databases include SQLite, MySQL, Microsoft SQL Server, and Postgres.

    If sensitive values (like private keys) should be stored in an encrypted format, set the encryption_passphrase option.

    "},{"location":"documentation/configuration/overview/#debug","title":"debug","text":"
    • Default: false
    • Description: If true, logs all database statements (verbose).
    "},{"location":"documentation/configuration/overview/#slow_query_threshold","title":"slow_query_threshold","text":"
    • Default: \"0\"
    • Description: A time threshold (e.g., 100ms) above which queries are considered slow and logged as warnings. If zero, slow query logging is disabled. Format uses s, ms for seconds, milliseconds, see time.ParseDuration. The value must be a string.
    "},{"location":"documentation/configuration/overview/#type","title":"type","text":"
    • Default: sqlite
    • Description: The database type. Valid options: sqlite, mssql, mysql, postgres.
    "},{"location":"documentation/configuration/overview/#dsn","title":"dsn","text":"
    • Default: data/sqlite.db
    • Description: The Data Source Name (DSN) for connecting to the database. For example:
      user:pass@tcp(1.2.3.4:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local\n
    "},{"location":"documentation/configuration/overview/#encryption_passphrase","title":"encryption_passphrase","text":"
    • Default: (empty)
    • Description: Passphrase for encrypting sensitive values such as private keys in the database. Encryption is only applied if this passphrase is set. Important: 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\u2019s next modified.
    "},{"location":"documentation/configuration/overview/#statistics","title":"Statistics","text":"

    Controls how WireGuard Portal collects and reports usage statistics, including ping checks and Prometheus metrics.

    "},{"location":"documentation/configuration/overview/#use_ping_checks","title":"use_ping_checks","text":"
    • Default: true
    • Description: Enable periodic ping checks to verify that peers remain responsive.
    "},{"location":"documentation/configuration/overview/#ping_check_workers","title":"ping_check_workers","text":"
    • Default: 10
    • Description: Number of parallel worker processes for ping checks.
    "},{"location":"documentation/configuration/overview/#ping_unprivileged","title":"ping_unprivileged","text":"
    • Default: false
    • Description: If false, ping checks run without root privileges. This is currently considered BETA.
    "},{"location":"documentation/configuration/overview/#ping_check_interval","title":"ping_check_interval","text":"
    • Default: 1m
    • Description: Interval between consecutive ping checks for all peers. Format uses s, m, h, d for seconds, minutes, hours, days, see time.ParseDuration.
    "},{"location":"documentation/configuration/overview/#data_collection_interval","title":"data_collection_interval","text":"
    • Default: 1m
    • Description: Interval between data collection cycles (bytes sent/received, handshake times, etc.). Format uses s, m, h, d for seconds, minutes, hours, days, see time.ParseDuration.
    "},{"location":"documentation/configuration/overview/#collect_interface_data","title":"collect_interface_data","text":"
    • Default: true
    • Description: If true, collects interface-level data (bytes in/out) for monitoring and statistics.
    "},{"location":"documentation/configuration/overview/#collect_peer_data","title":"collect_peer_data","text":"
    • Default: true
    • Description: If true, collects peer-level data (bytes, last handshake, endpoint, etc.).
    "},{"location":"documentation/configuration/overview/#collect_audit_data","title":"collect_audit_data","text":"
    • Default: true
    • Description: If true, logs certain portal events (such as user logins) to the database.
    "},{"location":"documentation/configuration/overview/#listening_address","title":"listening_address","text":"
    • Default: :8787
    • Description: Address and port for the integrated Prometheus metric server (e.g., :8787 or 127.0.0.1:8787).
    "},{"location":"documentation/configuration/overview/#mail","title":"Mail","text":"

    Options for configuring email notifications or sending peer configurations via email.

    "},{"location":"documentation/configuration/overview/#host","title":"host","text":"
    • Default: 127.0.0.1
    • Description: Hostname or IP of the SMTP server.
    "},{"location":"documentation/configuration/overview/#port","title":"port","text":"
    • Default: 25
    • Description: Port number for the SMTP server.
    "},{"location":"documentation/configuration/overview/#encryption","title":"encryption","text":"
    • Default: none
    • Description: SMTP encryption type. Valid values: none, tls, starttls.
    "},{"location":"documentation/configuration/overview/#cert_validation","title":"cert_validation","text":"
    • Default: true
    • Description: If true, validate the SMTP server certificate (relevant if encryption = tls).
    "},{"location":"documentation/configuration/overview/#username","title":"username","text":"
    • Default: (empty)
    • Description: Optional SMTP username for authentication.
    "},{"location":"documentation/configuration/overview/#password","title":"password","text":"
    • Default: (empty)
    • Description: Optional SMTP password for authentication.
    "},{"location":"documentation/configuration/overview/#auth_type","title":"auth_type","text":"
    • Default: plain
    • Description: SMTP authentication type. Valid values: plain, login, crammd5.
    "},{"location":"documentation/configuration/overview/#from","title":"from","text":"
    • Default: Wireguard Portal <noreply@wireguard.local>
    • Description: The default \"From\" address when sending emails.
    "},{"location":"documentation/configuration/overview/#link_only","title":"link_only","text":"
    • Default: false
    • Description: If true, emails only contain a link to WireGuard Portal, rather than attaching the full configuration.
    "},{"location":"documentation/configuration/overview/#auth","title":"Auth","text":"

    WireGuard Portal supports multiple authentication strategies, including OpenID Connect (oidc), OAuth (oauth), Passkeys (webauthn) and LDAP (ldap). Each can have multiple providers configured. Below are the relevant keys.

    Some core authentication options are shared across all providers, while others are specific to each provider type.

    "},{"location":"documentation/configuration/overview/#min_password_length","title":"min_password_length","text":"
    • Default: 16
    • Description: Minimum password length for local authentication. This is not enforced for LDAP authentication. The default admin password strength is also enforced by this setting.
    • Important: The password should be strong and secure. It is recommended to use a password with at least 16 characters, including uppercase and lowercase letters, numbers, and special characters.
    "},{"location":"documentation/configuration/overview/#oidc","title":"OIDC","text":"

    The oidc array contains a list of OpenID Connect providers. Below are the properties for each OIDC provider entry inside auth.oidc:

    "},{"location":"documentation/configuration/overview/#provider_name","title":"provider_name","text":"
    • Default: (empty)
    • Description: A unique name for this provider. Must not conflict with other providers.
    "},{"location":"documentation/configuration/overview/#display_name","title":"display_name","text":"
    • Default: (empty)
    • Description: A user-friendly name shown on the login page (e.g., \"Login with Google\").
    "},{"location":"documentation/configuration/overview/#base_url","title":"base_url","text":"
    • Default: (empty)
    • Description: The OIDC provider\u2019s base URL (e.g., https://accounts.google.com).
    "},{"location":"documentation/configuration/overview/#client_id","title":"client_id","text":"
    • Default: (empty)
    • Description: The OAuth client ID from the OIDC provider.
    "},{"location":"documentation/configuration/overview/#client_secret","title":"client_secret","text":"
    • Default: (empty)
    • Description: The OAuth client secret from the OIDC provider.
    "},{"location":"documentation/configuration/overview/#extra_scopes","title":"extra_scopes","text":"
    • Default: (empty)
    • Description: A list of additional OIDC scopes (e.g., profile, email).
    "},{"location":"documentation/configuration/overview/#allowed_domains","title":"allowed_domains","text":"
    • Default: (empty)
    • Description: A list of allowlisted domains. Only users with email addresses in these domains can log in or register. This is useful for restricting access to specific organizations or groups.
    "},{"location":"documentation/configuration/overview/#field_map","title":"field_map","text":"
    • Default: (empty)
    • Description: Maps OIDC claims to WireGuard Portal user fields.
    • Available fields: user_identifier, email, firstname, lastname, phone, department, is_admin, user_groups.

      Field Typical OIDC Claim Explanation user_identifier sub or preferred_username A unique identifier for the user. Often the OIDC sub claim is used because it\u2019s guaranteed to be unique for the user within the IdP. Some providers also support preferred_username if it\u2019s unique. email email The user\u2019s email address as provided by the IdP. Not always verified, depending on IdP settings. firstname given_name The user\u2019s first name, typically provided by the IdP in the given_name claim. lastname family_name The user\u2019s last (family) name, typically provided by the IdP in the family_name claim. phone phone_number The user\u2019s phone number. This may require additional scopes/permissions from the IdP to access. department Custom claim (e.g., department) If the IdP can provide organizational data, it may store it in a custom claim. Adjust accordingly (e.g., department, org, or another attribute). is_admin Custom claim or derived role If the IdP returns a role or admin flag, you can map that to is_admin. Often this is managed through custom claims or group membership. user_groups groups or another custom claim A list of group memberships for the user. Some IdPs provide groups out of the box; others require custom claims or directory lookups.
    "},{"location":"documentation/configuration/overview/#admin_mapping","title":"admin_mapping","text":"
    • Default: (empty)
    • Description: WgPortal can grant a user admin rights by matching the value of the is_admin claim against a regular expression. Alternatively, a regular expression can be used to check if a user is member of a specific group listed in the user_group claim. The regular expressions are defined in admin_value_regex and admin_group_regex.
      • admin_value_regex: A regular expression to match the is_admin claim. By default, this expression matches the string \"true\" (^true$).
      • admin_group_regex: A regular expression to match the user_groups claim. Each entry in the user_groups claim is checked against this regex.
    "},{"location":"documentation/configuration/overview/#registration_enabled","title":"registration_enabled","text":"
    • Default: (empty)
    • Description: If true, a new user will be created in WireGuard Portal if not already present.
    "},{"location":"documentation/configuration/overview/#log_user_info","title":"log_user_info","text":"
    • Default: (empty)
    • Description: If true, OIDC user data is logged at the trace level upon login (for debugging).
    "},{"location":"documentation/configuration/overview/#oauth","title":"OAuth","text":"

    The oauth array contains a list of plain OAuth2 providers. Below are the properties for each OAuth provider entry inside auth.oauth:

    "},{"location":"documentation/configuration/overview/#provider_name_1","title":"provider_name","text":"
    • Default: (empty)
    • Description: A unique name for this provider. Must not conflict with other providers.
    "},{"location":"documentation/configuration/overview/#display_name_1","title":"display_name","text":"
    • Default: (empty)
    • Description: A user-friendly name shown on the login page.
    "},{"location":"documentation/configuration/overview/#client_id_1","title":"client_id","text":"
    • Default: (empty)
    • Description: The OAuth client ID for the provider.
    "},{"location":"documentation/configuration/overview/#client_secret_1","title":"client_secret","text":"
    • Default: (empty)
    • Description: The OAuth client secret for the provider.
    "},{"location":"documentation/configuration/overview/#auth_url","title":"auth_url","text":"
    • Default: (empty)
    • Description: URL of the authentication endpoint.
    "},{"location":"documentation/configuration/overview/#token_url","title":"token_url","text":"
    • Default: (empty)
    • Description: URL of the token endpoint.
    "},{"location":"documentation/configuration/overview/#user_info_url","title":"user_info_url","text":"
    • Default: (empty)
    • Description: URL of the user information endpoint.
    "},{"location":"documentation/configuration/overview/#scopes","title":"scopes","text":"
    • Default: (empty)
    • Description: A list of OAuth scopes.
    "},{"location":"documentation/configuration/overview/#allowed_domains_1","title":"allowed_domains","text":"
    • Default: (empty)
    • Description: A list of allowlisted domains. Only users with email addresses in these domains can log in or register. This is useful for restricting access to specific organizations or groups.
    "},{"location":"documentation/configuration/overview/#field_map_1","title":"field_map","text":"
    • Default: (empty)
    • Description: Maps OAuth attributes to WireGuard Portal fields.
    • Available fields: user_identifier, email, firstname, lastname, phone, department, is_admin, user_groups.

      Field Typical Claim Explanation user_identifier sub or preferred_username A unique identifier for the user. Often the OIDC sub claim is used because it\u2019s guaranteed to be unique for the user within the IdP. Some providers also support preferred_username if it\u2019s unique. email email The user\u2019s email address as provided by the IdP. Not always verified, depending on IdP settings. firstname given_name The user\u2019s first name, typically provided by the IdP in the given_name claim. lastname family_name The user\u2019s last (family) name, typically provided by the IdP in the family_name claim. phone phone_number The user\u2019s phone number. This may require additional scopes/permissions from the IdP to access. department Custom claim (e.g., department) If the IdP can provide organizational data, it may store it in a custom claim. Adjust accordingly (e.g., department, org, or another attribute). is_admin Custom claim or derived role If the IdP returns a role or admin flag, you can map that to is_admin. Often this is managed through custom claims or group membership. user_groups groups or another custom claim A list of group memberships for the user. Some IdPs provide groups out of the box; others require custom claims or directory lookups.
    "},{"location":"documentation/configuration/overview/#admin_mapping_1","title":"admin_mapping","text":"
    • Default: (empty)
    • Description: WgPortal can grant a user admin rights by matching the value of the is_admin claim against a regular expression. Alternatively, a regular expression can be used to check if a user is member of a specific group listed in the user_group claim. The regular expressions are defined in admin_value_regex and admin_group_regex.
    • admin_value_regex: A regular expression to match the is_admin claim. By default, this expression matches the string \"true\" (^true$).
    • admin_group_regex: A regular expression to match the user_groups claim. Each entry in the user_groups claim is checked against this regex.
    "},{"location":"documentation/configuration/overview/#registration_enabled_1","title":"registration_enabled","text":"
    • Default: (empty)
    • Description: If true, new users are created automatically on successful login.
    "},{"location":"documentation/configuration/overview/#log_user_info_1","title":"log_user_info","text":"
    • Default: (empty)
    • Description: If true, logs user info at the trace level upon login.
    "},{"location":"documentation/configuration/overview/#ldap","title":"LDAP","text":"

    The ldap array contains a list of LDAP authentication providers. Below are the properties for each LDAP provider entry inside auth.ldap:

    "},{"location":"documentation/configuration/overview/#provider_name_2","title":"provider_name","text":"
    • Default: (empty)
    • Description: A unique name for this provider. Must not conflict with other providers.
    "},{"location":"documentation/configuration/overview/#url","title":"url","text":"
    • Default: (empty)
    • Description: The LDAP server URL (e.g., ldap://srv-ad01.company.local:389).
    "},{"location":"documentation/configuration/overview/#start_tls","title":"start_tls","text":"
    • Default: (empty)
    • Description: If true, use STARTTLS to secure the LDAP connection.
    "},{"location":"documentation/configuration/overview/#cert_validation_1","title":"cert_validation","text":"
    • Default: (empty)
    • Description: If true, validate the LDAP server\u2019s TLS certificate.
    "},{"location":"documentation/configuration/overview/#tls_certificate_path","title":"tls_certificate_path","text":"
    • Default: (empty)
    • Description: Path to a TLS certificate if needed for LDAP connections.
    "},{"location":"documentation/configuration/overview/#tls_key_path","title":"tls_key_path","text":"
    • Default: (empty)
    • Description: Path to the corresponding TLS certificate key.
    "},{"location":"documentation/configuration/overview/#base_dn","title":"base_dn","text":"
    • Default: (empty)
    • Description: The base DN for user searches (e.g., DC=COMPANY,DC=LOCAL).
    "},{"location":"documentation/configuration/overview/#bind_user","title":"bind_user","text":"
    • Default: (empty)
    • Description: The bind user for LDAP (e.g., company\\\\ldap_wireguard or ldap_wireguard@company.local).
    "},{"location":"documentation/configuration/overview/#bind_pass","title":"bind_pass","text":"
    • Default: (empty)
    • Description: The bind password for LDAP authentication.
    "},{"location":"documentation/configuration/overview/#field_map_2","title":"field_map","text":"
    • Default: (empty)
    • Description: Maps LDAP attributes to WireGuard Portal fields.

      • Available fields: user_identifier, email, firstname, lastname, phone, department, memberof.
      WireGuard Portal Field Typical LDAP Attribute Short Description user_identifier sAMAccountName / uid Uniquely identifies the user within the LDAP directory. email mail / userPrincipalName Stores the user's primary email address. firstname givenName Contains the user's first (given) name. lastname sn Contains the user's last (surname) name. phone telephoneNumber / mobile Holds the user's phone or mobile number. department departmentNumber / ou Specifies the department or organizational unit of the user. memberof memberOf Lists the groups and roles to which the user belongs.
    "},{"location":"documentation/configuration/overview/#login_filter","title":"login_filter","text":"
    • Default: (empty)
    • Description: An LDAP filter to restrict which users can log in. Use {{login_identifier}} to insert the username. For example:
      (&(objectClass=organizationalPerson)(mail={{login_identifier}})(!userAccountControl:1.2.840.113556.1.4.803:=2))\n
    • Important: The login_filter 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.
    "},{"location":"documentation/configuration/overview/#admin_group","title":"admin_group","text":"
    • Default: (empty)
    • Description: A specific LDAP group whose members are considered administrators in WireGuard Portal. For example:
      CN=WireGuardAdmins,OU=Some-OU,DC=YOURDOMAIN,DC=LOCAL\n
    "},{"location":"documentation/configuration/overview/#sync_interval","title":"sync_interval","text":"
    • Default: (empty)
    • Description: How frequently (in duration, e.g. 30m) to synchronize users from LDAP. Empty or 0 disables sync. Format uses s, m, h, d for seconds, minutes, hours, days, see time.ParseDuration. Only users that match the sync_filter are synchronized, if disable_missing is true, users not found in LDAP are disabled.
    "},{"location":"documentation/configuration/overview/#sync_filter","title":"sync_filter","text":"
    • Default: (empty)
    • Description: An LDAP filter to select which users get synchronized into WireGuard Portal. For example:
      (&(objectClass=organizationalPerson)(!userAccountControl:1.2.840.113556.1.4.803:=2)(mail=*))\n
    "},{"location":"documentation/configuration/overview/#disable_missing","title":"disable_missing","text":"
    • Default: (empty)
    • Description: If true, any user not found in LDAP (during sync) is disabled in WireGuard Portal.
    "},{"location":"documentation/configuration/overview/#auto_re_enable","title":"auto_re_enable","text":"
    • Default: (empty)
    • Description: If true, users that where disabled because they were missing (see disable_missing) will be re-enabled once they are found again.
    "},{"location":"documentation/configuration/overview/#registration_enabled_2","title":"registration_enabled","text":"
    • Default: (empty)
    • Description: If true, new user accounts are created in WireGuard Portal upon first login.
    "},{"location":"documentation/configuration/overview/#log_user_info_2","title":"log_user_info","text":"
    • Default: (empty)
    • Description: If true, logs LDAP user data at the trace level upon login.
    "},{"location":"documentation/configuration/overview/#webauthn-passkeys","title":"WebAuthn (Passkeys)","text":"

    The webauthn section contains configuration options for WebAuthn authentication (passkeys).

    "},{"location":"documentation/configuration/overview/#enabled","title":"enabled","text":"
    • Default: true
    • Description: If true, Passkey authentication is enabled. If false, 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.
    "},{"location":"documentation/configuration/overview/#web","title":"Web","text":"

    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 external_url for the web server, especially if you are using a reverse proxy. Without a valid external_url, the login process may fail due to CSRF protection.

    "},{"location":"documentation/configuration/overview/#listening_address_1","title":"listening_address","text":"
    • Default: :8888
    • Description: The listening address and port for the web server (e.g., :8888 to bind on all interfaces or 127.0.0.1:8888 to bind only on the loopback interface). Ensure that access to WireGuard Portal is protected against unauthorized access, especially if binding to all interfaces.
    "},{"location":"documentation/configuration/overview/#external_url","title":"external_url","text":"
    • Default: http://localhost:8888
    • Description: The URL where a client can access WireGuard Portal. This URL is used for generating links in emails and for performing OAUTH redirects. Important: If you are using a reverse proxy, set this to the external URL of the reverse proxy, otherwise login will fail. If you access the portal via IP address, set this to the IP address of the server.
    "},{"location":"documentation/configuration/overview/#site_company_name","title":"site_company_name","text":"
    • Default: WireGuard Portal
    • Description: The company name that is shown at the bottom of the web frontend.
    "},{"location":"documentation/configuration/overview/#site_title","title":"site_title","text":"
    • Default: WireGuard Portal
    • Description: The title that is shown in the web frontend.
    "},{"location":"documentation/configuration/overview/#session_identifier","title":"session_identifier","text":"
    • Default: wgPortalSession
    • Description: The session identifier for the web frontend.
    "},{"location":"documentation/configuration/overview/#session_secret","title":"session_secret","text":"
    • Default: very_secret
    • Description: The session secret for the web frontend.
    "},{"location":"documentation/configuration/overview/#csrf_secret","title":"csrf_secret","text":"
    • Default: extremely_secret
    • Description: The CSRF secret.
    "},{"location":"documentation/configuration/overview/#request_logging","title":"request_logging","text":"
    • Default: false
    • Description: Log all HTTP requests.
    "},{"location":"documentation/configuration/overview/#expose_host_info","title":"expose_host_info","text":"
    • Default: false
    • Description: Expose the hostname and version of the WireGuard Portal server in an HTTP header. This is useful for debugging but may expose sensitive information.
    "},{"location":"documentation/configuration/overview/#cert_file","title":"cert_file","text":"
    • Default: (empty)
    • Description: (Optional) Path to the TLS certificate file.
    "},{"location":"documentation/configuration/overview/#key_file","title":"key_file","text":"
    • Default: (empty)
    • Description: (Optional) Path to the TLS certificate key file.
    "},{"location":"documentation/configuration/overview/#webhook","title":"Webhook","text":"

    The webhook section allows you to configure a webhook that is called on certain events in WireGuard Portal. A JSON object is sent in a POST request to the webhook URL with the following structure:

    {\n  \"event\": \"peer_created\",\n  \"entity\": \"peer\",\n  \"identifier\": \"the-peer-identifier\",\n  \"payload\": {\n    // The payload of the event, e.g. peer data.\n    // Check the API documentation for the exact structure.\n  }\n}\n

    "},{"location":"documentation/configuration/overview/#url_1","title":"url","text":"
    • Default: (empty)
    • Description: The POST endpoint to which the webhook is sent. The URL must be reachable from the WireGuard Portal server. If the URL is empty, the webhook is disabled.
    "},{"location":"documentation/configuration/overview/#authentication","title":"authentication","text":"
    • Default: (empty)
    • Description: The Authorization header for the webhook endpoint. The value is send as-is in the header. For example: Bearer <token>.
    "},{"location":"documentation/configuration/overview/#timeout","title":"timeout","text":"
    • Default: 10s
    • Description: The timeout for the webhook request. If the request takes longer than this, it is aborted.
    "},{"location":"documentation/getting-started/binaries/","title":"Binaries","text":"

    Starting from v2, each release includes compiled binaries for supported platforms. These binary versions can be manually downloaded and installed.

    "},{"location":"documentation/getting-started/binaries/#download","title":"Download","text":"

    Make sure that you download the correct binary for your architecture. The available binaries are:

    • wg-portal_linux_amd64 - Linux x86_64
    • wg-portal_linux_arm64 - Linux ARM 64-bit
    • wg-portal_linux_arm_v7 - Linux ARM 32-bit

    With curl:

    curl -L -o wg-portal https://github.com/h44z/wg-portal/releases/download/${WG_PORTAL_VERSION}/wg-portal_linux_amd64 \n

    With wget:

    wget -O wg-portal https://github.com/h44z/wg-portal/releases/download/${WG_PORTAL_VERSION}/wg-portal_linux_amd64\n

    with gh cli:

    gh release download ${WG_PORTAL_VERSION} --repo h44z/wg-portal --output wg-portal --pattern '*amd64'\n
    "},{"location":"documentation/getting-started/binaries/#install","title":"Install","text":"
    sudo mkdir -p /opt/wg-portal\nsudo install wg-portal /opt/wg-portal/\n
    "},{"location":"documentation/getting-started/binaries/#unreleased-versions-master-branch-builds","title":"Unreleased versions (master branch builds)","text":"

    Unreleased versions can be fetched directly from the artifacts section of the GitHub Workflow.

    "},{"location":"documentation/getting-started/docker/","title":"Docker","text":""},{"location":"documentation/getting-started/docker/#image-usage","title":"Image Usage","text":"

    The WireGuard Portal Docker image is available on both Docker Hub and GitHub Container Registry. It is built on the official Alpine Linux base image and comes pre-packaged with all necessary WireGuard dependencies.

    This container allows you to establish WireGuard VPN connections without relying on a host system that supports WireGuard or using the linuxserver/wireguard Docker image.

    The recommended method for deploying WireGuard Portal is via Docker Compose for ease of configuration and management.

    A sample docker-compose.yml (managing WireGuard interfaces directly on the host) is provided below:

    ---\nservices:\n  wg-portal:\n    image: wgportal/wg-portal:v2\n    container_name: wg-portal\n    restart: unless-stopped\n    logging:\n      options:\n        max-size: \"10m\"\n        max-file: \"3\"\n    cap_add:\n      - NET_ADMIN\n    # Use host network mode for WireGuard and the UI. Ensure that access to the UI is properly secured.\n    network_mode: \"host\"\n    volumes:\n      # left side is the host path, right side is the container path\n      - /etc/wireguard:/etc/wireguard\n      - ./data:/app/data\n      - ./config:/app/config\n

    By default, the webserver for the UI is listening on port 8888 on all available interfaces.

    Volumes for /app/data and /app/config should be used ensure data persistence across container restarts.

    "},{"location":"documentation/getting-started/docker/#wireguard-interface-handling","title":"WireGuard Interface Handling","text":"

    WireGuard Portal supports managing WireGuard interfaces through three distinct deployment methods, providing flexibility based on your system architecture and operational preferences:

    • Directly on the host system: WireGuard Portal can control WireGuard interfaces natively on the host, without using containers. This setup is ideal for environments where direct access to system networking is preferred. To use this method, you need to set the network mode to host in your docker-compose.yml file.

      services:\n  wg-portal:\n    ...\n    network_mode: \"host\"\n    ...\n

      If host networking is used, the WireGuard Portal UI will be accessible on all the host's IP addresses if the listening address is set to :8888 in the configuration file. To avoid this, you can bind the listening address to a specific IP address, for example, the loopback address (127.0.0.1:8888). It is also possible to deploy firewall rules to restrict access to the WireGuard Portal UI.

    • Within the WireGuard Portal Docker container: WireGuard interfaces can be managed directly from within the WireGuard Portal container itself. This is the recommended approach when running WireGuard Portal via Docker, as it encapsulates all functionality in a single, portable container without requiring a separate WireGuard host or image.

      services:\n  wg-portal:\n    image: wgportal/wg-portal:v2\n    container_name: wg-portal\n    ...\n    cap_add:\n      - NET_ADMIN\n    ports:\n      # host port : container port\n      # WireGuard port, needs to match the port in wg-portal interface config (add one port mapping for each interface)\n      - \"51820:51820/udp\" \n      # Web UI port\n      - \"8888:8888/tcp\"\n    sysctls:\n      - net.ipv4.conf.all.src_valid_mark=1\n    volumes:\n      # host path : container path\n      - ./wg/data:/app/data\n      - ./wg/config:/app/config\n

    • Via a separate Docker container: WireGuard Portal can interface with and control WireGuard running in another Docker container, such as the linuxserver/wireguard image. This method is useful in setups that already use linuxserver/wireguard or where you want to isolate the VPN backend from the portal frontend. For this, you need to set the network mode to service:wireguard in your docker-compose.yml file, wireguard is the service name of your WireGuard container.

      services:\n  wg-portal:\n    image: wgportal/wg-portal:v2\n    container_name: wg-portal\n    ...\n    cap_add:\n      - NET_ADMIN\n    network_mode: \"service:wireguard\" # So we ensure to stay on the same network as the wireguard container.\n    volumes:\n      # host path : container path\n      - ./wg/etc:/etc/wireguard\n      - ./wg/data:/app/data\n      - ./wg/config:/app/config\n\n  wireguard:\n    image: lscr.io/linuxserver/wireguard:latest\n    container_name: wireguard\n    restart: unless-stopped\n    cap_add:\n      - NET_ADMIN\n    ports:\n      # host port : container port\n      - \"51820:51820/udp\" # WireGuard port, needs to match the port in wg-portal interface config\n      - \"8888:8888/tcp\" # Noticed that the port of the web UI is exposed in the wireguard container.\n    volumes:\n      - ./wg/etc:/config/wg_confs # We share the configuration (wgx.conf) between wg-portal and wireguard\n    sysctls:\n      - net.ipv4.conf.all.src_valid_mark=1\n
      As the linuxserver/wireguard image uses wg-quick to manage the interfaces, you need to have at least the following configuration set for WireGuard Portal:
      core:\n  # The WireGuard container uses wg-quick to manage the WireGuard interfaces - this conflicts with WireGuard Portal during startup.\n  # To avoid this, we need to set the restore_state option to false so that wg-quick can create the interfaces.\n  restore_state: false\n  # Usually, there are no existing interfaces in the WireGuard container, so we can set this to false.\n  import_existing: false\nadvanced:\n  # WireGuard Portal needs to export the WireGuard configuration as wg-quick config files so that the WireGuard container can use them.\n  config_storage_path: /etc/wireguard/\n

    "},{"location":"documentation/getting-started/docker/#image-versioning","title":"Image Versioning","text":"

    All images are hosted on Docker Hub at https://hub.docker.com/r/wgportal/wg-portal or in the GitHub Container Registry.

    Version 2 is the current stable release. Version 1 has moved to legacy status and is no longer recommended.

    There are three types of tags in the repository:

    "},{"location":"documentation/getting-started/docker/#semantic-versioned-tags","title":"Semantic versioned tags","text":"

    For example, 2.0.0-rc.1 or v2.0.0-rc.1.

    These are official releases of WireGuard Portal. For production deployments of WireGuard Portal, we strongly recommend using one of these versioned tags instead of the latest or canary tags.

    There are different types of these tags:

    • Major version tags: v2 or 2. These tags always refer to the latest image for WireGuard Portal version 2.
    • Minor version tags: v2.x or 2.0. These tags always refer to the latest image for WireGuard Portal version 2.x.
    • Specific version tags (patch version): v2.0.0 or 2.0.0. These tags denote a very specific release. They correspond to the GitHub tags that we make, and you can see the release notes for them here: https://github.com/h44z/wg-portal/releases. Once these tags for a specific version show up in the Docker repository, they will never change.
    "},{"location":"documentation/getting-started/docker/#the-latest-tag","title":"The latest tag","text":"

    The lastest tag is the latest stable release of WireGuard Portal. For version 2, this is the same as the v2 tag.

    "},{"location":"documentation/getting-started/docker/#the-master-tag","title":"The master tag","text":"

    This is the most recent build to the main branch! It changes a lot and is very unstable.

    We recommend that you don't use it except for development purposes or to test the latest features.

    "},{"location":"documentation/getting-started/docker/#configuration","title":"Configuration","text":"

    You can configure WireGuard Portal using a YAML configuration file. The filepath of the YAML configuration file defaults to /app/config/config.yaml. It is possible to override the configuration filepath using the environment variable WG_PORTAL_CONFIG.

    By default, WireGuard Portal uses an SQLite database. The database is stored in /app/data/sqlite.db.

    You should mount those directories as a volume:

    • /app/data
    • /app/config

    A detailed description of the configuration options can be found here.

    If you want to access configuration files in wg-quick format, you can mount the /etc/wireguard directory inside the container to a location of your choice. Also enable the config_storage_path option in the configuration file:

    advanced:\n  config_storage_path: /etc/wireguard\n

    "},{"location":"documentation/getting-started/helm/","title":"Helm","text":""},{"location":"documentation/getting-started/helm/#installing-the-chart","title":"Installing the Chart","text":"

    To install the chart with the release name wg-portal:

    helm install wg-portal oci://ghcr.io/h44z/charts/wg-portal\n

    This command deploy wg-portal on the Kubernetes cluster in the default configuration. The Values section lists the parameters that can be configured during installation.

    "},{"location":"documentation/getting-started/helm/#values","title":"Values","text":"Key Type Default Description nameOverride string \"\" Partially override resource names (adds suffix) fullnameOverride string \"\" Fully override resource names extraDeploy list [] Array of extra objects to deploy with the release config.advanced tpl/object {} Advanced configuration options. config.auth tpl/object {} Auth configuration options. config.core tpl/object {} Core configuration options. If external admins in auth are defined and there are no admin_user and admin_password defined here, the default admin account will be disabled. config.database tpl/object {} Database configuration options config.mail tpl/object {} Mail configuration options config.statistics tpl/object {} Statistics configuration options config.web tpl/object {} Web configuration options. listening_address will be set automatically from service.web.port. external_url is required to enable ingress and certificate resources. revisionHistoryLimit string 10 The number of old ReplicaSets to retain to allow rollback. workloadType string \"Deployment\" Workload type - Deployment or StatefulSet strategy object {\"type\":\"RollingUpdate\"} Update strategy for the workload Valid values are: RollingUpdate or Recreate for Deployment, RollingUpdate or OnDelete for StatefulSet image.repository string \"ghcr.io/h44z/wg-portal\" Image repository image.pullPolicy string \"IfNotPresent\" Image pull policy image.tag string \"\" Overrides the image tag whose default is the chart appVersion imagePullSecrets list [] Image pull secrets podAnnotations tpl/object {} Extra annotations to add to the pod podLabels object {} Extra labels to add to the pod podSecurityContext object {} Pod Security Context securityContext.capabilities.add list [\"NET_ADMIN\"] Add capabilities to the container initContainers tpl/list [] Pod init containers sidecarContainers tpl/list [] Pod sidecar containers dnsPolicy string \"ClusterFirst\" Set DNS policy for the pod. Valid values are ClusterFirstWithHostNet, ClusterFirst, Default or None. restartPolicy string \"Always\" Restart policy for all containers within the pod. Valid values are Always, OnFailure or Never. hostNetwork string false. Use the host's network namespace. resources object {} Resources requests and limits command list [] Overwrite pod command args list [] Additional pod arguments env tpl/list [] Additional environment variables envFrom tpl/list [] Additional environment variables from a secret or configMap livenessProbe object {} Liveness probe configuration readinessProbe object {} Readiness probe configuration startupProbe object {} Startup probe configuration volumes tpl/list [] Additional volumes volumeMounts tpl/list [] Additional volumeMounts nodeSelector object {\"kubernetes.io/os\":\"linux\"} Node Selector configuration tolerations list [] Tolerations configuration affinity object {} Affinity configuration service.mixed.enabled bool false Whether to create a single service for the web and wireguard interfaces service.mixed.type string \"LoadBalancer\" Service type service.web.annotations object {} Annotations for the web service service.web.type string \"ClusterIP\" Web service type service.web.port int 8888 Web service port Used for the web interface listener service.web.appProtocol string \"http\" Web service appProtocol. Will be auto set to https if certificate is enabled. service.wireguard.annotations object {} Annotations for the WireGuard service service.wireguard.type string \"LoadBalancer\" Wireguard service type service.wireguard.ports list [51820] Wireguard service ports. Exposes the WireGuard ports for created interfaces. Lowerest port is selected as start port for the first interface. Increment next port by 1 for each additional interface. service.metrics.port int 8787 ingress.enabled bool false Specifies whether an ingress resource should be created ingress.className string \"\" Ingress class name ingress.annotations object {} Ingress annotations ingress.tls bool false Ingress TLS configuration. Enable certificate resource or add ingress annotation to create required secret certificate.enabled bool false Specifies whether a certificate resource should be created. If enabled, certificate will be used for the web. certificate.issuer.name string \"\" Certificate issuer name certificate.issuer.kind string \"\" Certificate issuer kind (ClusterIssuer or Issuer) certificate.issuer.group string \"cert-manager.io\" Certificate issuer group certificate.duration string \"\" Optional. Documentation certificate.renewBefore string \"\" Optional. Documentation certificate.commonName string \"\" Optional. Documentation certificate.emailAddresses list [] Optional. Documentation certificate.ipAddresses list [] Optional. Documentation certificate.keystores object {} Optional. Documentation certificate.privateKey object {} Optional. Documentation certificate.secretTemplate object {} Optional. Documentation certificate.subject object {} Optional. Documentation certificate.uris list [] Optional. Documentation certificate.usages list [] Optional. Documentation persistence.enabled bool false Specifies whether an persistent volume should be created persistence.annotations object {} Persistent Volume Claim annotations persistence.storageClass string \"\" Persistent Volume storage class. If undefined (the default) cluster's default provisioner will be used. persistence.accessMode string \"ReadWriteOnce\" Persistent Volume Access Mode persistence.size string \"1Gi\" Persistent Volume size persistence.volumeName string \"\" Persistent Volume Name (optional) serviceAccount.create bool true Specifies whether a service account should be created serviceAccount.annotations object {} Service account annotations serviceAccount.automount bool false Automatically mount a ServiceAccount's API credentials serviceAccount.name string \"\" The name of the service account to use. If not set and create is true, a name is generated using the fullname template monitoring.enabled bool false Enable Prometheus monitoring. monitoring.apiVersion string \"monitoring.coreos.com/v1\" API version of the Prometheus resource. Use azmonitoring.coreos.com/v1 for Azure Managed Prometheus. monitoring.kind string \"PodMonitor\" Kind of the Prometheus resource. Could be PodMonitor or ServiceMonitor. monitoring.labels object {} Resource labels. monitoring.annotations object {} Resource annotations. monitoring.interval string 1m Interval at which metrics should be scraped. If not specified config.statistics.data_collection_interval interval is used. monitoring.metricRelabelings list [] Relabelings to samples before ingestion. monitoring.relabelings list [] Relabelings to samples before scraping. monitoring.scrapeTimeout string \"\" Timeout after which the scrape is ended If not specified, the Prometheus global scrape interval is used. monitoring.jobLabel string \"\" The label to use to retrieve the job name from. monitoring.podTargetLabels object {} Transfers labels on the Kubernetes Pod onto the target. monitoring.dashboard.enabled bool false Enable Grafana dashboard. monitoring.dashboard.annotations object {} Annotations for the dashboard ConfigMap. monitoring.dashboard.labels object {} Additional labels for the dashboard ConfigMap. monitoring.dashboard.namespace string \"\" Dashboard ConfigMap namespace Overrides the namespace for the dashboard ConfigMap."},{"location":"documentation/getting-started/reverse-proxy/","title":"Reverse Proxy (HTTPS)","text":""},{"location":"documentation/getting-started/reverse-proxy/#reverse-proxy-for-https","title":"Reverse Proxy for HTTPS","text":"

    For production deployments, always serve the WireGuard Portal over HTTPS. You have two options to secure your connection:

    "},{"location":"documentation/getting-started/reverse-proxy/#reverse-proxy","title":"Reverse Proxy","text":"

    Let a front\u2010end proxy handle HTTPS for you. This also frees you from managing certificates manually and is therefore the preferred option. You can use Nginx, Traefik, Caddy or any other proxy.

    Below is an example using a Docker Compose stack with Traefik. It exposes the WireGuard Portal on https://wg.domain.com and redirects initial HTTP traffic to HTTPS.

    services:\n  reverse-proxy:\n    image: traefik:v3.3\n    restart: unless-stopped\n    command:\n      #- '--log.level=DEBUG'\n      - '--providers.docker.endpoint=unix:///var/run/docker.sock'\n      - '--providers.docker.exposedbydefault=false'\n      - '--entrypoints.web.address=:80'\n      - '--entrypoints.websecure.address=:443'\n      - '--entrypoints.websecure.http3'\n      - '--certificatesresolvers.letsencryptresolver.acme.httpchallenge=true'\n      - '--certificatesresolvers.letsencryptresolver.acme.httpchallenge.entrypoint=web'\n      - '--certificatesresolvers.letsencryptresolver.acme.email=your.email@domain.com'\n      - '--certificatesresolvers.letsencryptresolver.acme.storage=/letsencrypt/acme.json'\n      #- '--certificatesresolvers.letsencryptresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory'  # just for testing\n    ports:\n      - 80:80 # for HTTP\n      - 443:443/tcp  # for HTTPS\n      - 443:443/udp  # for HTTP/3\n    volumes:\n      - acme-certs:/letsencrypt\n      - /var/run/docker.sock:/var/run/docker.sock:ro\n    labels:\n      - 'traefik.enable=true'\n      # HTTP Catchall for redirecting HTTP -> HTTPS\n      - 'traefik.http.routers.dashboard-catchall.rule=Host(`wg.domain.com`) && PathPrefix(`/`)'\n      - 'traefik.http.routers.dashboard-catchall.entrypoints=web'\n      - 'traefik.http.routers.dashboard-catchall.middlewares=redirect-to-https'\n      - 'traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https'\n\n  wg-portal:\n    image: wgportal/wg-portal:v2\n    container_name: wg-portal\n    restart: unless-stopped\n    logging:\n      options:\n        max-size: \"10m\"\n        max-file: \"3\"\n    cap_add:\n      - NET_ADMIN\n    ports:\n      # host port : container port\n      # WireGuard port, needs to match the port in wg-portal interface config (add one port mapping for each interface)\n      - \"51820:51820/udp\"\n      # Web UI port (only available on localhost, Traefik will handle the HTTPS)\n      - \"127.0.0.1:8888:8888/tcp\"\n    sysctls:\n      - net.ipv4.conf.all.src_valid_mark=1\n    volumes:\n      # host path : container path\n      - ./wg/data:/app/data\n      - ./wg/config:/app/config\n    labels:\n      - 'traefik.enable=true'\n      - 'traefik.http.routers.wgportal.rule=Host(`wg.domain.com`)'\n      - 'traefik.http.routers.wgportal.entrypoints=websecure'\n      - 'traefik.http.routers.wgportal.tls.certresolver=letsencryptresolver'\n      - 'traefik.http.routers.wgportal.service=wgportal'\n      - 'traefik.http.services.wgportal.loadbalancer.server.port=8888'\n\nvolumes:\n  acme-certs:\n

    The WireGuard Portal configuration must be updated accordingly so that the correct external URL is set for the web interface:

    web:\n  external_url: https://wg.domain.com\n
    "},{"location":"documentation/getting-started/reverse-proxy/#built-in-tls","title":"Built-in TLS","text":"

    If you prefer to let WireGuard Portal handle TLS itself, you can use the built-in TLS support. In your config.yaml, under the web section, point to your certificate and key files:

    web:\n  cert_file: /path/to/your/fullchain.pem\n  key_file:  /path/to/your/privkey.pem\n

    The web server will then use these files to serve HTTPS traffic directly instead of HTTP.

    "},{"location":"documentation/getting-started/sources/","title":"Sources","text":"

    To build the application from source files, use the Makefile provided in the repository.

    "},{"location":"documentation/getting-started/sources/#requirements","title":"Requirements","text":"
    • Git
    • Make
    • Go: >=1.24.0
    • Node.js with npm: node>=18, npm>=9
    "},{"location":"documentation/getting-started/sources/#build","title":"Build","text":"
    # Get source code\ngit clone https://github.com/h44z/wg-portal -b ${WG_PORTAL_VERSION:-master} --depth 1\ncd wg-portal\n# Build the frontend\nmake frontend\n# Build the backend\nmake build\n
    "},{"location":"documentation/getting-started/sources/#install","title":"Install","text":"

    Compiled binary will be available in ./dist directory.

    For installation instructions, check the Binaries section.

    "},{"location":"documentation/monitoring/prometheus/","title":"Monitoring","text":"

    By default, WG-Portal exposes Prometheus metrics on port 8787 if interface/peer statistic data collection is enabled.

    "},{"location":"documentation/monitoring/prometheus/#exposed-metrics","title":"Exposed Metrics","text":"Metric Type Description wireguard_interface_received_bytes_total gauge Bytes received through the interface. wireguard_interface_sent_bytes_total gauge Bytes sent through the interface. wireguard_peer_last_handshake_seconds gauge Seconds from the last handshake with the peer. wireguard_peer_received_bytes_total gauge Bytes received from the peer. wireguard_peer_sent_bytes_total gauge Bytes sent to the peer. wireguard_peer_up gauge Peer connection state (boolean: 1/0)."},{"location":"documentation/monitoring/prometheus/#prometheus-config","title":"Prometheus Config","text":"

    Add the following scrape job to your Prometheus config file:

    # prometheus.yaml\nscrape_configs:\n  - job_name: wg-portal\n    scrape_interval: 60s\n    static_configs:\n      - targets:\n          - localhost:8787 # Change localhost to IP Address or hostname with WG-Portal\n
    "},{"location":"documentation/monitoring/prometheus/#grafana-dashboard","title":"Grafana Dashboard","text":"

    You may import dashboard.json into your Grafana instance.

    "},{"location":"documentation/rest-api/api-doc/","title":"REST API","text":""},{"location":"documentation/upgrade/v1/","title":"Upgrade","text":"

    Major upgrades between different versions may require special procedures, which are described in the following sections.

    "},{"location":"documentation/upgrade/v1/#upgrade-from-v1-to-v2","title":"Upgrade from v1 to v2","text":"

    Before upgrading from V1, make sure that you have a backup of your currently working configuration files and database!

    To start the upgrade process, start the wg-portal binary with the -migrateFrom parameter. The configuration (config.yaml) for WireGuard Portal must be updated and valid before starting the upgrade.

    To upgrade from a previous SQLite database, start wg-portal like:

    ./wg-portal-amd64 -migrateFrom=old_wg_portal.db\n

    You can also specify the database type using the parameter -migrateFromType. Supported database types: mysql, mssql, postgres or sqlite.

    For example:

    ./wg-portal-amd64 -migrateFromType=mysql -migrateFrom='user:pass@tcp(1.2.3.4:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local'\n

    The upgrade will transform the old, existing database and store the values in the new database specified in the config.yaml configuration file. Ensure that the new database does not contain any data!

    If you are using Docker, you can adapt the docker-compose.yml file to start the upgrade process:

    services:\n  wg-portal:\n    image: wgportal/wg-portal:v2\n    # ... other settings\n    restart: no\n    command: [\"-migrateFrom=/app/data/old_wg_portal.db\"]\n
    "},{"location":"documentation/usage/general/","title":"General","text":"

    This documentation section describes the general usage of WireGuard Portal. If you are looking for specific setup instructions, please refer to the Getting Started and Configuration sections, for example, using a Docker deployment.

    "},{"location":"documentation/usage/general/#basic-concepts","title":"Basic Concepts","text":"

    WireGuard Portal is a web-based configuration portal for WireGuard server management. It allows managing multiple WireGuard interfaces and users from a single web UI. WireGuard Interfaces can be categorized into three types:

    • Server: A WireGuard server interface that to which multiple peers can connect. In this mode, it is possible to specify default settings for all peers, such as the IP address range, DNS servers, and MTU size.
    • Client: A WireGuard client interface that can be used to connect to a WireGuard server. Usually, such an interface has exactly one peer.
    • Unknown: This is the default type for imported interfaces. It is encouraged to change the type to either Server or Client after importing the interface.
    "},{"location":"documentation/usage/general/#accessing-the-web-ui","title":"Accessing the Web UI","text":"

    The web UI should be accessed via the URL specified in the external_url property of the configuration file. By default, WireGuard Portal listens on port 8888 for HTTP connections. Check the Security section for more information on securing the web UI.

    So the default URL to access the web UI is:

    http://localhost:8888\n

    A freshly set-up WireGuard Portal instance will have a default admin user with the username admin@wgportal.local and the password wgportal-default. You can and should override the default credentials in the configuration file. Make sure to change the default password immediately after the first login!

    "},{"location":"documentation/usage/general/#basic-ui-description","title":"Basic UI Description","text":"

    As seen in the screenshot above, the web UI is divided into several sections which are accessible via the navigation bar on the top of the screen.

    1. Home: The landing page of WireGuard Portal. It provides a staring point for the user to access the different sections of the web UI. It also provides quick links to WireGuard Client downloads or official documentation.
    2. Interfaces: This section allows you to manage the WireGuard interfaces. You can add, edit, or delete interfaces, as well as view their status and statistics. Peers for each interface can be managed here as well.
    3. Users: This section allows you to manage the users of WireGuard Portal. You can add, edit, or delete users, as well as view their status and statistics.
    4. Key Generator: This section allows you to generate WireGuard keys locally on your browser. The generated keys are never sent to the server. This is useful if you want to generate keys for a new peer without having to store the private keys in the database.
    5. Profile / Settings: This section allows you to access your own profile page, settings, and audit logs.
    "},{"location":"documentation/usage/general/#interface-view","title":"Interface View","text":"

    The interface view provides an overview of the WireGuard interfaces and peers configured in WireGuard Portal.

    The most important elements are:

    1. Interface Selector: This dropdown allows you to select the WireGuard interface you want to manage. All further actions will be performed on the selected interface.
    2. Create new Interface: This button allows you to create a new WireGuard interface.
    3. Interface Overview: This section provides an overview of the selected WireGuard interface. It shows the interface type, number of peers, and other important information.
    4. List of Peers: This section provides a list of all peers associated with the selected WireGuard interface. You can view, add, edit, or delete peers from this list.
    5. Add new Peer: This button allows you to add a new peer to the selected WireGuard interface.
    6. Add multiple Peers: This button allows you to add multiple peers to the selected WireGuard interface. This is useful if you want to add a large number of peers at once.
    "},{"location":"documentation/usage/ldap/","title":"LDAP","text":"

    WireGuard Portal lets you hook up any LDAP server such as Active Directory or OpenLDAP for both authentication and user sync. You can even register multiple LDAP servers side-by-side. When someone logs in via LDAP, their specific provider is remembered, so there's no risk of cross-provider conflicts. Details on the log-in process can be found in the Security documentation.

    If you enable LDAP synchronization, all users within the LDAP directory will be created automatically in the WireGuard Portal database if they do not exist. If a user is disabled or deleted in LDAP, the user will be disabled in WireGuard Portal as well. The synchronization process can be fine-tuned by multiple parameters, which are described below.

    "},{"location":"documentation/usage/ldap/#ldap-synchronization","title":"LDAP Synchronization","text":"

    WireGuard Portal can automatically synchronize users from LDAP to the database. To enable this feature, set the sync_interval property in the LDAP provider configuration to a value greater than \"0\". The value is a string representing a duration, such as \"15m\" for 15 minutes or \"1h\" for 1 hour (check the exact format definition for details). The synchronization process will run in the background and synchronize users from LDAP to the database at the specified interval. Also make sure that the sync_filter property is a well-formed LDAP filter, or synchronization will fail.

    "},{"location":"documentation/usage/ldap/#limiting-synchronization-to-specific-users","title":"Limiting Synchronization to Specific Users","text":"

    Use the sync_filter property in your LDAP provider block to restrict which users get synchronized. It accepts any valid LDAP search filter, only entries matching that filter will be pulled into the portal's database.

    For example, to import only users with a mail attribute:

    auth:\n  ldap:\n    - id: ldap\n      # ... other settings\n      sync_filter: (mail=*)\n

    "},{"location":"documentation/usage/ldap/#disable-missing-users","title":"Disable Missing Users","text":"

    If you set the disable_missing property to true, any user that is not found in LDAP during synchronization will be disabled in WireGuard Portal. All peers associated with that user will also be disabled.

    If you want a user and its peers to be automatically re-enabled once they are found in LDAP again, set the auto_re_enable property to true. This will only re-enable the user if they where disabled by the synchronization process. Manually disabled users will not be re-enabled.

    "},{"location":"documentation/usage/security/","title":"Security","text":"

    This section describes the security features available to administrators for hardening WireGuard Portal and protecting its data.

    "},{"location":"documentation/usage/security/#authentication","title":"Authentication","text":"

    WireGuard Portal supports multiple authentication methods, including:

    • Local user accounts
    • LDAP authentication
    • OAuth and OIDC authentication
    • Passkey authentication (WebAuthn)

    Users can have two roles which limit their permissions in WireGuard Portal:

    • User: Can manage their own account and peers.
    • Admin: Can manage all users and peers, including the ability to manage WireGuard interfaces.
    "},{"location":"documentation/usage/security/#password-security","title":"Password Security","text":"

    WireGuard Portal supports username and password authentication for both local and LDAP-backed accounts. Local users are stored in the database, while LDAP users are authenticated against an external LDAP server.

    On initial startup, WireGuard Portal automatically creates a local admin account with the password wgportal-default.

    This password must be changed immediately after the first login.

    The minimum password length for all local users can be configured in the auth section of the configuration file. The default value is 16 characters, see min_password_length. The minimum password length is also enforced for the default admin user.

    "},{"location":"documentation/usage/security/#passkey-webauthn-authentication","title":"Passkey (WebAuthn) Authentication","text":"

    Besides the standard authentication mechanisms, WireGuard Portal supports Passkey authentication. This feature is enabled by default and can be configured in the webauthn section of the configuration file.

    Users can register multiple Passkeys to their account. These Passkeys can be used to log in to the web UI as long as the user is not locked.

    Passkey authentication does not disable password authentication. The password can still be used to log in (e.g., as a fallback).

    To register a Passkey, open the settings page (1) in the web UI and click on the \"Register Passkey\" (2) button.

    "},{"location":"documentation/usage/security/#oauth-and-oidc-authentication","title":"OAuth and OIDC Authentication","text":"

    WireGuard Portal supports OAuth and OIDC authentication. You can use any OAuth or OIDC provider that supports the authorization code flow, such as Google, GitHub, or Keycloak.

    For OAuth or OIDC to work, you need to configure the external_url property in the web section of the configuration file. If you are planning to expose the portal to the internet, make sure that the external_url is configured to use HTTPS.

    To add OIDC or OAuth authentication to WireGuard Portal, create a Client-ID and Client-Secret in your OAuth provider and configure a new authentication provider in the auth section of the configuration file. Make sure that each configured provider has a unique provider_name property set. Samples can be seen here.

    "},{"location":"documentation/usage/security/#limiting-login-to-specific-domains","title":"Limiting Login to Specific Domains","text":"

    You can limit the login to specific domains by setting the allowed_domains property for OAuth or OIDC providers. This property is a comma-separated list of domains that are allowed to log in. The user's email address is checked against this list. For example, if you want to allow only users with an email address ending in outlook.com to log in, set the property as follows:

    auth:\n  oidc:\n    - provider_name: \"oidc1\"\n      # ... other settings\n      allowed_domains:\n        - \"outlook.com\"\n
    "},{"location":"documentation/usage/security/#limit-login-to-existing-users","title":"Limit Login to Existing Users","text":"

    You can limit the login to existing users only by setting the registration_enabled property to false for OAuth or OIDC providers. If registration is enabled, new users will be created in the database when they log in for the first time.

    "},{"location":"documentation/usage/security/#admin-mapping","title":"Admin Mapping","text":"

    You can map users to admin roles based on their attributes in the OAuth or OIDC provider. To do this, set the admin_mapping property for the provider. Administrative access can either be mapped by a specific attribute or by group membership.

    Attribute specific mapping can be achieved by setting the admin_value_regex and the is_admin property. The admin_value_regex property is a regular expression that is matched against the value of the is_admin attribute. The user is granted admin access if the regex matches the attribute value.

    Example:

    auth:\n  oidc:\n    - provider_name: \"oidc1\"\n      # ... other settings\n      field_map:\n        is_admin: \"wg_admin_prop\"\n      admin_mapping:\n        admin_value_regex: \"^true$\"\n
    The example above will grant admin access to users with the wg_admin_prop attribute set to true.

    Group membership mapping can be achieved by setting the admin_group_regex and user_groups property. The admin_group_regex property is a regular expression that is matched against the group names of the user. The user is granted admin access if the regex matches any of the group names.

    Example:

    auth:\n  oidc:\n    - provider_name: \"oidc1\"\n      # ... other settings\n      field_map:\n        user_groups: \"groups\"\n      admin_mapping:\n        admin_group_regex: \"^the-admin-group$\"\n
    The example above will grant admin access to users who are members of the the-admin-group group.

    "},{"location":"documentation/usage/security/#ldap-authentication","title":"LDAP Authentication","text":"

    WireGuard Portal supports LDAP authentication. You can use any LDAP server that supports the LDAP protocol, such as Active Directory or OpenLDAP. Multiple LDAP servers can be configured in the auth section of the configuration file. WireGuard Portal remembers the authentication provider of the user and therefore avoids conflicts between multiple LDAP providers.

    To configure LDAP authentication, create a new ldap authentication provider in the auth section of the configuration file.

    "},{"location":"documentation/usage/security/#limiting-login-to-specific-users","title":"Limiting Login to Specific Users","text":"

    You can limit the login to specific users by setting the login_filter property for LDAP provider. This filter uses the LDAP search filter syntax. The username can be inserted into the query by placing the {{login_identifier}} placeholder in the filter. This placeholder will then be replaced with the username entered by the user during login.

    For example, if you want to allow only users with the objectClass attribute set to organizationalPerson to log in, set the property as follows:

    auth:\n  ldap:\n    - provider_name: \"ldap1\"\n      # ... other settings\n      login_filter: \"(&(objectClass=organizationalPerson)(uid={{login_identifier}}))\"\n

    The login_filter should always be designed to return at most one user.

    "},{"location":"documentation/usage/security/#limit-login-to-existing-users_1","title":"Limit Login to Existing Users","text":"

    You can limit the login to existing users only by setting the registration_enabled property to false for LDAP providers. If registration is enabled, new users will be created in the database when they log in for the first time.

    "},{"location":"documentation/usage/security/#admin-mapping_1","title":"Admin Mapping","text":"

    You can map users to admin roles based on their group membership in the LDAP server. To do this, set the admin_group and memberof property for the provider. The admin_group property defines the distinguished name of the group that is allowed to log in as admin. All groups that are listed in the memberof attribute of the user will be checked against this group. If one of the groups matches, the user is granted admin access.

    "},{"location":"documentation/usage/security/#ui-and-api-access","title":"UI and API Access","text":"

    WireGuard Portal provides a web UI and a REST API for user interaction. It is important to secure these interfaces to prevent unauthorized access and data breaches.

    "},{"location":"documentation/usage/security/#https","title":"HTTPS","text":"

    It is recommended to use HTTPS for all communication with the portal to prevent eavesdropping.

    Event though, WireGuard Portal supports HTTPS out of the box, it is recommended to use a reverse proxy like Nginx or Traefik to handle SSL termination and other security features. A detailed explanation is available in the Reverse Proxy section.

    "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"documentation/overview/","title":"Overview","text":"

    WireGuard Portal is a simple, web-based configuration portal for WireGuard server management. The portal uses the WireGuard wgctrl library to manage existing VPN interfaces. This allows for the seamless activation or deactivation of new users without disturbing existing VPN connections.

    The configuration portal supports using a database (SQLite, MySQL, MsSQL, or Postgres), OAuth or LDAP (Active Directory or OpenLDAP) as a user source for authentication and profile data.

    "},{"location":"documentation/overview/#features","title":"Features","text":"
    • Self-hosted - the whole application is a single binary
    • Responsive multi-language web UI written in Vue.js
    • Automatically selects IP from the network pool assigned to the client
    • QR-Code for convenient mobile client configuration
    • Sends email to the client with QR-code and client config
    • Enable / Disable clients seamlessly
    • Generation of wg-quick configuration file (wgX.conf) if required
    • User authentication (database, OAuth, or LDAP), Passkey support
    • IPv6 ready
    • Docker ready
    • Can be used with existing WireGuard setups
    • Support for multiple WireGuard interfaces
    • Peer Expiry Feature
    • Handles route and DNS settings like wg-quick does
    • Exposes Prometheus metrics for monitoring and alerting
    • REST API for management and client deployment
    • Webhook for custom actions on peer, interface, or user updates
    "},{"location":"documentation/configuration/examples/","title":"Examples","text":"

    Below are some sample YAML configurations demonstrating how to override some default values.

    "},{"location":"documentation/configuration/examples/#basic","title":"Basic","text":"
    core:\n  admin_user: test@example.com\n  admin_password: password\n  admin_api_token: super-s3cr3t-api-token-or-a-UUID\n  import_existing: false\n  create_default_peer: true\n  self_provisioning_allowed: true\n\nweb:\n  site_title: My WireGuard Server\n  site_company_name: My Company\n  listening_address: :8080\n  external_url: https://my.external-domain.com\n  csrf_secret: super-s3cr3t-csrf\n  session_secret: super-s3cr3t-session\n  request_logging: true\n\nadvanced:\n  log_level: trace\n  log_pretty: true\n  log_json: false\n  config_storage_path: /etc/wireguard\n  expiry_check_interval: 5m\n\ndatabase:\n  debug: true\n  type: sqlite\n  dsn: data/sqlite.db\n  encryption_passphrase: change-this-s3cr3t-encryption-passphrase\n\nauth:\n  webauthn:\n    enabled: true\n
    "},{"location":"documentation/configuration/examples/#ldap-authentication-and-synchronization","title":"LDAP Authentication and Synchronization","text":"
    # ... (basic configuration)\n\nauth:\n  ldap:\n    # a sample LDAP provider with user sync enabled\n    - id: ldap\n      provider_name: Active Directory\n      url: ldap://srv-ad1.company.local:389\n      bind_user: ldap_wireguard@company.local\n      bind_pass: super-s3cr3t-ldap\n      base_dn: DC=COMPANY,DC=LOCAL\n      login_filter: (&(objectClass=organizationalPerson)(mail={{login_identifier}})(!userAccountControl:1.2.840.113556.1.4.803:=2))\n      sync_interval: 15m\n      sync_filter: (&(objectClass=organizationalPerson)(!userAccountControl:1.2.840.113556.1.4.803:=2)(mail=*))\n      disable_missing: true\n      field_map:\n        user_identifier: sAMAccountName\n        email: mail\n        firstname: givenName\n        lastname: sn\n        phone: telephoneNumber\n        department: department\n        memberof: memberOf\n      admin_group: CN=WireGuardAdmins,OU=Some-OU,DC=COMPANY,DC=LOCAL\n      registration_enabled: true\n      log_user_info: true\n
    "},{"location":"documentation/configuration/examples/#openid-connect-oidc-authentication","title":"OpenID Connect (OIDC) Authentication","text":"
    # ... (basic configuration)\n\nauth:\n  oidc:\n    # A sample Entra ID provider with environment variable substitution.\n    # Only users with an @outlook.com email address are allowed to register or login.\n    - id: azure\n      provider_name: azure\n      display_name: Login with</br>Entra ID\n      registration_enabled: true\n      base_url: \"https://login.microsoftonline.com/${AZURE_TENANT_ID}/v2.0\"\n      client_id: \"${AZURE_CLIENT_ID}\"\n      client_secret: \"${AZURE_CLIENT_SECRET}\"\n      allowed_domains:\n        - \"outlook.com\"\n      extra_scopes:\n        - profile\n        - email\n\n    # a sample provider where users with the attribute `wg_admin` set to `true` are considered as admins\n    - id: oidc-with-admin-attribute\n      provider_name: google\n      display_name: Login with</br>Google\n      base_url: https://accounts.google.com\n      client_id: the-client-id-1234.apps.googleusercontent.com\n      client_secret: A_CLIENT_SECRET\n      extra_scopes:\n        - https://www.googleapis.com/auth/userinfo.email\n        - https://www.googleapis.com/auth/userinfo.profile\n      field_map:\n        user_identifier: sub\n        email: email\n        firstname: given_name\n        lastname: family_name\n        phone: phone_number\n        department: department\n        is_admin: wg_admin\n      admin_mapping:\n        admin_value_regex: ^true$\n      registration_enabled: true\n      log_user_info: true\n\n    # a sample provider where users in the group `the-admin-group` are considered as admins\n    - id: oidc-with-admin-group\n      provider_name: google2\n      display_name: Login with</br>Google2\n      base_url: https://accounts.google.com\n      client_id: another-client-id-1234.apps.googleusercontent.com\n      client_secret: A_CLIENT_SECRET\n      extra_scopes:\n        - https://www.googleapis.com/auth/userinfo.email\n        - https://www.googleapis.com/auth/userinfo.profile\n      field_map:\n        user_identifier: sub\n        email: email\n        firstname: given_name\n        lastname: family_name\n        phone: phone_number\n        department: department\n        user_groups: groups\n      admin_mapping:\n        admin_group_regex: ^the-admin-group$\n      registration_enabled: true\n      log_user_info: true\n
    "},{"location":"documentation/configuration/examples/#plain-oauth2-authentication","title":"Plain OAuth2 Authentication","text":"
    # ... (basic configuration)\n\nauth:\n  oauth:\n    # a sample provider where users with the attribute `this-attribute-must-be-true` set to `true` or `True`\n    # are considered as admins\n    - id: google_plain_oauth-with-admin-attribute\n      provider_name: google3\n      display_name: Login with</br>Google3\n      client_id: another-client-id-1234.apps.googleusercontent.com\n      client_secret: A_CLIENT_SECRET\n      auth_url: https://accounts.google.com/o/oauth2/v2/auth\n      token_url: https://oauth2.googleapis.com/token\n      user_info_url: https://openidconnect.googleapis.com/v1/userinfo\n      scopes:\n        - openid\n        - email\n        - profile\n      field_map:\n        user_identifier: sub\n        email: email\n        firstname: name\n        is_admin: this-attribute-must-be-true\n      admin_mapping:\n        admin_value_regex: ^(True|true)$\n      registration_enabled: true\n\n    # a sample provider where either users with the attribute `this-attribute-must-be-true` set to `true` or \n    # users in the group `admin-group-name` are considered as admins\n    - id: google_plain_oauth_with_groups\n      provider_name: google4\n      display_name: Login with</br>Google4\n      client_id: another-client-id-1234.apps.googleusercontent.com\n      client_secret: A_CLIENT_SECRET\n      auth_url: https://accounts.google.com/o/oauth2/v2/auth\n      token_url: https://oauth2.googleapis.com/token\n      user_info_url: https://openidconnect.googleapis.com/v1/userinfo\n      scopes:\n        - openid\n        - email\n        - profile\n        - i-want-some-groups\n      field_map:\n        email: email\n        firstname: name\n        user_identifier: sub\n        is_admin: this-attribute-must-be-true\n        user_groups: groups\n      admin_mapping:\n        admin_value_regex: ^true$\n        admin_group_regex: ^admin-group-name$\n      registration_enabled: true\n      log_user_info: true\n
    "},{"location":"documentation/configuration/overview/","title":"Overview","text":"

    This page provides an overview of all available configuration options for WireGuard Portal.

    You can supply these configurations in a YAML file when starting the Portal. The path of the configuration file defaults to config/config.yaml (or config/config.yml) in the working directory of the executable. It is possible to override the configuration filepath using the environment variable WG_PORTAL_CONFIG. For example: WG_PORTAL_CONFIG=/etc/wg-portal/config.yaml ./wg-portal. Also, environment variable substitution in the config file is supported. Refer to the syntax.

    Configuration examples are available on the Examples page.

    Default configuration
    core:\n  admin_user: admin@wgportal.local\n  admin_password: wgportal-default\n  admin_api_token: \"\"\n  editable_keys: true\n  create_default_peer: false\n  create_default_peer_on_creation: false\n  re_enable_peer_after_user_enable: true\n  delete_peer_after_user_deleted: false\n  self_provisioning_allowed: false\n  import_existing: true\n  restore_state: true\n\nadvanced:\n  log_level: info\n  log_pretty: false\n  log_json: false\n  start_listen_port: 51820\n  start_cidr_v4: 10.11.12.0/24\n  start_cidr_v6: fdfd:d3ad:c0de:1234::0/64\n  use_ip_v6: true\n  config_storage_path: \"\"\n  expiry_check_interval: 15m\n  rule_prio_offset: 20000\n  route_table_offset: 20000\n  api_admin_only: true\n  limit_additional_user_peers: 0\n\ndatabase:\n  debug: false\n  slow_query_threshold: \"0\"\n  type: sqlite\n  dsn: data/sqlite.db\n  encryption_passphrase: \"\"\n\nstatistics:\n  use_ping_checks: true\n  ping_check_workers: 10\n  ping_unprivileged: false\n  ping_check_interval: 1m\n  data_collection_interval: 1m\n  collect_interface_data: true\n  collect_peer_data: true\n  collect_audit_data: true\n  listening_address: :8787\n\nmail:\n  host: 127.0.0.1\n  port: 25\n  encryption: none\n  cert_validation: true\n  username: \"\"\n  password: \"\"\n  auth_type: plain\n  from: Wireguard Portal <noreply@wireguard.local>\n  link_only: false\n\nauth:\n  oidc: []\n  oauth: []\n  ldap: []\n  webauthn:\n    enabled: true\n  min_password_length: 16\n\nweb:\n  listening_address: :8888\n  external_url: http://localhost:8888\n  site_company_name: WireGuard Portal\n  site_title: WireGuard Portal\n  session_identifier: wgPortalSession\n  session_secret: very_secret\n  csrf_secret: extremely_secret\n  request_logging: false\n  expose_host_info: false\n  cert_file: \"\"\n  key_File: \"\"\n\nwebhook:\n  url: \"\"\n  authentication: \"\"\n  timeout: 10s\n

    Below you will find sections like core, advanced, database, statistics, mail, auth, web and webhook. Each section describes the individual configuration keys, their default values, and a brief explanation of their purpose.

    "},{"location":"documentation/configuration/overview/#core","title":"Core","text":"

    These are the primary configuration options that control fundamental WireGuard Portal behavior. More advanced options are found in the subsequent Advanced section.

    "},{"location":"documentation/configuration/overview/#admin_user","title":"admin_user","text":"
    • Default: admin@wgportal.local
    • Description: The administrator user. This user will be created as a default admin if it does not yet exist.
    "},{"location":"documentation/configuration/overview/#admin_password","title":"admin_password","text":"
    • Default: wgportal-default
    • Description: The administrator password. The default password should be changed immediately!
    • Important: The password should be strong and secure. The minimum password length is specified in auth.min_password_length. By default, it is 16 characters.
    "},{"location":"documentation/configuration/overview/#admin_api_token","title":"admin_api_token","text":"
    • Default: (empty)
    • Description: 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.
    "},{"location":"documentation/configuration/overview/#editable_keys","title":"editable_keys","text":"
    • Default: true
    • Description: Allow editing of WireGuard key-pairs directly in the UI.
    "},{"location":"documentation/configuration/overview/#create_default_peer","title":"create_default_peer","text":"
    • Default: false
    • Description: If a user logs in for the first time with no existing peers, automatically create a new WireGuard peer for all server interfaces.
    "},{"location":"documentation/configuration/overview/#create_default_peer_on_creation","title":"create_default_peer_on_creation","text":"
    • Default: false
    • Description: If an LDAP user is created (e.g., through LDAP sync) and has no peers, automatically create a new WireGuard peer for all server interfaces.
    "},{"location":"documentation/configuration/overview/#re_enable_peer_after_user_enable","title":"re_enable_peer_after_user_enable","text":"
    • Default: true
    • Description: Re-enable all peers that were previously disabled if the associated user is re-enabled.
    "},{"location":"documentation/configuration/overview/#delete_peer_after_user_deleted","title":"delete_peer_after_user_deleted","text":"
    • Default: false
    • Description: If a user is deleted, remove all linked peers. Otherwise, peers remain but are disabled.
    "},{"location":"documentation/configuration/overview/#self_provisioning_allowed","title":"self_provisioning_allowed","text":"
    • Default: false
    • Description: Allow registered (non-admin) users to self-provision peers from their profile page.
    "},{"location":"documentation/configuration/overview/#import_existing","title":"import_existing","text":"
    • Default: true
    • Description: On startup, import existing WireGuard interfaces and peers into WireGuard Portal.
    "},{"location":"documentation/configuration/overview/#restore_state","title":"restore_state","text":"
    • Default: true
    • Description: Restore the WireGuard interface states (up/down) that existed before WireGuard Portal started.
    "},{"location":"documentation/configuration/overview/#advanced","title":"Advanced","text":"

    Additional or more specialized configuration options for logging and interface creation details.

    "},{"location":"documentation/configuration/overview/#log_level","title":"log_level","text":"
    • Default: info
    • Description: The log level used by the application. Valid options are: trace, debug, info, warn, error.
    "},{"location":"documentation/configuration/overview/#log_pretty","title":"log_pretty","text":"
    • Default: false
    • Description: If true, log messages are colorized and formatted for readability (pretty-print).
    "},{"location":"documentation/configuration/overview/#log_json","title":"log_json","text":"
    • Default: false
    • Description: If true, log messages are structured in JSON format.
    "},{"location":"documentation/configuration/overview/#start_listen_port","title":"start_listen_port","text":"
    • Default: 51820
    • Description: The first port to use when automatically creating new WireGuard interfaces.
    "},{"location":"documentation/configuration/overview/#start_cidr_v4","title":"start_cidr_v4","text":"
    • Default: 10.11.12.0/24
    • Description: The initial IPv4 subnet to use when automatically creating new WireGuard interfaces.
    "},{"location":"documentation/configuration/overview/#start_cidr_v6","title":"start_cidr_v6","text":"
    • Default: fdfd:d3ad:c0de:1234::0/64
    • Description: The initial IPv6 subnet to use when automatically creating new WireGuard interfaces.
    "},{"location":"documentation/configuration/overview/#use_ip_v6","title":"use_ip_v6","text":"
    • Default: true
    • Description: Enable or disable IPv6 support.
    "},{"location":"documentation/configuration/overview/#config_storage_path","title":"config_storage_path","text":"
    • Default: (empty)
    • Description: Path to a directory where wg-quick style configuration files will be stored (if you need local filesystem configs).
    "},{"location":"documentation/configuration/overview/#expiry_check_interval","title":"expiry_check_interval","text":"
    • Default: 15m
    • Description: Interval after which existing peers are checked if they are expired. Format uses s, m, h, d for seconds, minutes, hours, days, see time.ParseDuration.
    "},{"location":"documentation/configuration/overview/#rule_prio_offset","title":"rule_prio_offset","text":"
    • Default: 20000
    • Description: Offset for IP route rule priorities when configuring routing.
    "},{"location":"documentation/configuration/overview/#route_table_offset","title":"route_table_offset","text":"
    • Default: 20000
    • Description: Offset for IP route table IDs when configuring routing.
    "},{"location":"documentation/configuration/overview/#api_admin_only","title":"api_admin_only","text":"
    • Default: true
    • Description: If true, the public REST API is accessible only to admin users. The API docs live at /api/v1/doc.html.
    "},{"location":"documentation/configuration/overview/#limit_additional_user_peers","title":"limit_additional_user_peers","text":"
    • Default: 0
    • Description: Limit additional peers a normal user can create. 0 means unlimited.
    "},{"location":"documentation/configuration/overview/#database","title":"Database","text":"

    Configuration for the underlying database used by WireGuard Portal. Supported databases include SQLite, MySQL, Microsoft SQL Server, and Postgres.

    If sensitive values (like private keys) should be stored in an encrypted format, set the encryption_passphrase option.

    "},{"location":"documentation/configuration/overview/#debug","title":"debug","text":"
    • Default: false
    • Description: If true, logs all database statements (verbose).
    "},{"location":"documentation/configuration/overview/#slow_query_threshold","title":"slow_query_threshold","text":"
    • Default: \"0\"
    • Description: A time threshold (e.g., 100ms) above which queries are considered slow and logged as warnings. If zero, slow query logging is disabled. Format uses s, ms for seconds, milliseconds, see time.ParseDuration. The value must be a string.
    "},{"location":"documentation/configuration/overview/#type","title":"type","text":"
    • Default: sqlite
    • Description: The database type. Valid options: sqlite, mssql, mysql, postgres.
    "},{"location":"documentation/configuration/overview/#dsn","title":"dsn","text":"
    • Default: data/sqlite.db
    • Description: The Data Source Name (DSN) for connecting to the database. For example:
      user:pass@tcp(1.2.3.4:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local\n
    "},{"location":"documentation/configuration/overview/#encryption_passphrase","title":"encryption_passphrase","text":"
    • Default: (empty)
    • Description: Passphrase for encrypting sensitive values such as private keys in the database. Encryption is only applied if this passphrase is set. Important: 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\u2019s next modified.
    "},{"location":"documentation/configuration/overview/#statistics","title":"Statistics","text":"

    Controls how WireGuard Portal collects and reports usage statistics, including ping checks and Prometheus metrics.

    "},{"location":"documentation/configuration/overview/#use_ping_checks","title":"use_ping_checks","text":"
    • Default: true
    • Description: Enable periodic ping checks to verify that peers remain responsive.
    "},{"location":"documentation/configuration/overview/#ping_check_workers","title":"ping_check_workers","text":"
    • Default: 10
    • Description: Number of parallel worker processes for ping checks.
    "},{"location":"documentation/configuration/overview/#ping_unprivileged","title":"ping_unprivileged","text":"
    • Default: false
    • Description: If false, ping checks run without root privileges. This is currently considered BETA.
    "},{"location":"documentation/configuration/overview/#ping_check_interval","title":"ping_check_interval","text":"
    • Default: 1m
    • Description: Interval between consecutive ping checks for all peers. Format uses s, m, h, d for seconds, minutes, hours, days, see time.ParseDuration.
    "},{"location":"documentation/configuration/overview/#data_collection_interval","title":"data_collection_interval","text":"
    • Default: 1m
    • Description: Interval between data collection cycles (bytes sent/received, handshake times, etc.). Format uses s, m, h, d for seconds, minutes, hours, days, see time.ParseDuration.
    "},{"location":"documentation/configuration/overview/#collect_interface_data","title":"collect_interface_data","text":"
    • Default: true
    • Description: If true, collects interface-level data (bytes in/out) for monitoring and statistics.
    "},{"location":"documentation/configuration/overview/#collect_peer_data","title":"collect_peer_data","text":"
    • Default: true
    • Description: If true, collects peer-level data (bytes, last handshake, endpoint, etc.).
    "},{"location":"documentation/configuration/overview/#collect_audit_data","title":"collect_audit_data","text":"
    • Default: true
    • Description: If true, logs certain portal events (such as user logins) to the database.
    "},{"location":"documentation/configuration/overview/#listening_address","title":"listening_address","text":"
    • Default: :8787
    • Description: Address and port for the integrated Prometheus metric server (e.g., :8787 or 127.0.0.1:8787).
    "},{"location":"documentation/configuration/overview/#mail","title":"Mail","text":"

    Options for configuring email notifications or sending peer configurations via email.

    "},{"location":"documentation/configuration/overview/#host","title":"host","text":"
    • Default: 127.0.0.1
    • Description: Hostname or IP of the SMTP server.
    "},{"location":"documentation/configuration/overview/#port","title":"port","text":"
    • Default: 25
    • Description: Port number for the SMTP server.
    "},{"location":"documentation/configuration/overview/#encryption","title":"encryption","text":"
    • Default: none
    • Description: SMTP encryption type. Valid values: none, tls, starttls.
    "},{"location":"documentation/configuration/overview/#cert_validation","title":"cert_validation","text":"
    • Default: true
    • Description: If true, validate the SMTP server certificate (relevant if encryption = tls).
    "},{"location":"documentation/configuration/overview/#username","title":"username","text":"
    • Default: (empty)
    • Description: Optional SMTP username for authentication.
    "},{"location":"documentation/configuration/overview/#password","title":"password","text":"
    • Default: (empty)
    • Description: Optional SMTP password for authentication.
    "},{"location":"documentation/configuration/overview/#auth_type","title":"auth_type","text":"
    • Default: plain
    • Description: SMTP authentication type. Valid values: plain, login, crammd5.
    "},{"location":"documentation/configuration/overview/#from","title":"from","text":"
    • Default: Wireguard Portal <noreply@wireguard.local>
    • Description: The default \"From\" address when sending emails.
    "},{"location":"documentation/configuration/overview/#link_only","title":"link_only","text":"
    • Default: false
    • Description: If true, emails only contain a link to WireGuard Portal, rather than attaching the full configuration.
    "},{"location":"documentation/configuration/overview/#auth","title":"Auth","text":"

    WireGuard Portal supports multiple authentication strategies, including OpenID Connect (oidc), OAuth (oauth), Passkeys (webauthn) and LDAP (ldap). Each can have multiple providers configured. Below are the relevant keys.

    Some core authentication options are shared across all providers, while others are specific to each provider type.

    "},{"location":"documentation/configuration/overview/#min_password_length","title":"min_password_length","text":"
    • Default: 16
    • Description: Minimum password length for local authentication. This is not enforced for LDAP authentication. The default admin password strength is also enforced by this setting.
    • Important: The password should be strong and secure. It is recommended to use a password with at least 16 characters, including uppercase and lowercase letters, numbers, and special characters.
    "},{"location":"documentation/configuration/overview/#oidc","title":"OIDC","text":"

    The oidc array contains a list of OpenID Connect providers. Below are the properties for each OIDC provider entry inside auth.oidc:

    "},{"location":"documentation/configuration/overview/#provider_name","title":"provider_name","text":"
    • Default: (empty)
    • Description: A unique name for this provider. Must not conflict with other providers.
    "},{"location":"documentation/configuration/overview/#display_name","title":"display_name","text":"
    • Default: (empty)
    • Description: A user-friendly name shown on the login page (e.g., \"Login with Google\").
    "},{"location":"documentation/configuration/overview/#base_url","title":"base_url","text":"
    • Default: (empty)
    • Description: The OIDC provider\u2019s base URL (e.g., https://accounts.google.com).
    "},{"location":"documentation/configuration/overview/#client_id","title":"client_id","text":"
    • Default: (empty)
    • Description: The OAuth client ID from the OIDC provider.
    "},{"location":"documentation/configuration/overview/#client_secret","title":"client_secret","text":"
    • Default: (empty)
    • Description: The OAuth client secret from the OIDC provider.
    "},{"location":"documentation/configuration/overview/#extra_scopes","title":"extra_scopes","text":"
    • Default: (empty)
    • Description: A list of additional OIDC scopes (e.g., profile, email).
    "},{"location":"documentation/configuration/overview/#allowed_domains","title":"allowed_domains","text":"
    • Default: (empty)
    • Description: A list of allowlisted domains. Only users with email addresses in these domains can log in or register. This is useful for restricting access to specific organizations or groups.
    "},{"location":"documentation/configuration/overview/#field_map","title":"field_map","text":"
    • Default: (empty)
    • Description: Maps OIDC claims to WireGuard Portal user fields.
    • Available fields: user_identifier, email, firstname, lastname, phone, department, is_admin, user_groups.

      Field Typical OIDC Claim Explanation user_identifier sub or preferred_username A unique identifier for the user. Often the OIDC sub claim is used because it\u2019s guaranteed to be unique for the user within the IdP. Some providers also support preferred_username if it\u2019s unique. email email The user\u2019s email address as provided by the IdP. Not always verified, depending on IdP settings. firstname given_name The user\u2019s first name, typically provided by the IdP in the given_name claim. lastname family_name The user\u2019s last (family) name, typically provided by the IdP in the family_name claim. phone phone_number The user\u2019s phone number. This may require additional scopes/permissions from the IdP to access. department Custom claim (e.g., department) If the IdP can provide organizational data, it may store it in a custom claim. Adjust accordingly (e.g., department, org, or another attribute). is_admin Custom claim or derived role If the IdP returns a role or admin flag, you can map that to is_admin. Often this is managed through custom claims or group membership. user_groups groups or another custom claim A list of group memberships for the user. Some IdPs provide groups out of the box; others require custom claims or directory lookups.
    "},{"location":"documentation/configuration/overview/#admin_mapping","title":"admin_mapping","text":"
    • Default: (empty)
    • Description: WgPortal can grant a user admin rights by matching the value of the is_admin claim against a regular expression. Alternatively, a regular expression can be used to check if a user is member of a specific group listed in the user_group claim. The regular expressions are defined in admin_value_regex and admin_group_regex.
      • admin_value_regex: A regular expression to match the is_admin claim. By default, this expression matches the string \"true\" (^true$).
      • admin_group_regex: A regular expression to match the user_groups claim. Each entry in the user_groups claim is checked against this regex.
    "},{"location":"documentation/configuration/overview/#registration_enabled","title":"registration_enabled","text":"
    • Default: (empty)
    • Description: If true, a new user will be created in WireGuard Portal if not already present.
    "},{"location":"documentation/configuration/overview/#log_user_info","title":"log_user_info","text":"
    • Default: (empty)
    • Description: If true, OIDC user data is logged at the trace level upon login (for debugging).
    "},{"location":"documentation/configuration/overview/#oauth","title":"OAuth","text":"

    The oauth array contains a list of plain OAuth2 providers. Below are the properties for each OAuth provider entry inside auth.oauth:

    "},{"location":"documentation/configuration/overview/#provider_name_1","title":"provider_name","text":"
    • Default: (empty)
    • Description: A unique name for this provider. Must not conflict with other providers.
    "},{"location":"documentation/configuration/overview/#display_name_1","title":"display_name","text":"
    • Default: (empty)
    • Description: A user-friendly name shown on the login page.
    "},{"location":"documentation/configuration/overview/#client_id_1","title":"client_id","text":"
    • Default: (empty)
    • Description: The OAuth client ID for the provider.
    "},{"location":"documentation/configuration/overview/#client_secret_1","title":"client_secret","text":"
    • Default: (empty)
    • Description: The OAuth client secret for the provider.
    "},{"location":"documentation/configuration/overview/#auth_url","title":"auth_url","text":"
    • Default: (empty)
    • Description: URL of the authentication endpoint.
    "},{"location":"documentation/configuration/overview/#token_url","title":"token_url","text":"
    • Default: (empty)
    • Description: URL of the token endpoint.
    "},{"location":"documentation/configuration/overview/#user_info_url","title":"user_info_url","text":"
    • Default: (empty)
    • Description: URL of the user information endpoint.
    "},{"location":"documentation/configuration/overview/#scopes","title":"scopes","text":"
    • Default: (empty)
    • Description: A list of OAuth scopes.
    "},{"location":"documentation/configuration/overview/#allowed_domains_1","title":"allowed_domains","text":"
    • Default: (empty)
    • Description: A list of allowlisted domains. Only users with email addresses in these domains can log in or register. This is useful for restricting access to specific organizations or groups.
    "},{"location":"documentation/configuration/overview/#field_map_1","title":"field_map","text":"
    • Default: (empty)
    • Description: Maps OAuth attributes to WireGuard Portal fields.
    • Available fields: user_identifier, email, firstname, lastname, phone, department, is_admin, user_groups.

      Field Typical Claim Explanation user_identifier sub or preferred_username A unique identifier for the user. Often the OIDC sub claim is used because it\u2019s guaranteed to be unique for the user within the IdP. Some providers also support preferred_username if it\u2019s unique. email email The user\u2019s email address as provided by the IdP. Not always verified, depending on IdP settings. firstname given_name The user\u2019s first name, typically provided by the IdP in the given_name claim. lastname family_name The user\u2019s last (family) name, typically provided by the IdP in the family_name claim. phone phone_number The user\u2019s phone number. This may require additional scopes/permissions from the IdP to access. department Custom claim (e.g., department) If the IdP can provide organizational data, it may store it in a custom claim. Adjust accordingly (e.g., department, org, or another attribute). is_admin Custom claim or derived role If the IdP returns a role or admin flag, you can map that to is_admin. Often this is managed through custom claims or group membership. user_groups groups or another custom claim A list of group memberships for the user. Some IdPs provide groups out of the box; others require custom claims or directory lookups.
    "},{"location":"documentation/configuration/overview/#admin_mapping_1","title":"admin_mapping","text":"
    • Default: (empty)
    • Description: WgPortal can grant a user admin rights by matching the value of the is_admin claim against a regular expression. Alternatively, a regular expression can be used to check if a user is member of a specific group listed in the user_group claim. The regular expressions are defined in admin_value_regex and admin_group_regex.
    • admin_value_regex: A regular expression to match the is_admin claim. By default, this expression matches the string \"true\" (^true$).
    • admin_group_regex: A regular expression to match the user_groups claim. Each entry in the user_groups claim is checked against this regex.
    "},{"location":"documentation/configuration/overview/#registration_enabled_1","title":"registration_enabled","text":"
    • Default: (empty)
    • Description: If true, new users are created automatically on successful login.
    "},{"location":"documentation/configuration/overview/#log_user_info_1","title":"log_user_info","text":"
    • Default: (empty)
    • Description: If true, logs user info at the trace level upon login.
    "},{"location":"documentation/configuration/overview/#ldap","title":"LDAP","text":"

    The ldap array contains a list of LDAP authentication providers. Below are the properties for each LDAP provider entry inside auth.ldap:

    "},{"location":"documentation/configuration/overview/#provider_name_2","title":"provider_name","text":"
    • Default: (empty)
    • Description: A unique name for this provider. Must not conflict with other providers.
    "},{"location":"documentation/configuration/overview/#url","title":"url","text":"
    • Default: (empty)
    • Description: The LDAP server URL (e.g., ldap://srv-ad01.company.local:389).
    "},{"location":"documentation/configuration/overview/#start_tls","title":"start_tls","text":"
    • Default: (empty)
    • Description: If true, use STARTTLS to secure the LDAP connection.
    "},{"location":"documentation/configuration/overview/#cert_validation_1","title":"cert_validation","text":"
    • Default: (empty)
    • Description: If true, validate the LDAP server\u2019s TLS certificate.
    "},{"location":"documentation/configuration/overview/#tls_certificate_path","title":"tls_certificate_path","text":"
    • Default: (empty)
    • Description: Path to a TLS certificate if needed for LDAP connections.
    "},{"location":"documentation/configuration/overview/#tls_key_path","title":"tls_key_path","text":"
    • Default: (empty)
    • Description: Path to the corresponding TLS certificate key.
    "},{"location":"documentation/configuration/overview/#base_dn","title":"base_dn","text":"
    • Default: (empty)
    • Description: The base DN for user searches (e.g., DC=COMPANY,DC=LOCAL).
    "},{"location":"documentation/configuration/overview/#bind_user","title":"bind_user","text":"
    • Default: (empty)
    • Description: The bind user for LDAP (e.g., company\\\\ldap_wireguard or ldap_wireguard@company.local).
    "},{"location":"documentation/configuration/overview/#bind_pass","title":"bind_pass","text":"
    • Default: (empty)
    • Description: The bind password for LDAP authentication.
    "},{"location":"documentation/configuration/overview/#field_map_2","title":"field_map","text":"
    • Default: (empty)
    • Description: Maps LDAP attributes to WireGuard Portal fields.

      • Available fields: user_identifier, email, firstname, lastname, phone, department, memberof.
      WireGuard Portal Field Typical LDAP Attribute Short Description user_identifier sAMAccountName / uid Uniquely identifies the user within the LDAP directory. email mail / userPrincipalName Stores the user's primary email address. firstname givenName Contains the user's first (given) name. lastname sn Contains the user's last (surname) name. phone telephoneNumber / mobile Holds the user's phone or mobile number. department departmentNumber / ou Specifies the department or organizational unit of the user. memberof memberOf Lists the groups and roles to which the user belongs.
    "},{"location":"documentation/configuration/overview/#login_filter","title":"login_filter","text":"
    • Default: (empty)
    • Description: An LDAP filter to restrict which users can log in. Use {{login_identifier}} to insert the username. For example:
      (&(objectClass=organizationalPerson)(mail={{login_identifier}})(!userAccountControl:1.2.840.113556.1.4.803:=2))\n
    • Important: The login_filter 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.
    "},{"location":"documentation/configuration/overview/#admin_group","title":"admin_group","text":"
    • Default: (empty)
    • Description: A specific LDAP group whose members are considered administrators in WireGuard Portal. For example:
      CN=WireGuardAdmins,OU=Some-OU,DC=YOURDOMAIN,DC=LOCAL\n
    "},{"location":"documentation/configuration/overview/#sync_interval","title":"sync_interval","text":"
    • Default: (empty)
    • Description: How frequently (in duration, e.g. 30m) to synchronize users from LDAP. Empty or 0 disables sync. Format uses s, m, h, d for seconds, minutes, hours, days, see time.ParseDuration. Only users that match the sync_filter are synchronized, if disable_missing is true, users not found in LDAP are disabled.
    "},{"location":"documentation/configuration/overview/#sync_filter","title":"sync_filter","text":"
    • Default: (empty)
    • Description: An LDAP filter to select which users get synchronized into WireGuard Portal. For example:
      (&(objectClass=organizationalPerson)(!userAccountControl:1.2.840.113556.1.4.803:=2)(mail=*))\n
    "},{"location":"documentation/configuration/overview/#disable_missing","title":"disable_missing","text":"
    • Default: (empty)
    • Description: If true, any user not found in LDAP (during sync) is disabled in WireGuard Portal.
    "},{"location":"documentation/configuration/overview/#auto_re_enable","title":"auto_re_enable","text":"
    • Default: (empty)
    • Description: If true, users that where disabled because they were missing (see disable_missing) will be re-enabled once they are found again.
    "},{"location":"documentation/configuration/overview/#registration_enabled_2","title":"registration_enabled","text":"
    • Default: (empty)
    • Description: If true, new user accounts are created in WireGuard Portal upon first login.
    "},{"location":"documentation/configuration/overview/#log_user_info_2","title":"log_user_info","text":"
    • Default: (empty)
    • Description: If true, logs LDAP user data at the trace level upon login.
    "},{"location":"documentation/configuration/overview/#webauthn-passkeys","title":"WebAuthn (Passkeys)","text":"

    The webauthn section contains configuration options for WebAuthn authentication (passkeys).

    "},{"location":"documentation/configuration/overview/#enabled","title":"enabled","text":"
    • Default: true
    • Description: If true, Passkey authentication is enabled. If false, 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.
    "},{"location":"documentation/configuration/overview/#web","title":"Web","text":"

    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 external_url for the web server, especially if you are using a reverse proxy. Without a valid external_url, the login process may fail due to CSRF protection.

    "},{"location":"documentation/configuration/overview/#listening_address_1","title":"listening_address","text":"
    • Default: :8888
    • Description: The listening address and port for the web server (e.g., :8888 to bind on all interfaces or 127.0.0.1:8888 to bind only on the loopback interface). Ensure that access to WireGuard Portal is protected against unauthorized access, especially if binding to all interfaces.
    "},{"location":"documentation/configuration/overview/#external_url","title":"external_url","text":"
    • Default: http://localhost:8888
    • Description: The URL where a client can access WireGuard Portal. This URL is used for generating links in emails and for performing OAUTH redirects. Important: If you are using a reverse proxy, set this to the external URL of the reverse proxy, otherwise login will fail. If you access the portal via IP address, set this to the IP address of the server.
    "},{"location":"documentation/configuration/overview/#site_company_name","title":"site_company_name","text":"
    • Default: WireGuard Portal
    • Description: The company name that is shown at the bottom of the web frontend.
    "},{"location":"documentation/configuration/overview/#site_title","title":"site_title","text":"
    • Default: WireGuard Portal
    • Description: The title that is shown in the web frontend.
    "},{"location":"documentation/configuration/overview/#session_identifier","title":"session_identifier","text":"
    • Default: wgPortalSession
    • Description: The session identifier for the web frontend.
    "},{"location":"documentation/configuration/overview/#session_secret","title":"session_secret","text":"
    • Default: very_secret
    • Description: The session secret for the web frontend.
    "},{"location":"documentation/configuration/overview/#csrf_secret","title":"csrf_secret","text":"
    • Default: extremely_secret
    • Description: The CSRF secret.
    "},{"location":"documentation/configuration/overview/#request_logging","title":"request_logging","text":"
    • Default: false
    • Description: Log all HTTP requests.
    "},{"location":"documentation/configuration/overview/#expose_host_info","title":"expose_host_info","text":"
    • Default: false
    • Description: Expose the hostname and version of the WireGuard Portal server in an HTTP header. This is useful for debugging but may expose sensitive information.
    "},{"location":"documentation/configuration/overview/#cert_file","title":"cert_file","text":"
    • Default: (empty)
    • Description: (Optional) Path to the TLS certificate file.
    "},{"location":"documentation/configuration/overview/#key_file","title":"key_file","text":"
    • Default: (empty)
    • Description: (Optional) Path to the TLS certificate key file.
    "},{"location":"documentation/configuration/overview/#webhook","title":"Webhook","text":"

    The webhook section allows you to configure a webhook that is called on certain events in WireGuard Portal. A JSON object is sent in a POST request to the webhook URL with the following structure:

    {\n  \"event\": \"peer_created\",\n  \"entity\": \"peer\",\n  \"identifier\": \"the-peer-identifier\",\n  \"payload\": {\n    // The payload of the event, e.g. peer data.\n    // Check the API documentation for the exact structure.\n  }\n}\n

    "},{"location":"documentation/configuration/overview/#url_1","title":"url","text":"
    • Default: (empty)
    • Description: The POST endpoint to which the webhook is sent. The URL must be reachable from the WireGuard Portal server. If the URL is empty, the webhook is disabled.
    "},{"location":"documentation/configuration/overview/#authentication","title":"authentication","text":"
    • Default: (empty)
    • Description: The Authorization header for the webhook endpoint. The value is send as-is in the header. For example: Bearer <token>.
    "},{"location":"documentation/configuration/overview/#timeout","title":"timeout","text":"
    • Default: 10s
    • Description: The timeout for the webhook request. If the request takes longer than this, it is aborted.
    "},{"location":"documentation/getting-started/binaries/","title":"Binaries","text":"

    Starting from v2, each release includes compiled binaries for supported platforms. These binary versions can be manually downloaded and installed.

    "},{"location":"documentation/getting-started/binaries/#download","title":"Download","text":"

    Make sure that you download the correct binary for your architecture. The available binaries are:

    • wg-portal_linux_amd64 - Linux x86_64
    • wg-portal_linux_arm64 - Linux ARM 64-bit
    • wg-portal_linux_arm_v7 - Linux ARM 32-bit

    With curl:

    curl -L -o wg-portal https://github.com/h44z/wg-portal/releases/download/${WG_PORTAL_VERSION}/wg-portal_linux_amd64 \n

    With wget:

    wget -O wg-portal https://github.com/h44z/wg-portal/releases/download/${WG_PORTAL_VERSION}/wg-portal_linux_amd64\n

    with gh cli:

    gh release download ${WG_PORTAL_VERSION} --repo h44z/wg-portal --output wg-portal --pattern '*amd64'\n
    "},{"location":"documentation/getting-started/binaries/#install","title":"Install","text":"
    sudo mkdir -p /opt/wg-portal\nsudo install wg-portal /opt/wg-portal/\n
    "},{"location":"documentation/getting-started/binaries/#unreleased-versions-master-branch-builds","title":"Unreleased versions (master branch builds)","text":"

    Unreleased versions can be fetched directly from the artifacts section of the GitHub Workflow.

    "},{"location":"documentation/getting-started/docker/","title":"Docker","text":""},{"location":"documentation/getting-started/docker/#image-usage","title":"Image Usage","text":"

    The WireGuard Portal Docker image is available on both Docker Hub and GitHub Container Registry. It is built on the official Alpine Linux base image and comes pre-packaged with all necessary WireGuard dependencies.

    This container allows you to establish WireGuard VPN connections without relying on a host system that supports WireGuard or using the linuxserver/wireguard Docker image.

    The recommended method for deploying WireGuard Portal is via Docker Compose for ease of configuration and management.

    A sample docker-compose.yml (managing WireGuard interfaces directly on the host) is provided below:

    ---\nservices:\n  wg-portal:\n    image: wgportal/wg-portal:v2\n    container_name: wg-portal\n    restart: unless-stopped\n    logging:\n      options:\n        max-size: \"10m\"\n        max-file: \"3\"\n    cap_add:\n      - NET_ADMIN\n    # Use host network mode for WireGuard and the UI. Ensure that access to the UI is properly secured.\n    network_mode: \"host\"\n    volumes:\n      # left side is the host path, right side is the container path\n      - /etc/wireguard:/etc/wireguard\n      - ./data:/app/data\n      - ./config:/app/config\n

    By default, the webserver for the UI is listening on port 8888 on all available interfaces.

    Volumes for /app/data and /app/config should be used ensure data persistence across container restarts.

    "},{"location":"documentation/getting-started/docker/#wireguard-interface-handling","title":"WireGuard Interface Handling","text":"

    WireGuard Portal supports managing WireGuard interfaces through three distinct deployment methods, providing flexibility based on your system architecture and operational preferences:

    • Directly on the host system: WireGuard Portal can control WireGuard interfaces natively on the host, without using containers. This setup is ideal for environments where direct access to system networking is preferred. To use this method, you need to set the network mode to host in your docker-compose.yml file.

      services:\n  wg-portal:\n    ...\n    network_mode: \"host\"\n    ...\n

      If host networking is used, the WireGuard Portal UI will be accessible on all the host's IP addresses if the listening address is set to :8888 in the configuration file. To avoid this, you can bind the listening address to a specific IP address, for example, the loopback address (127.0.0.1:8888). It is also possible to deploy firewall rules to restrict access to the WireGuard Portal UI.

    • Within the WireGuard Portal Docker container: WireGuard interfaces can be managed directly from within the WireGuard Portal container itself. This is the recommended approach when running WireGuard Portal via Docker, as it encapsulates all functionality in a single, portable container without requiring a separate WireGuard host or image.

      services:\n  wg-portal:\n    image: wgportal/wg-portal:v2\n    container_name: wg-portal\n    ...\n    cap_add:\n      - NET_ADMIN\n    ports:\n      # host port : container port\n      # WireGuard port, needs to match the port in wg-portal interface config (add one port mapping for each interface)\n      - \"51820:51820/udp\" \n      # Web UI port\n      - \"8888:8888/tcp\"\n    sysctls:\n      - net.ipv4.conf.all.src_valid_mark=1\n    volumes:\n      # host path : container path\n      - ./wg/data:/app/data\n      - ./wg/config:/app/config\n

    • Via a separate Docker container: WireGuard Portal can interface with and control WireGuard running in another Docker container, such as the linuxserver/wireguard image. This method is useful in setups that already use linuxserver/wireguard or where you want to isolate the VPN backend from the portal frontend. For this, you need to set the network mode to service:wireguard in your docker-compose.yml file, wireguard is the service name of your WireGuard container.

      services:\n  wg-portal:\n    image: wgportal/wg-portal:v2\n    container_name: wg-portal\n    ...\n    cap_add:\n      - NET_ADMIN\n    network_mode: \"service:wireguard\" # So we ensure to stay on the same network as the wireguard container.\n    volumes:\n      # host path : container path\n      - ./wg/etc:/etc/wireguard\n      - ./wg/data:/app/data\n      - ./wg/config:/app/config\n\n  wireguard:\n    image: lscr.io/linuxserver/wireguard:latest\n    container_name: wireguard\n    restart: unless-stopped\n    cap_add:\n      - NET_ADMIN\n    ports:\n      # host port : container port\n      - \"51820:51820/udp\" # WireGuard port, needs to match the port in wg-portal interface config\n      - \"8888:8888/tcp\" # Noticed that the port of the web UI is exposed in the wireguard container.\n    volumes:\n      - ./wg/etc:/config/wg_confs # We share the configuration (wgx.conf) between wg-portal and wireguard\n    sysctls:\n      - net.ipv4.conf.all.src_valid_mark=1\n
      As the linuxserver/wireguard image uses wg-quick to manage the interfaces, you need to have at least the following configuration set for WireGuard Portal:
      core:\n  # The WireGuard container uses wg-quick to manage the WireGuard interfaces - this conflicts with WireGuard Portal during startup.\n  # To avoid this, we need to set the restore_state option to false so that wg-quick can create the interfaces.\n  restore_state: false\n  # Usually, there are no existing interfaces in the WireGuard container, so we can set this to false.\n  import_existing: false\nadvanced:\n  # WireGuard Portal needs to export the WireGuard configuration as wg-quick config files so that the WireGuard container can use them.\n  config_storage_path: /etc/wireguard/\n

    "},{"location":"documentation/getting-started/docker/#image-versioning","title":"Image Versioning","text":"

    All images are hosted on Docker Hub at https://hub.docker.com/r/wgportal/wg-portal or in the GitHub Container Registry.

    Version 2 is the current stable release. Version 1 has moved to legacy status and is no longer recommended.

    There are three types of tags in the repository:

    "},{"location":"documentation/getting-started/docker/#semantic-versioned-tags","title":"Semantic versioned tags","text":"

    For example, 2.0.0-rc.1 or v2.0.0-rc.1.

    These are official releases of WireGuard Portal. For production deployments of WireGuard Portal, we strongly recommend using one of these versioned tags instead of the latest or canary tags.

    There are different types of these tags:

    • Major version tags: v2 or 2. These tags always refer to the latest image for WireGuard Portal version 2.
    • Minor version tags: v2.x or 2.0. These tags always refer to the latest image for WireGuard Portal version 2.x.
    • Specific version tags (patch version): v2.0.0 or 2.0.0. These tags denote a very specific release. They correspond to the GitHub tags that we make, and you can see the release notes for them here: https://github.com/h44z/wg-portal/releases. Once these tags for a specific version show up in the Docker repository, they will never change.
    "},{"location":"documentation/getting-started/docker/#the-latest-tag","title":"The latest tag","text":"

    The lastest tag is the latest stable release of WireGuard Portal. For version 2, this is the same as the v2 tag.

    "},{"location":"documentation/getting-started/docker/#the-master-tag","title":"The master tag","text":"

    This is the most recent build to the main branch! It changes a lot and is very unstable.

    We recommend that you don't use it except for development purposes or to test the latest features.

    "},{"location":"documentation/getting-started/docker/#configuration","title":"Configuration","text":"

    You can configure WireGuard Portal using a YAML configuration file. The filepath of the YAML configuration file defaults to /app/config/config.yaml. It is possible to override the configuration filepath using the environment variable WG_PORTAL_CONFIG.

    By default, WireGuard Portal uses an SQLite database. The database is stored in /app/data/sqlite.db.

    You should mount those directories as a volume:

    • /app/data
    • /app/config

    A detailed description of the configuration options can be found here.

    If you want to access configuration files in wg-quick format, you can mount the /etc/wireguard directory inside the container to a location of your choice. Also enable the config_storage_path option in the configuration file:

    advanced:\n  config_storage_path: /etc/wireguard\n

    "},{"location":"documentation/getting-started/helm/","title":"Helm","text":""},{"location":"documentation/getting-started/helm/#installing-the-chart","title":"Installing the Chart","text":"

    To install the chart with the release name wg-portal:

    helm install wg-portal oci://ghcr.io/h44z/charts/wg-portal\n

    This command deploy wg-portal on the Kubernetes cluster in the default configuration. The Values section lists the parameters that can be configured during installation.

    "},{"location":"documentation/getting-started/helm/#values","title":"Values","text":"Key Type Default Description nameOverride string \"\" Partially override resource names (adds suffix) fullnameOverride string \"\" Fully override resource names extraDeploy list [] Array of extra objects to deploy with the release config.advanced tpl/object {} Advanced configuration options. config.auth tpl/object {} Auth configuration options. config.core tpl/object {} Core configuration options. If external admins in auth are defined and there are no admin_user and admin_password defined here, the default admin account will be disabled. config.database tpl/object {} Database configuration options config.mail tpl/object {} Mail configuration options config.statistics tpl/object {} Statistics configuration options config.web tpl/object {} Web configuration options. listening_address will be set automatically from service.web.port. external_url is required to enable ingress and certificate resources. revisionHistoryLimit string 10 The number of old ReplicaSets to retain to allow rollback. workloadType string \"Deployment\" Workload type - Deployment or StatefulSet strategy object {\"type\":\"RollingUpdate\"} Update strategy for the workload Valid values are: RollingUpdate or Recreate for Deployment, RollingUpdate or OnDelete for StatefulSet image.repository string \"ghcr.io/h44z/wg-portal\" Image repository image.pullPolicy string \"IfNotPresent\" Image pull policy image.tag string \"\" Overrides the image tag whose default is the chart appVersion imagePullSecrets list [] Image pull secrets podAnnotations tpl/object {} Extra annotations to add to the pod podLabels object {} Extra labels to add to the pod podSecurityContext object {} Pod Security Context securityContext.capabilities.add list [\"NET_ADMIN\"] Add capabilities to the container initContainers tpl/list [] Pod init containers sidecarContainers tpl/list [] Pod sidecar containers dnsPolicy string \"ClusterFirst\" Set DNS policy for the pod. Valid values are ClusterFirstWithHostNet, ClusterFirst, Default or None. restartPolicy string \"Always\" Restart policy for all containers within the pod. Valid values are Always, OnFailure or Never. hostNetwork string false. Use the host's network namespace. resources object {} Resources requests and limits command list [] Overwrite pod command args list [] Additional pod arguments env tpl/list [] Additional environment variables envFrom tpl/list [] Additional environment variables from a secret or configMap livenessProbe object {} Liveness probe configuration readinessProbe object {} Readiness probe configuration startupProbe object {} Startup probe configuration volumes tpl/list [] Additional volumes volumeMounts tpl/list [] Additional volumeMounts nodeSelector object {\"kubernetes.io/os\":\"linux\"} Node Selector configuration tolerations list [] Tolerations configuration affinity object {} Affinity configuration service.mixed.enabled bool false Whether to create a single service for the web and wireguard interfaces service.mixed.type string \"LoadBalancer\" Service type service.web.annotations object {} Annotations for the web service service.web.type string \"ClusterIP\" Web service type service.web.port int 8888 Web service port Used for the web interface listener service.web.appProtocol string \"http\" Web service appProtocol. Will be auto set to https if certificate is enabled. service.wireguard.annotations object {} Annotations for the WireGuard service service.wireguard.type string \"LoadBalancer\" Wireguard service type service.wireguard.ports list [51820] Wireguard service ports. Exposes the WireGuard ports for created interfaces. Lowerest port is selected as start port for the first interface. Increment next port by 1 for each additional interface. service.metrics.port int 8787 ingress.enabled bool false Specifies whether an ingress resource should be created ingress.className string \"\" Ingress class name ingress.annotations object {} Ingress annotations ingress.tls bool false Ingress TLS configuration. Enable certificate resource or add ingress annotation to create required secret certificate.enabled bool false Specifies whether a certificate resource should be created. If enabled, certificate will be used for the web. certificate.issuer.name string \"\" Certificate issuer name certificate.issuer.kind string \"\" Certificate issuer kind (ClusterIssuer or Issuer) certificate.issuer.group string \"cert-manager.io\" Certificate issuer group certificate.duration string \"\" Optional. Documentation certificate.renewBefore string \"\" Optional. Documentation certificate.commonName string \"\" Optional. Documentation certificate.emailAddresses list [] Optional. Documentation certificate.ipAddresses list [] Optional. Documentation certificate.keystores object {} Optional. Documentation certificate.privateKey object {} Optional. Documentation certificate.secretTemplate object {} Optional. Documentation certificate.subject object {} Optional. Documentation certificate.uris list [] Optional. Documentation certificate.usages list [] Optional. Documentation persistence.enabled bool false Specifies whether an persistent volume should be created persistence.annotations object {} Persistent Volume Claim annotations persistence.storageClass string \"\" Persistent Volume storage class. If undefined (the default) cluster's default provisioner will be used. persistence.accessMode string \"ReadWriteOnce\" Persistent Volume Access Mode persistence.size string \"1Gi\" Persistent Volume size persistence.volumeName string \"\" Persistent Volume Name (optional) serviceAccount.create bool true Specifies whether a service account should be created serviceAccount.annotations object {} Service account annotations serviceAccount.automount bool false Automatically mount a ServiceAccount's API credentials serviceAccount.name string \"\" The name of the service account to use. If not set and create is true, a name is generated using the fullname template monitoring.enabled bool false Enable Prometheus monitoring. monitoring.apiVersion string \"monitoring.coreos.com/v1\" API version of the Prometheus resource. Use azmonitoring.coreos.com/v1 for Azure Managed Prometheus. monitoring.kind string \"PodMonitor\" Kind of the Prometheus resource. Could be PodMonitor or ServiceMonitor. monitoring.labels object {} Resource labels. monitoring.annotations object {} Resource annotations. monitoring.interval string 1m Interval at which metrics should be scraped. If not specified config.statistics.data_collection_interval interval is used. monitoring.metricRelabelings list [] Relabelings to samples before ingestion. monitoring.relabelings list [] Relabelings to samples before scraping. monitoring.scrapeTimeout string \"\" Timeout after which the scrape is ended If not specified, the Prometheus global scrape interval is used. monitoring.jobLabel string \"\" The label to use to retrieve the job name from. monitoring.podTargetLabels object {} Transfers labels on the Kubernetes Pod onto the target. monitoring.dashboard.enabled bool false Enable Grafana dashboard. monitoring.dashboard.annotations object {} Annotations for the dashboard ConfigMap. monitoring.dashboard.labels object {} Additional labels for the dashboard ConfigMap. monitoring.dashboard.namespace string \"\" Dashboard ConfigMap namespace Overrides the namespace for the dashboard ConfigMap."},{"location":"documentation/getting-started/reverse-proxy/","title":"Reverse Proxy (HTTPS)","text":""},{"location":"documentation/getting-started/reverse-proxy/#reverse-proxy-for-https","title":"Reverse Proxy for HTTPS","text":"

    For production deployments, always serve the WireGuard Portal over HTTPS. You have two options to secure your connection:

    "},{"location":"documentation/getting-started/reverse-proxy/#reverse-proxy","title":"Reverse Proxy","text":"

    Let a front\u2010end proxy handle HTTPS for you. This also frees you from managing certificates manually and is therefore the preferred option. You can use Nginx, Traefik, Caddy or any other proxy.

    Below is an example using a Docker Compose stack with Traefik. It exposes the WireGuard Portal on https://wg.domain.com and redirects initial HTTP traffic to HTTPS.

    services:\n  reverse-proxy:\n    image: traefik:v3.3\n    restart: unless-stopped\n    command:\n      #- '--log.level=DEBUG'\n      - '--providers.docker.endpoint=unix:///var/run/docker.sock'\n      - '--providers.docker.exposedbydefault=false'\n      - '--entrypoints.web.address=:80'\n      - '--entrypoints.websecure.address=:443'\n      - '--entrypoints.websecure.http3'\n      - '--certificatesresolvers.letsencryptresolver.acme.httpchallenge=true'\n      - '--certificatesresolvers.letsencryptresolver.acme.httpchallenge.entrypoint=web'\n      - '--certificatesresolvers.letsencryptresolver.acme.email=your.email@domain.com'\n      - '--certificatesresolvers.letsencryptresolver.acme.storage=/letsencrypt/acme.json'\n      #- '--certificatesresolvers.letsencryptresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory'  # just for testing\n    ports:\n      - 80:80 # for HTTP\n      - 443:443/tcp  # for HTTPS\n      - 443:443/udp  # for HTTP/3\n    volumes:\n      - acme-certs:/letsencrypt\n      - /var/run/docker.sock:/var/run/docker.sock:ro\n    labels:\n      - 'traefik.enable=true'\n      # HTTP Catchall for redirecting HTTP -> HTTPS\n      - 'traefik.http.routers.dashboard-catchall.rule=Host(`wg.domain.com`) && PathPrefix(`/`)'\n      - 'traefik.http.routers.dashboard-catchall.entrypoints=web'\n      - 'traefik.http.routers.dashboard-catchall.middlewares=redirect-to-https'\n      - 'traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https'\n\n  wg-portal:\n    image: wgportal/wg-portal:v2\n    container_name: wg-portal\n    restart: unless-stopped\n    logging:\n      options:\n        max-size: \"10m\"\n        max-file: \"3\"\n    cap_add:\n      - NET_ADMIN\n    ports:\n      # host port : container port\n      # WireGuard port, needs to match the port in wg-portal interface config (add one port mapping for each interface)\n      - \"51820:51820/udp\"\n      # Web UI port (only available on localhost, Traefik will handle the HTTPS)\n      - \"127.0.0.1:8888:8888/tcp\"\n    sysctls:\n      - net.ipv4.conf.all.src_valid_mark=1\n    volumes:\n      # host path : container path\n      - ./wg/data:/app/data\n      - ./wg/config:/app/config\n    labels:\n      - 'traefik.enable=true'\n      - 'traefik.http.routers.wgportal.rule=Host(`wg.domain.com`)'\n      - 'traefik.http.routers.wgportal.entrypoints=websecure'\n      - 'traefik.http.routers.wgportal.tls.certresolver=letsencryptresolver'\n      - 'traefik.http.routers.wgportal.service=wgportal'\n      - 'traefik.http.services.wgportal.loadbalancer.server.port=8888'\n\nvolumes:\n  acme-certs:\n

    The WireGuard Portal configuration must be updated accordingly so that the correct external URL is set for the web interface:

    web:\n  external_url: https://wg.domain.com\n
    "},{"location":"documentation/getting-started/reverse-proxy/#built-in-tls","title":"Built-in TLS","text":"

    If you prefer to let WireGuard Portal handle TLS itself, you can use the built-in TLS support. In your config.yaml, under the web section, point to your certificate and key files:

    web:\n  cert_file: /path/to/your/fullchain.pem\n  key_file:  /path/to/your/privkey.pem\n

    The web server will then use these files to serve HTTPS traffic directly instead of HTTP.

    "},{"location":"documentation/getting-started/sources/","title":"Sources","text":"

    To build the application from source files, use the Makefile provided in the repository.

    "},{"location":"documentation/getting-started/sources/#requirements","title":"Requirements","text":"
    • Git
    • Make
    • Go: >=1.24.0
    • Node.js with npm: node>=18, npm>=9
    "},{"location":"documentation/getting-started/sources/#build","title":"Build","text":"
    # Get source code\ngit clone https://github.com/h44z/wg-portal -b ${WG_PORTAL_VERSION:-master} --depth 1\ncd wg-portal\n# Build the frontend\nmake frontend\n# Build the backend\nmake build\n
    "},{"location":"documentation/getting-started/sources/#install","title":"Install","text":"

    Compiled binary will be available in ./dist directory.

    For installation instructions, check the Binaries section.

    "},{"location":"documentation/monitoring/prometheus/","title":"Monitoring","text":"

    By default, WG-Portal exposes Prometheus metrics on port 8787 if interface/peer statistic data collection is enabled.

    "},{"location":"documentation/monitoring/prometheus/#exposed-metrics","title":"Exposed Metrics","text":"Metric Type Description wireguard_interface_received_bytes_total gauge Bytes received through the interface. wireguard_interface_sent_bytes_total gauge Bytes sent through the interface. wireguard_peer_last_handshake_seconds gauge Seconds from the last handshake with the peer. wireguard_peer_received_bytes_total gauge Bytes received from the peer. wireguard_peer_sent_bytes_total gauge Bytes sent to the peer. wireguard_peer_up gauge Peer connection state (boolean: 1/0)."},{"location":"documentation/monitoring/prometheus/#prometheus-config","title":"Prometheus Config","text":"

    Add the following scrape job to your Prometheus config file:

    # prometheus.yaml\nscrape_configs:\n  - job_name: wg-portal\n    scrape_interval: 60s\n    static_configs:\n      - targets:\n          - localhost:8787 # Change localhost to IP Address or hostname with WG-Portal\n
    "},{"location":"documentation/monitoring/prometheus/#grafana-dashboard","title":"Grafana Dashboard","text":"

    You may import dashboard.json into your Grafana instance.

    "},{"location":"documentation/rest-api/api-doc/","title":"REST API","text":""},{"location":"documentation/upgrade/v1/","title":"Upgrade","text":"

    Major upgrades between different versions may require special procedures, which are described in the following sections.

    "},{"location":"documentation/upgrade/v1/#upgrade-from-v1-to-v2","title":"Upgrade from v1 to v2","text":"

    Before upgrading from V1, make sure that you have a backup of your currently working configuration files and database!

    To start the upgrade process, start the wg-portal binary with the -migrateFrom parameter. The configuration (config.yaml) for WireGuard Portal must be updated and valid before starting the upgrade.

    To upgrade from a previous SQLite database, start wg-portal like:

    ./wg-portal-amd64 -migrateFrom=old_wg_portal.db\n

    You can also specify the database type using the parameter -migrateFromType. Supported database types: mysql, mssql, postgres or sqlite.

    For example:

    ./wg-portal-amd64 -migrateFromType=mysql -migrateFrom='user:pass@tcp(1.2.3.4:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local'\n

    The upgrade will transform the old, existing database and store the values in the new database specified in the config.yaml configuration file. Ensure that the new database does not contain any data!

    If you are using Docker, you can adapt the docker-compose.yml file to start the upgrade process:

    services:\n  wg-portal:\n    image: wgportal/wg-portal:v2\n    # ... other settings\n    restart: no\n    command: [\"-migrateFrom=/app/data/old_wg_portal.db\"]\n
    "},{"location":"documentation/usage/general/","title":"General","text":"

    This documentation section describes the general usage of WireGuard Portal. If you are looking for specific setup instructions, please refer to the Getting Started and Configuration sections, for example, using a Docker deployment.

    "},{"location":"documentation/usage/general/#basic-concepts","title":"Basic Concepts","text":"

    WireGuard Portal is a web-based configuration portal for WireGuard server management. It allows managing multiple WireGuard interfaces and users from a single web UI. WireGuard Interfaces can be categorized into three types:

    • Server: A WireGuard server interface that to which multiple peers can connect. In this mode, it is possible to specify default settings for all peers, such as the IP address range, DNS servers, and MTU size.
    • Client: A WireGuard client interface that can be used to connect to a WireGuard server. Usually, such an interface has exactly one peer.
    • Unknown: This is the default type for imported interfaces. It is encouraged to change the type to either Server or Client after importing the interface.
    "},{"location":"documentation/usage/general/#accessing-the-web-ui","title":"Accessing the Web UI","text":"

    The web UI should be accessed via the URL specified in the external_url property of the configuration file. By default, WireGuard Portal listens on port 8888 for HTTP connections. Check the Security section for more information on securing the web UI.

    So the default URL to access the web UI is:

    http://localhost:8888\n

    A freshly set-up WireGuard Portal instance will have a default admin user with the username admin@wgportal.local and the password wgportal-default. You can and should override the default credentials in the configuration file. Make sure to change the default password immediately after the first login!

    "},{"location":"documentation/usage/general/#basic-ui-description","title":"Basic UI Description","text":"

    As seen in the screenshot above, the web UI is divided into several sections which are accessible via the navigation bar on the top of the screen.

    1. Home: The landing page of WireGuard Portal. It provides a staring point for the user to access the different sections of the web UI. It also provides quick links to WireGuard Client downloads or official documentation.
    2. Interfaces: This section allows you to manage the WireGuard interfaces. You can add, edit, or delete interfaces, as well as view their status and statistics. Peers for each interface can be managed here as well.
    3. Users: This section allows you to manage the users of WireGuard Portal. You can add, edit, or delete users, as well as view their status and statistics.
    4. Key Generator: This section allows you to generate WireGuard keys locally on your browser. The generated keys are never sent to the server. This is useful if you want to generate keys for a new peer without having to store the private keys in the database.
    5. Profile / Settings: This section allows you to access your own profile page, settings, and audit logs.
    "},{"location":"documentation/usage/general/#interface-view","title":"Interface View","text":"

    The interface view provides an overview of the WireGuard interfaces and peers configured in WireGuard Portal.

    The most important elements are:

    1. Interface Selector: This dropdown allows you to select the WireGuard interface you want to manage. All further actions will be performed on the selected interface.
    2. Create new Interface: This button allows you to create a new WireGuard interface.
    3. Interface Overview: This section provides an overview of the selected WireGuard interface. It shows the interface type, number of peers, and other important information.
    4. List of Peers: This section provides a list of all peers associated with the selected WireGuard interface. You can view, add, edit, or delete peers from this list.
    5. Add new Peer: This button allows you to add a new peer to the selected WireGuard interface.
    6. Add multiple Peers: This button allows you to add multiple peers to the selected WireGuard interface. This is useful if you want to add a large number of peers at once.
    "},{"location":"documentation/usage/ldap/","title":"LDAP","text":"

    WireGuard Portal lets you hook up any LDAP server such as Active Directory or OpenLDAP for both authentication and user sync. You can even register multiple LDAP servers side-by-side. When someone logs in via LDAP, their specific provider is remembered, so there's no risk of cross-provider conflicts. Details on the log-in process can be found in the Security documentation.

    If you enable LDAP synchronization, all users within the LDAP directory will be created automatically in the WireGuard Portal database if they do not exist. If a user is disabled or deleted in LDAP, the user will be disabled in WireGuard Portal as well. The synchronization process can be fine-tuned by multiple parameters, which are described below.

    "},{"location":"documentation/usage/ldap/#ldap-synchronization","title":"LDAP Synchronization","text":"

    WireGuard Portal can automatically synchronize users from LDAP to the database. To enable this feature, set the sync_interval property in the LDAP provider configuration to a value greater than \"0\". The value is a string representing a duration, such as \"15m\" for 15 minutes or \"1h\" for 1 hour (check the exact format definition for details). The synchronization process will run in the background and synchronize users from LDAP to the database at the specified interval. Also make sure that the sync_filter property is a well-formed LDAP filter, or synchronization will fail.

    "},{"location":"documentation/usage/ldap/#limiting-synchronization-to-specific-users","title":"Limiting Synchronization to Specific Users","text":"

    Use the sync_filter property in your LDAP provider block to restrict which users get synchronized. It accepts any valid LDAP search filter, only entries matching that filter will be pulled into the portal's database.

    For example, to import only users with a mail attribute:

    auth:\n  ldap:\n    - id: ldap\n      # ... other settings\n      sync_filter: (mail=*)\n

    "},{"location":"documentation/usage/ldap/#disable-missing-users","title":"Disable Missing Users","text":"

    If you set the disable_missing property to true, any user that is not found in LDAP during synchronization will be disabled in WireGuard Portal. All peers associated with that user will also be disabled.

    If you want a user and its peers to be automatically re-enabled once they are found in LDAP again, set the auto_re_enable property to true. This will only re-enable the user if they where disabled by the synchronization process. Manually disabled users will not be re-enabled.

    "},{"location":"documentation/usage/security/","title":"Security","text":"

    This section describes the security features available to administrators for hardening WireGuard Portal and protecting its data.

    "},{"location":"documentation/usage/security/#authentication","title":"Authentication","text":"

    WireGuard Portal supports multiple authentication methods, including:

    • Local user accounts
    • LDAP authentication
    • OAuth and OIDC authentication
    • Passkey authentication (WebAuthn)

    Users can have two roles which limit their permissions in WireGuard Portal:

    • User: Can manage their own account and peers.
    • Admin: Can manage all users and peers, including the ability to manage WireGuard interfaces.
    "},{"location":"documentation/usage/security/#password-security","title":"Password Security","text":"

    WireGuard Portal supports username and password authentication for both local and LDAP-backed accounts. Local users are stored in the database, while LDAP users are authenticated against an external LDAP server.

    On initial startup, WireGuard Portal automatically creates a local admin account with the password wgportal-default.

    This password must be changed immediately after the first login.

    The minimum password length for all local users can be configured in the auth section of the configuration file. The default value is 16 characters, see min_password_length. The minimum password length is also enforced for the default admin user.

    "},{"location":"documentation/usage/security/#passkey-webauthn-authentication","title":"Passkey (WebAuthn) Authentication","text":"

    Besides the standard authentication mechanisms, WireGuard Portal supports Passkey authentication. This feature is enabled by default and can be configured in the webauthn section of the configuration file.

    Users can register multiple Passkeys to their account. These Passkeys can be used to log in to the web UI as long as the user is not locked.

    Passkey authentication does not disable password authentication. The password can still be used to log in (e.g., as a fallback).

    To register a Passkey, open the settings page (1) in the web UI and click on the \"Register Passkey\" (2) button.

    "},{"location":"documentation/usage/security/#oauth-and-oidc-authentication","title":"OAuth and OIDC Authentication","text":"

    WireGuard Portal supports OAuth and OIDC authentication. You can use any OAuth or OIDC provider that supports the authorization code flow, such as Google, GitHub, or Keycloak.

    For OAuth or OIDC to work, you need to configure the external_url property in the web section of the configuration file. If you are planning to expose the portal to the internet, make sure that the external_url is configured to use HTTPS.

    To add OIDC or OAuth authentication to WireGuard Portal, create a Client-ID and Client-Secret in your OAuth provider and configure a new authentication provider in the auth section of the configuration file. Make sure that each configured provider has a unique provider_name property set. Samples can be seen here.

    "},{"location":"documentation/usage/security/#limiting-login-to-specific-domains","title":"Limiting Login to Specific Domains","text":"

    You can limit the login to specific domains by setting the allowed_domains property for OAuth or OIDC providers. This property is a comma-separated list of domains that are allowed to log in. The user's email address is checked against this list. For example, if you want to allow only users with an email address ending in outlook.com to log in, set the property as follows:

    auth:\n  oidc:\n    - provider_name: \"oidc1\"\n      # ... other settings\n      allowed_domains:\n        - \"outlook.com\"\n
    "},{"location":"documentation/usage/security/#limit-login-to-existing-users","title":"Limit Login to Existing Users","text":"

    You can limit the login to existing users only by setting the registration_enabled property to false for OAuth or OIDC providers. If registration is enabled, new users will be created in the database when they log in for the first time.

    "},{"location":"documentation/usage/security/#admin-mapping","title":"Admin Mapping","text":"

    You can map users to admin roles based on their attributes in the OAuth or OIDC provider. To do this, set the admin_mapping property for the provider. Administrative access can either be mapped by a specific attribute or by group membership.

    Attribute specific mapping can be achieved by setting the admin_value_regex and the is_admin property. The admin_value_regex property is a regular expression that is matched against the value of the is_admin attribute. The user is granted admin access if the regex matches the attribute value.

    Example:

    auth:\n  oidc:\n    - provider_name: \"oidc1\"\n      # ... other settings\n      field_map:\n        is_admin: \"wg_admin_prop\"\n      admin_mapping:\n        admin_value_regex: \"^true$\"\n
    The example above will grant admin access to users with the wg_admin_prop attribute set to true.

    Group membership mapping can be achieved by setting the admin_group_regex and user_groups property. The admin_group_regex property is a regular expression that is matched against the group names of the user. The user is granted admin access if the regex matches any of the group names.

    Example:

    auth:\n  oidc:\n    - provider_name: \"oidc1\"\n      # ... other settings\n      field_map:\n        user_groups: \"groups\"\n      admin_mapping:\n        admin_group_regex: \"^the-admin-group$\"\n
    The example above will grant admin access to users who are members of the the-admin-group group.

    "},{"location":"documentation/usage/security/#ldap-authentication","title":"LDAP Authentication","text":"

    WireGuard Portal supports LDAP authentication. You can use any LDAP server that supports the LDAP protocol, such as Active Directory or OpenLDAP. Multiple LDAP servers can be configured in the auth section of the configuration file. WireGuard Portal remembers the authentication provider of the user and therefore avoids conflicts between multiple LDAP providers.

    To configure LDAP authentication, create a new ldap authentication provider in the auth section of the configuration file.

    "},{"location":"documentation/usage/security/#limiting-login-to-specific-users","title":"Limiting Login to Specific Users","text":"

    You can limit the login to specific users by setting the login_filter property for LDAP provider. This filter uses the LDAP search filter syntax. The username can be inserted into the query by placing the {{login_identifier}} placeholder in the filter. This placeholder will then be replaced with the username entered by the user during login.

    For example, if you want to allow only users with the objectClass attribute set to organizationalPerson to log in, set the property as follows:

    auth:\n  ldap:\n    - provider_name: \"ldap1\"\n      # ... other settings\n      login_filter: \"(&(objectClass=organizationalPerson)(uid={{login_identifier}}))\"\n

    The login_filter should always be designed to return at most one user.

    "},{"location":"documentation/usage/security/#limit-login-to-existing-users_1","title":"Limit Login to Existing Users","text":"

    You can limit the login to existing users only by setting the registration_enabled property to false for LDAP providers. If registration is enabled, new users will be created in the database when they log in for the first time.

    "},{"location":"documentation/usage/security/#admin-mapping_1","title":"Admin Mapping","text":"

    You can map users to admin roles based on their group membership in the LDAP server. To do this, set the admin_group and memberof property for the provider. The admin_group property defines the distinguished name of the group that is allowed to log in as admin. All groups that are listed in the memberof attribute of the user will be checked against this group. If one of the groups matches, the user is granted admin access.

    "},{"location":"documentation/usage/security/#ui-and-api-access","title":"UI and API Access","text":"

    WireGuard Portal provides a web UI and a REST API for user interaction. It is important to secure these interfaces to prevent unauthorized access and data breaches.

    "},{"location":"documentation/usage/security/#https","title":"HTTPS","text":"

    It is recommended to use HTTPS for all communication with the portal to prevent eavesdropping.

    Event though, WireGuard Portal supports HTTPS out of the box, it is recommended to use a reverse proxy like Nginx or Traefik to handle SSL termination and other security features. A detailed explanation is available in the Reverse Proxy section.

    "}]} \ No newline at end of file