Authenticate sockets by header or one-time ticket instead of ?token=

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013GAeg4Jo6xjZzjwy9QDWMQ
This commit is contained in:
2026-10-07 08:58:22 +02:00
co-authored by Claude Opus 5.5
parent eb45fb2763
commit 5259b8db0a
21 changed files with 336 additions and 44 deletions
+3
View File
@@ -19,6 +19,9 @@ its own wheels without the engine ever installing them. Mint a token from the
engine with `POST /api/v1/workers/tokens`; it carries this worker's name and
labels, and `--labels` may repeat those but not change them.
It sends the token as an `Authorization` header, which an engine from before
that does not read: upgrade the engine first, then its workers.
A plain `ws://` address is refused unless the engine is on this machine, since
the token and node secrets would cross the network in clear; `--insecure`
allows it on a network you trust.
+7 -2
View File
@@ -156,8 +156,13 @@ class Agent:
backoff = min(MAX_BACKOFF_S, backoff * 2)
async def _session(self) -> None:
url = f"{self.args.url}?token={self.args.token}"
async with websockets.connect(url, max_size=None, ping_interval=20) as socket:
# A header rather than the query string, which access logs keep.
async with websockets.connect(
self.args.url,
additional_headers={"Authorization": f"Bearer {self.args.token}"},
max_size=None,
ping_interval=20,
) as socket:
await socket.send(
json.dumps(
{
+1 -1
View File
@@ -22,7 +22,7 @@ classifiers = [
"Topic :: System :: Distributed Computing",
]
dependencies = [
"websockets>=12",
"websockets>=14",
]
[project.urls]