- Move the new zone config key into the existing AgentNetwork config
group (management/internals/server/config/config.go) instead of a
sibling top-level field, wire modules.go to the new path, add the
matching field to combined/cmd/config.go's AgentNetworkConfig and its
mapping (it was previously unreachable in the combined binary), and
document the key in infrastructure_files/management.json.tmpl and
combined/config.yaml.example.
- Delete PickUnique and its three tests: Task 5 removed its last
production caller, leaving it dead exported code with a stale
words.go comment pointing at it.
- Reword two test comments that referenced our private review process
instead of stating what the test locks down / why TargetId stays
pinned to Cluster.
- Add TestBootstrapSettings_NonRetryableErrorFailsImmediately: a
regression that dropped the isUniqueConstraintError gate and retried
on every error would leave every existing allocator test green.
- Fix TestSynthesizeServiceForDomain_DegenerateInput's docstring: the
early-return guard is an optimisation, not what makes "" and
"localhost" resolve to no service.
- Replace manager.go's allocation-comment archaeology (a deleted
per-cluster "taken" set, an `accountID[:4]` suffix, "~68 minutes") with
the actual invariant, and note why each retry attempt gets its own
transaction (a failed statement poisons the enclosing transaction on
postgres).
- Collapse the per-service "no matching zone apex" debug log in
account.go into a single line per call instead of one per skipped
service.
- Document why idx_agent_network_settings_cluster_subdomain must stay
on mysql: its index tag is what sizes subdomain as varchar(191)
rather than longtext, which the new unique index requires.
## Summary
Adds a unified `admin` CLI for self-hosted instance administrators in
both the management and combined binaries.
## User Management
### `admin user change-password`
- Changes a local embedded IdP user's password.
- Selects the user with `--email` or `--user-id`.
- Reads the new password from `--password` or `--password-file`.
- Clears the user's local authentication session so the new password is
required on the next login.
- **Alias:** `admin user set-password`.
### `admin user reset-mfa`
- Resets a local embedded IdP user's MFA enrollment.
- Selects the user with `--email` or `--user-id`.
- Clears TOTP/WebAuthn enrollment data and removes the local
authentication session.
- The user will re-enroll MFA on the next login.
## MFA Management
### `admin mfa status`
- Shows whether local MFA is enabled in the account settings.
- Checks the embedded IdP client configuration and reports whether MFA
is enabled there.
### `admin mfa enable`
- Enables local MFA for embedded IdP users.
- Updates embedded IdP clients and saves the account MFA setting.
- Records an audit event on a best-effort basis.
### `admin mfa disable`
- Disables local MFA for embedded IdP users.
- Updates embedded IdP clients and saves the account MFA setting.
- Records an audit event on a best-effort basis.
## Reverse Proxy Tokens
### `admin token create --name <name> [--expires-in <duration>]`
- Creates a reverse proxy access token.
- Prints the plaintext token once, along with the token ID.
- `--expires-in` supports values such as `24h`, `30d`, or `365d`. If
omitted, the token never expires.
### `admin token list`
- Lists reverse proxy access tokens.
- Shows the token ID, name, creation date, expiration, last-used time,
and revocation status.
- **Alias:** `admin token ls`.
### `admin token revoke <token-id>`
- Revokes a reverse proxy access token.
- Revoked tokens can no longer authenticate reverse proxy instances.
## Reverse Proxy Management
### `admin proxy disconnect-all`
- Lists registered reverse proxy instances and force-marks all connected
instances as disconnected.
- Useful for repairing stale proxy state after an unclean management
server shutdown.
- Prompts for confirmation by default.
- `--dry-run` previews the changes without applying them.
- `--force` skips the confirmation prompt.
- Live proxies may appear again after their next heartbeat, reconnect,
or re-registration.
## Compatibility Commands
### `token ...`
- Deprecated top-level compatibility path.
- Behaves the same as `admin token ...`.
- Retained so existing scripts using `token create`, `token list`, or
`token revoke` continue to work.
## Changes
- Adds reusable `management/cmd/admin` command package.
- Wires `admin` into `netbird-mgmt` and `combined`.
- Adds local user password reset with existing password strength
validation.
- Adds local MFA enrollment reset by clearing Dex TOTP/WebAuthn
credentials and local auth sessions.
- Adds local MFA enable/disable/status helpers for embedded IdP
deployments.
- Moves proxy access token commands under `admin token` for a single
admin-focused CLI entry point.
- Exports `server.ValidatePassword` for reuse by CLI helpers.
## Tests
```bash
go test ./management/cmd/...
go test ./management/cmd/admin ./management/cmd ./combined/cmd
go test ./management/server -run TestValidatePassword
```
Pre-push lint also passed.
### Checklist
- [ ] Is it a bug fix
- [ ] Is a typo/documentation fix
- [x] Is a feature enhancement
- [ ] It is a refactor
- [ ] Created tests that fail without the change (if possible)
- [ ] This change does **not** modify the public API, gRPC protocols,
functionality behavior, CLI / service flags, or introduce a new feature
— **OR** I have discussed it with the NetBird team beforehand (link the
issue / Slack thread in the description). See
[CONTRIBUTING.md](https://github.com/netbirdio/netbird/blob/main/CONTRIBUTING.md#discuss-changes-with-the-netbird-team-first).
> By submitting this pull request, you confirm that you have read and
agree to the terms of the [Contributor License
Agreement](https://github.com/netbirdio/netbird/blob/main/CONTRIBUTOR_LICENSE_AGREEMENT.md).
## Documentation
Select exactly one:
- [x] I added/updated documentation for this change
- [ ] Documentation is **not needed** for this change (explain why)
### Docs PR URL (required if "docs added" is checked)
Paste the PR link from https://github.com/netbirdio/docs here:
https://github.com/netbirdio/docs/pull/832
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
* **New Features**
* Added self-hosted admin CLI commands for changing passwords, resetting
MFA (including WebAuthn), and managing embedded IdP client MFA
(enable/disable/status).
* Introduced a unified admin command entry point and improved
data-directory handling for embedded IdP storage.
* **Refactor**
* Centralized password strength validation into a shared exported
validator.
* **Tests**
* Added a comprehensive admin command test suite covering password
input, selectors, MFA reset, and client MFA state handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
* [relay] Replace net.Conn with context-aware Conn interface for relay transports
Introduce a listener.Conn interface with context-based Read/Write methods,
replacing net.Conn throughout the relay server. This enables proper timeout
propagation (e.g. handshake timeout) without goroutine-based workarounds
and removes unused LocalAddr/SetDeadline methods from WS and QUIC conns.
* [relay] Refactor Peer context management to ensure proper cleanup
Integrate context creation (`context.WithCancel`) directly in `NewPeer` and remove redundant initialization in `Work`. Add `ctxCancel` calls to ensure context is properly canceled during `Close` operations.
The combined server was using the hostname from exposedAddress for both
singleAccountModeDomain and dnsDomain, causing fresh installs to get
the wrong domain and existing installs to break if the config changed.
Add resolveDomains() to BaseServer that reads domain from the store:
- Fresh install (0 accounts): uses "netbird.selfhosted" default
- Existing install: reads persisted domain from the account in DB
- Store errors: falls back to default safely
The combined server opts in via AutoResolveDomains flag, while the
standalone management server is unaffected.
* Unified NetBird combined server (Management, Signal, Relay, STUN) as a single executable with richer YAML configuration, validation, and defaults.
* Official Dockerfile/image for single-container deployment.
* Optional in-process profiling endpoint for diagnostics.
* Multiplexing to route HTTP/gRPC/WebSocket traffic via one port; runtime hooks to inject custom handlers.
* **Chores**
* Updated deployment scripts, compose files, and reverse-proxy templates to target the combined server; added example configs and getting-started updates.