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

1.5 KiB

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.