feat: Implement LDAP interface-specific provisioning filters (#642)
Some checks failed
Docker / Build and Push (push) Has been cancelled
github-pages / deploy (push) Has been cancelled
Docker / release (push) Has been cancelled

* Implement LDAP filter-based access control for interface provisioning

* test: add unit tests for LDAP interface filtering logic

* smaller improvements / cleanup

---------

Co-authored-by: jc <37738506+theguy147@users.noreply.github.com>
Co-authored-by: Christoph Haas <christoph.h@sprinternet.at>
This commit is contained in:
Jacopo Clark
2026-03-19 23:13:19 +01:00
committed by GitHub
parent f70f60a3f5
commit 402cc1b5f3
16 changed files with 339 additions and 18 deletions

View File

@@ -86,6 +86,9 @@ auth:
memberof: memberOf
admin_group: CN=WireGuardAdmins,OU=Some-OU,DC=COMPANY,DC=LOCAL
registration_enabled: true
# Restrict interface access based on LDAP filters
interface_filter:
wg0: "(memberOf=CN=VPNUsers,OU=Groups,DC=COMPANY,DC=LOCAL)"
log_user_info: true
```

View File

@@ -742,6 +742,16 @@ Below are the properties for each LDAP provider entry inside `auth.ldap`:
- **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.
#### `interface_filter`
- **Default:** *(empty)*
- **Description:** A map of LDAP filters to restrict access to specific WireGuard interfaces. The map keys are the interface identifiers (e.g., `wg0`), and the values are LDAP filters. Only users matching the filter will be allowed to provision peers for the respective interface.
For example:
```yaml
interface_filter:
wg0: "(memberOf=CN=VPNUsers,OU=Groups,DC=COMPANY,DC=LOCAL)"
wg1: "(description=special-access)"
```
#### `admin_group`
- **Default:** *(empty)*
- **Description:** A specific LDAP group whose members are considered administrators in WireGuard Portal.

View File

@@ -147,6 +147,26 @@ You can map users to admin roles based on their group membership in the LDAP ser
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.
### Interface-specific Provisioning Filters
You can restrict which users are allowed to provision peers for specific WireGuard interfaces by setting the `interface_filter` property.
This property is a map where each key corresponds to a WireGuard interface identifier, and the value is an LDAP filter.
A user will only be able to see and provision peers for an interface if they match the specified LDAP filter for that interface.
Example:
```yaml
auth:
ldap:
- provider_name: "ldap1"
# ... other settings
interface_filter:
wg0: "(memberOf=CN=VPNUsers,OU=Groups,DC=COMPANY,DC=LOCAL)"
wg1: "(department=IT)"
```
This feature works by materializing the list of authorized users for each interface during the periodic LDAP synchronization.
Even if a user bypasses the UI, the backend will enforce these restrictions at the service layer.
## User Synchronization

View File

@@ -43,4 +43,12 @@ If you set the `disable_missing` property to `true`, any user that is not found
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 were disabled by the synchronization process. Manually disabled users will not be re-enabled.
This will only re-enable the user if they were disabled by the synchronization process. Manually disabled users will not be re-enabled.
##### Interface-specific Access Materialization
If `interface_filter` is configured in the LDAP provider, the synchronization process will evaluate these filters for each enabled user.
The results are materialized in the `interfaces` table of the database in a hidden field.
This materialized list is used by the backend to quickly determine if a user has permission to provision peers for a specific interface, without having to query the LDAP server for every request.
The list is refreshed every time the LDAP synchronization runs.
For more details on how to configure these filters, see the [Authentication](./authentication.md#interface-specific-provisioning-filters) section.