Add monorepo structure for NexaVPN WireGuard control plane including: - .gitignore for node_modules, build artifacts, and environment files - README with project overview, monorepo layout, and quick start guide - Admin web UI with React, Vite, TypeScript, and nginx reverse proxy - API client with type definitions for users, devices, policies, gateways, and audit logs - Admin pages for dashboard, users, devices, policies, g
77 lines
2.7 KiB
Markdown
77 lines
2.7 KiB
Markdown
# Device Enrollment And Auto-Provisioning
|
|
|
|
## Enrollment Flow
|
|
|
|
1. The user launches the desktop client.
|
|
2. The client shows a minimal form with:
|
|
- server URL
|
|
- username
|
|
- password
|
|
3. The client validates the server URL and performs a TLS reachability check.
|
|
4. The user submits credentials.
|
|
5. The client calls `POST /api/v1/auth/login`.
|
|
6. On success, the client securely stores:
|
|
- access token
|
|
- refresh token
|
|
- remembered server URL
|
|
7. The client generates a WireGuard keypair locally.
|
|
8. The client computes a stable device fingerprint.
|
|
9. The client calls `POST /api/v1/devices/enroll`.
|
|
10. The backend:
|
|
- creates or updates the device record
|
|
- selects an active gateway
|
|
- allocates a VPN IP
|
|
- resolves effective policy destinations
|
|
- stores the peer
|
|
- renders the WireGuard profile
|
|
- emits audit events
|
|
11. The client stores the profile locally in secure application storage.
|
|
12. The client registers the profile with the local tunnel manager.
|
|
13. The post-login view shows:
|
|
- connection status
|
|
- assigned VPN IP
|
|
- allowed resources
|
|
- connect/disconnect button
|
|
- last sync time
|
|
|
|
## Private Key Handling
|
|
|
|
- The WireGuard private key is generated on-device.
|
|
- It is never sent to the backend.
|
|
- The backend stores only the public key and provisioning metadata.
|
|
- The desktop app keeps the private key inside the OS-secured storage boundary where possible.
|
|
|
|
## Auto-Profile Provisioning Design
|
|
|
|
The provisioning response returns both structured metadata and a rendered WireGuard config. The client uses the rendered config for immediate compatibility and the structured metadata for UI status.
|
|
|
|
### Preferred MVP Strategy
|
|
|
|
Use an embedded tunnel manager inside the Tauri app:
|
|
|
|
- Windows
|
|
- manage the tunnel using a Rust bridge and local service abstraction
|
|
- support future integration with WireGuardNT or the official service
|
|
- macOS
|
|
- manage the tunnel through a privileged helper or Network Extension bridge in a later hardening phase
|
|
- MVP keeps the app abstraction stable while platform backends can evolve
|
|
|
|
This approach keeps the user flow consistent even if the platform-specific implementation differs.
|
|
|
|
### Fallback Strategy
|
|
|
|
If native embedded control is not ready on a platform:
|
|
|
|
- the app still auto-creates the profile locally
|
|
- the app exposes a one-click import handoff to the system WireGuard client
|
|
- this fallback is clearly labeled as temporary in documentation, not as the intended end state
|
|
|
|
## Reprovisioning
|
|
|
|
- Profile rotation increments `profile_revision`.
|
|
- On next sync or forced refresh, the client fetches a new profile.
|
|
- Revoked devices lose access because:
|
|
- the gateway peer is removed
|
|
- tokens can be invalidated
|
|
- the client marks the local profile unusable
|