fix: send Scheduler API Bearer auth from the task registrar

The Scheduler's task-management endpoints (GET/POST /tasks, PUT
/tasks/{name}) are guarded by verify_api_key, but execute() built a bare
httpx.Client with no Authorization header: the existence probe 401'd
(misread as 'task absent') and every POST/PUT registration failed, so
--execute was never runnable end-to-end against the real Scheduler.

--execute now requires SCHEDULER_API_KEY from the environment (never
stored) and sends Authorization: Bearer on all registrar HTTP calls.
Deploy notes updated alongside the LIBRARY_API_KEY requirement.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QbFZyDvYksazX6nYQYZ67L
This commit is contained in:
2026-07-14 15:13:16 +02:00
co-authored by Claude Fable 5
parent 9ceec1464a
commit b4a5a92fee
4 changed files with 85 additions and 3 deletions
+22 -3
View File
@@ -17,6 +17,11 @@ SAFETY MODEL
if present, and disable test_example_task.
- The Scheduler API location comes from the environment (SCHEDULER_URL);
there is no hardcoded production default.
- The Scheduler's task-management endpoints are themselves guarded by
Bearer auth (verify_api_key). --execute therefore requires
SCHEDULER_API_KEY in the environment; the registrar sends it as
``Authorization: Bearer <key>`` on its own HTTP calls. It is read from
the environment only and never stored anywhere.
- NO SECRET IS EVER STORED: the library-desk API key is referenced as the
literal placeholder ``${LIBRARY_API_KEY}`` inside the task's
``auth.token`` field. The Scheduler's rest_api_executor substitutes
@@ -32,6 +37,7 @@ Usage:
# Register for real (deploy checklist step)
SCHEDULER_URL=http://scheduler-host:8090 \
SCHEDULER_API_KEY=<scheduler-api-key> \
python scripts/register_scheduler_tasks.py --execute
"""
@@ -156,9 +162,16 @@ def dry_run(scheduler_url: str) -> None:
f"{len(TASKS)} task definition(s), {len(TASK_UPDATES)} update(s).")
def execute(scheduler_url: str) -> int:
def execute(scheduler_url: str, scheduler_api_key: str) -> int:
failures = 0
with httpx.Client(base_url=scheduler_url, timeout=30.0) as client:
# The Scheduler's task-management endpoints require Bearer auth
# (verify_api_key: 401 when missing, 403 when wrong). Without this
# header the existence probes 401 (misread as "task absent") and
# every POST/PUT fails.
auth_headers = {"Authorization": f"Bearer {scheduler_api_key}"}
with httpx.Client(
base_url=scheduler_url, timeout=30.0, headers=auth_headers
) as client:
health = client.get("/health")
if health.status_code != 200:
print(f"ERROR: Scheduler health check failed: {health.status_code}")
@@ -224,7 +237,13 @@ def main() -> int:
print("ERROR: SCHEDULER_URL must be set for --execute")
return 1
return execute(scheduler_url)
scheduler_api_key = os.environ.get("SCHEDULER_API_KEY", "")
if not scheduler_api_key:
print("ERROR: SCHEDULER_API_KEY must be set for --execute "
"(the Scheduler's task endpoints require Bearer auth)")
return 1
return execute(scheduler_url, scheduler_api_key)
if __name__ == "__main__":