Replace the Schulcloud token without a restart
A token lasts 30 days and only a browser login yields one — the account is federated, so the server cannot mint it. Replacing it meant editing .env and recreating the container, every month. `schulcloud token set` (a hidden prompt, or piped input) and a /token page both send it to PUT /api/token. The server checks it with Schulcloud first — well-formed, unexpired, still logged in, the same account — then swaps it into the config every request reads, restarts the keepalive and saves it in STATE_DIR, a new volume, with mode 0600. At startup the newer of the saved token and TSC_JWT_COOKIE wins, unless they belong to different accounts. A refused paste changes nothing, and the token is never logged. The keepalive's pings carry a generation, so a 401 for the old token that arrives after a swap cannot stop the new cycle. `schulcloud token`, whoami and the log report the expiry and warn a week ahead. Found on the way: a host that is off for more than two hours loses the session however long the token has left — this machine lost it overnight — which is what the always-on Pi is for. 174 tests. Smoke 72/72 on the local instance, and a real swap verified end to end there. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,8 @@ TSC_URL=https://schulcloud-thueringen.de
|
||||
# TTL that the built-in keepalive holds open. IMPORTANT: close the Schulportal
|
||||
# window after copying this — an open tab shares the session and its auto-logout
|
||||
# will revoke this token ~2h after login. See docs/AUTH.md.
|
||||
# Needed for the first start. Later tokens go in with `schulcloud token set` or
|
||||
# the server's /token page, without a restart; a saved newer one wins over this.
|
||||
TSC_JWT_COOKIE=
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -22,6 +24,11 @@ TSC_JWT_COOKIE=
|
||||
# openssl rand -hex 32
|
||||
MCP_AUTH_TOKEN=
|
||||
|
||||
# Where a Schulcloud token replaced at runtime (`schulcloud token set`, /token)
|
||||
# is saved, so a restart keeps it. docker-compose.yml sets /data/state; unset =
|
||||
# replacements last until the next restart.
|
||||
# STATE_DIR=/data/state
|
||||
|
||||
# Listen address inside the container. Leave as-is when running behind Caddy.
|
||||
PORT=8080
|
||||
BIND_HOST=0.0.0.0
|
||||
|
||||
Reference in New Issue
Block a user