vpn/docs/backend.md
2026-09-23 01:19:36 +00:00

26 lines
1.5 KiB
Markdown

# Backend contract
The admin UI is a single `backend/admin.html` file. It sends the configured admin
Bearer token in memory/session storage and calls only `/admin/api/*` endpoints.
## Device flow
1. Operator creates a user and device in the page.
2. Backend returns a one-time `enrollment_url` and a stable `subscription_url`.
3. The app makes the first request with `X-Device-Token: <random token>` and
`User-Agent: vpnapp/vMAJOR.MINOR/DEVICE_UUID`.
4. Backend checks URL UUID, credential, and User-Agent UUID atomically, records the
User-Agent, and returns the user's decrypted-for-transport config payload.
5. Polling every few hours uses the same device token and bound User-Agent. A different
installation cannot reuse the same device binding unless the token is copied; UUID
and User-Agent alone never authenticate.
The device endpoint must be deployed behind TLS. The admin token is not accepted on
`/d/{device_id}`. Server configs and user secrets are Fernet-encrypted at rest with
`VPNAPP_SECRET_KEY`; only sanitized fields are shown in the admin list.
The reusable client-side request code is in `app/services/subscription.py`. It accepts
an injected secret store, emits the required User-Agent, performs one-time enrollment,
refreshes the device subscription asynchronously, and maps the response into the
separate VLESS/Amnezia/FreeTurn profile models. Android should connect its injected
store to Keystore-backed native storage before shipping credentials.