- config: is_insecure_secret() rejects any dev/placeholder key (dev-*,
jwt-secret-key*, *change-in-production*, *change-this*, empty), not just the
two exact default strings — a variant like `dev-jwt-...` can no longer boot
in production. Used in both ProductionConfig.__init__ and init_app.
- systemd unit: bind gunicorn to 127.0.0.1 by default so the raw API port is
not world-reachable (host nginx already fronts :80/:443). Override with
SERVERKIT_BIND_HOST=0.0.0.0 for setups that front it differently.
- cli break-glass: mint the token with a string identity; flask-jwt-extended
rejects a non-string `sub` at decode time with a 422, which broke every CLI
call that authenticated against the panel API.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
serverkit status / services / apps / doctor [--repair] / repair /
update / login-url / support-bundle. Break-glass auth mints a 10-minute
admin JWT in-process (audit-logged) — root on the box already implies
full control. The support bundle exports a secret-scrubbed zip of
versions, service states, setting shapes and recent job failures.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>