69961a52cd0c2eca4a01cb9e219a701fa1e7dff7
/api/vpn/enroll minted pre-auth keys itself, from HEADSCALE_URL, HEADSCALE_API_KEY and HEADSCALE_USER in the host env. Three globals describe one server; Officer keeps a registry of many in headscale_servers with one active, so the env could contradict the server the owner had selected — and HEADSCALE_USER filed every joining device under the same name on all of them. The two credential vars had already been removed from the environment and nothing noticed: the route checks `if (!base || !apiKey)` first, so it had been answering 503 to every enrollment attempt, silently. HEADSCALE_USER was read but never reached. Enrollment moves into the sidecar that owns the registry and acts on the active server. The owning user is resolved rather than hardcoded: an explicit userId wins, one user on the server needs no choice, several is a 409 listing them instead of a silent guess. The platform route keeps its path and response shape — both are a contract with enrollVpn() in the mobile core — and is now a bare forward holding no Headscale URL, key or user name. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Description
No description provided
42 MiB
Languages
TypeScript
90.9%
Shell
4.7%
JavaScript
4.1%
CSS
0.2%
HTML
0.1%