Files
NexaVPN/docs/api.md
nessi 830491cb0d chore: initial project scaffold with admin web, backend, desktop client, and deployment setup
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
2026-03-15 16:32:34 +01:00

224 lines
3.7 KiB
Markdown

# REST API Contract
Base path: `/api/v1`
All responses are JSON.
## Authentication
### `POST /auth/login`
Request:
```json
{
"username": "alice",
"password": "secret-password"
}
```
Response:
```json
{
"access_token": "jwt",
"refresh_token": "opaque-token",
"expires_in": 900,
"user": {
"id": "uuid",
"username": "alice",
"display_name": "Alice",
"role": "admin"
}
}
```
### `POST /auth/refresh`
Request:
```json
{
"refresh_token": "opaque-token"
}
```
### `POST /auth/logout`
Request:
```json
{
"refresh_token": "opaque-token"
}
```
### `GET /auth/me`
Returns the authenticated user and role.
## User Self-Service
### `GET /me/devices`
Returns the current user devices.
### `GET /me/profile`
Returns profile metadata for the current active device when the client needs to resync.
## Device Enrollment and Provisioning
### `POST /devices/enroll`
Request:
```json
{
"name": "Alice MacBook Pro",
"platform": "macos",
"os_version": "14.4",
"app_version": "0.1.0",
"device_fingerprint": "sha256:...",
"public_key": "base64-wireguard-public-key"
}
```
Response:
```json
{
"device": {
"id": "uuid",
"name": "Alice MacBook Pro",
"status": "active"
},
"peer": {
"assigned_ip": "100.96.0.10/32",
"dns_servers": ["10.20.0.53"],
"allowed_ips": ["172.16.10.0/24"],
"gateway": {
"id": "uuid",
"name": "primary-gateway",
"endpoint": "vpn.example.com:51820",
"public_key": "gateway-public-key"
},
"profile_revision": 1
},
"profile": {
"format": "wireguard",
"content": "[Interface]\n..."
},
"resources": [
{
"type": "cidr",
"value": "172.16.10.0/24",
"label": "Private subnet"
}
]
}
```
### `GET /devices/{deviceId}/profile`
Admin-only debug endpoint for rendered config retrieval.
### `POST /devices/{deviceId}/rotate`
Rotates the device profile revision and forces reprovisioning.
### `POST /devices/{deviceId}/revoke`
Revokes the device and removes it from future gateway sync output.
### `POST /devices/{deviceId}/heartbeat`
Optional client status sync for last-seen and runtime metadata.
## Connection Metadata
### `GET /connection/status`
Returns assigned IP, latest sync time, and effective allowed resources for the current authenticated device session.
## Admin: Users
### `GET /admin/users`
### `POST /admin/users`
### `GET /admin/users/{id}`
### `PATCH /admin/users/{id}`
### `POST /admin/users/{id}/disable`
### `POST /admin/users/{id}/enable`
### `POST /admin/users/{id}/password`
## Admin: Devices
### `GET /admin/devices`
### `GET /admin/devices/{id}`
### `PATCH /admin/devices/{id}`
### `POST /admin/devices/{id}/revoke`
### `POST /admin/devices/{id}/rotate`
## Admin: Policies
### `GET /admin/policies`
### `POST /admin/policies`
### `GET /admin/policies/{id}`
### `PATCH /admin/policies/{id}`
### `DELETE /admin/policies/{id}`
Policy create request:
```json
{
"name": "Finance subnet access",
"description": "Access for finance team",
"priority": 100,
"effect": "allow",
"full_tunnel": false,
"destinations": [
"172.16.20.0/24",
"172.16.21.10/32"
],
"targets": [
{
"type": "user",
"id": "uuid"
}
]
}
```
## Admin: Gateways
### `GET /admin/gateways`
### `POST /admin/gateways`
### `GET /admin/gateways/{id}`
### `PATCH /admin/gateways/{id}`
### `GET /admin/gateways/{id}/sync`
The sync endpoint returns the peer and firewall bundle consumed by the gateway helper.
## Admin: Audit
### `GET /admin/audit-logs`
Query params:
- `event_type`
- `entity_type`
- `status`
- `page`
- `page_size`
## Error Format
```json
{
"error": {
"code": "validation_error",
"message": "public_key is required"
}
}
```