feat: SHARED_SECRET_LEGACY migration escape hatch for plugin secret rollout
Accepts one legacy secret alongside the real one so existing clients keep registering while game machines migrate to websocket_secret.txt. Remove SHARED_SECRET_LEGACY from .env after the rollout. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
15ae870117
commit
52bf9342df
2 changed files with 21 additions and 3 deletions
21
main.py
21
main.py
|
|
@ -1003,6 +1003,17 @@ if not _SHARED_SECRET_OK:
|
|||
"SHARED_SECRET env var is unset or still the placeholder — "
|
||||
"refusing ALL plugin WebSocket connections until it is set in .env"
|
||||
)
|
||||
# Migration escape hatch: while game machines are being migrated to
|
||||
# websocket_secret.txt, a second (legacy) secret can be accepted alongside
|
||||
# the real one. REMOVE SHARED_SECRET_LEGACY from .env once the plugin
|
||||
# rollout is complete — with the old placeholder in it, this re-opens the
|
||||
# known-secret hole it exists to close.
|
||||
SHARED_SECRET_LEGACY = os.getenv("SHARED_SECRET_LEGACY", "")
|
||||
if SHARED_SECRET_LEGACY:
|
||||
logger.warning(
|
||||
"SHARED_SECRET_LEGACY is set — legacy plugin secret accepted during "
|
||||
"migration; remove it from .env after the plugin rollout"
|
||||
)
|
||||
# Secret key for signing session cookies. Fail closed: running with a
|
||||
# publicly-known default would let anyone forge admin sessions.
|
||||
SECRET_KEY = os.getenv("SECRET_KEY", "")
|
||||
|
|
@ -2979,9 +2990,13 @@ async def ws_receive_snapshots(
|
|||
# compare; refuse everything when the secret is not configured).
|
||||
key = secret or x_plugin_secret or ""
|
||||
# compare bytes: compare_digest(str, str) raises TypeError on non-ASCII
|
||||
if not _SHARED_SECRET_OK or not hmac.compare_digest(
|
||||
key.encode("utf-8", "replace"), SHARED_SECRET.encode("utf-8")
|
||||
):
|
||||
key_b = key.encode("utf-8", "replace")
|
||||
auth_ok = _SHARED_SECRET_OK and hmac.compare_digest(
|
||||
key_b, SHARED_SECRET.encode("utf-8")
|
||||
)
|
||||
if not auth_ok and SHARED_SECRET_LEGACY:
|
||||
auth_ok = hmac.compare_digest(key_b, SHARED_SECRET_LEGACY.encode("utf-8"))
|
||||
if not auth_ok:
|
||||
# Reject without completing the WebSocket handshake
|
||||
logger.warning(
|
||||
f"Plugin WebSocket authentication failed from {websocket.client}"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue