Skip to content

fix: workflow scheduler now applies route-level security controls#689

Merged
utksh1 merged 3 commits into
utksh1:mainfrom
ionfwsrijan:fix/workflow-scheduler-security-655
Jun 9, 2026
Merged

fix: workflow scheduler now applies route-level security controls#689
utksh1 merged 3 commits into
utksh1:mainfrom
ionfwsrijan:fix/workflow-scheduler-security-655

Conversation

@ionfwsrijan

Copy link
Copy Markdown
Contributor

Description

Fixes #655 — Workflow Scheduler Bypasses All Route-Level Security Controls.

Changes

  1. routes.py — Extracted _execute_scan_safe() shared function that applies consent validation, safe mode enforcement, target validation, rate limiting, and concurrency limits. Both start_task() and run_workflow_once() now use this entry point.

  2. workflows.py — Refactored _run_workflow() to apply all security checks directly: plugin existence validation, target validation (safe mode + timeout), network policy enforcement, rate limiting per client+plugin, concurrency slot acquisition, and source-tagged audit logging. Each check failure gracefully skips the step instead of crashing the scheduler loop.

  3. ratelimit.py — Added WorkflowRateLimiter class with two methods:

    • check_workflow_rate_limit(workflow_id, min_interval) — prevents a single workflow from firing faster than the configured minimum interval
    • check_user_workflow_limit(user_id, max_workflows) — limits the number of workflows a single user can create
  4. executor.py — Added source parameter to create_task() and included "source": "api" | "workflow" | "scheduler" in audit log context for all task lifecycle events.

  5. config.py — Added workflow configuration settings:

    • max_workflows_per_user (default 50)
    • workflow_min_interval_seconds (default 60)
    • workflow_consent_refresh_days (default 30)

Impact

  • Rate limit bypass: ✅ Closed — scheduler now checks rate limits per (client, plugin) pair
  • Audit invisibility: ✅ Closed — all executions tagged with source in audit log
  • Access revocation bypass: ✅ Partially mitigated — consent re-validation required each run
  • Consent bypass: ✅ Closed — scheduler respects require_consent setting

@ionfwsrijan ionfwsrijan force-pushed the fix/workflow-scheduler-security-655 branch from b54a940 to 2b73be5 Compare June 8, 2026 20:13
@utksh1 utksh1 added level:advanced 55 pts difficulty label for advanced contributor PRs type:security Security work category bonus label type:bug Bug fix work category bonus label area:backend Backend API, database, or service work area:security Security-sensitive implementation or tests labels Jun 8, 2026

@utksh1 utksh1 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs changes before review can proceed. The branch currently has merge conflicts, and the new _execute_scan_safe() path schedules executor.execute_task() internally while start_task() also adds executor.execute_task() to BackgroundTasks, so API-created scans can be executed twice. Please rebase on current main, resolve conflicts, and make task scheduling happen in exactly one place while preserving the existing TestClient/background task behavior.

@ionfwsrijan ionfwsrijan force-pushed the fix/workflow-scheduler-security-655 branch 2 times, most recently from 987c6c4 to 8188905 Compare June 8, 2026 20:45
@ionfwsrijan

Copy link
Copy Markdown
Contributor Author

@utksh1 I've address the requested changes. You may review it now

@utksh1 utksh1 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed the latest push. This route-level scheduler security change is still too broad to merge without a clean rebase and focused tests for the workflow scheduler path. Please reduce unrelated churn, rebase on main, and demonstrate the route-level controls are applied consistently.

@ionfwsrijan ionfwsrijan force-pushed the fix/workflow-scheduler-security-655 branch from 1ed1439 to 4be01d8 Compare June 9, 2026 16:48
@ionfwsrijan

ionfwsrijan commented Jun 9, 2026

Copy link
Copy Markdown
Contributor Author

Rebased on latest main. Scope reduced to 7 backend files + focused tests. No unrelated docs, frontend, or test deletions. Single clean commit. See diff for details.

- Extracted _execute_scan_safe() in routes.py as shared security entry point
  used by both start_task() and run_workflow_once()
- Scheduler _run_workflow() now validates targets, enforces rate limits,
  checks network policy, acquires concurrency slots, and logs source
- Added WorkflowRateLimiter to ratelimit.py with per-workflow and per-user
  limits
- Added source parameter (api|workflow|scheduler) to executor audit logging
- Added workflow config settings (min interval, max per user, consent
  refresh)
- Added focused tests for workflow scheduler security path

Closes utksh1#655
@ionfwsrijan ionfwsrijan force-pushed the fix/workflow-scheduler-security-655 branch from 4be01d8 to 8fc5290 Compare June 9, 2026 16:52
@ionfwsrijan

Copy link
Copy Markdown
Contributor Author

@utksh1 I've made the changes you may review now.

@utksh1 utksh1 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checks are green, but this is still too broad for the workflow scheduler security issue. The PR rewrites a large part of routes.py, changes executor audit/completion behavior, adds a new global workflow rate limiter, changes main.py shutdown behavior, and modifies plugin input handling. Please split this down to the minimum scheduler hardening path: validate/enforce policy for scheduler-triggered workflow scans with focused tests, and move unrelated executor lifecycle, shutdown, and route refactors into separate PRs.

…low scans

- _run_workflow() now validates plugin existence, targets in safe mode,
  enforces network policy, rate limits per (client, plugin), and acquires
  concurrency slots before executing each step
- tick() enforces workflow_min_interval_seconds via WorkflowRateLimiter
- run_workflow_once() applies the same workflow rate limit
- Added WorkflowRateLimiter with per-workflow rate limiting
- Added workflow_min_interval_seconds config setting
- Each check failure gracefully logs and skips the step

Executor lifecycle, shutdown handling, route refactoring, and plugin
input handling split into separate PRs.

Closes utksh1#655
@ionfwsrijan

Copy link
Copy Markdown
Contributor Author

@utksh1 I've addressed the changes asked. Please review it.

@utksh1 utksh1 added the gssoc:approved Admin validation: approved for GSSoC scoring label Jun 9, 2026

@utksh1 utksh1 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved current head after re-review. The latest update narrows the PR to scheduler workflow security controls, removes the unrelated route/executor/shutdown/plugin-input refactors from the earlier version, and keeps focused coverage for workflow rate limiting, target validation, task rate limiting, safe-mode handling, and concurrency acquisition. I also updated the branch onto current main; fresh CI is green.

@utksh1 utksh1 merged commit 44551c8 into utksh1:main Jun 9, 2026
11 checks passed
@ionfwsrijan

Copy link
Copy Markdown
Contributor Author

@utksh1 Thanks for your valuable time. Please review my other PRs too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:backend Backend API, database, or service work area:security Security-sensitive implementation or tests gssoc:approved Admin validation: approved for GSSoC scoring level:advanced 55 pts difficulty label for advanced contributor PRs type:bug Bug fix work category bonus label type:security Security work category bonus label

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Workflow Scheduler Bypasses All Route-Level Security Controls

2 participants