fix(scheduler): require admin/analyst scope on scheduler routes
Addresses GHSA-cx3g-ffv9-4gwg. The scheduler router was mounted without authentication, allowing unauthenticated enumeration via GET /api/scheduler and reaching POST /api/scheduler/jobs/run/{job_id} without a 401/403. Enforce auth at the router level so every endpoint inherits the scope check; internal job execution is unaffected since jobs fire in-process via APScheduler, not via HTTP. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
taylorwalton committed
Apr 24, 2026 at 12:37 UTC
7d5917b39ae13f8153043f612076c56e533d351c
1 file changed
+5
-1
backend/app/schedulers/routes/scheduler.py
+5
-1
@@ -4,10 +4,12 @@ from typing import Optional
4
from fastapi import APIRouter
5
from fastapi import Depends
6
from fastapi import HTTPException
7
+from fastapi import Security
8
from loguru import logger
9
from sqlalchemy.ext.asyncio import AsyncSession
10
from sqlalchemy.future import select
11
12
+from app.auth.utils import AuthHandler
13
from app.db.db_session import get_db
14
from app.schedulers.models.scheduler import JobMetadata
15
from app.schedulers.scheduler import get_function_by_name
@@ -16,7 +18,9 @@ from app.schedulers.scheduler import init_scheduler
18
from app.schedulers.schema.scheduler import JobsNextRunResponse
19
from app.schedulers.schema.scheduler import JobsResponse
20
19
-scheduler_router = APIRouter()
21
+scheduler_router = APIRouter(
22
+ dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
23
+)
24
25
26
async def get_scheduler():