Skip to content

fix(api): scope GET /api/workflows/{id}/runs to the path workflow#6298

Merged
houko merged 3 commits into
mainfrom
fix/workflow-runs-id-scope
Jun 24, 2026
Merged

fix(api): scope GET /api/workflows/{id}/runs to the path workflow#6298
houko merged 3 commits into
mainfrom
fix/workflow-runs-id-scope

Conversation

@houko

@houko houko commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

What

GET /api/workflows/{id}/runs ignored its {id} path parameter: the handler bound it as Path(_id) and called list_runs(None), which returns every workflow's runs. So GET /api/workflows/A/runs returned the runs of all workflows, not just A's.

Since each WorkflowRun carries its initial input string, the unscoped list also leaked the inputs of unrelated workflows to any caller of a single workflow's runs endpoint.

Changes

  • crates/librefang-api/src/routes/workflows/workflow.rs — parse the path id into a WorkflowId (400 on an unparseable id, matching get_workflow / run_workflow and the other endpoints), then filter(|r| r.workflow_id == workflow_id) over list_runs(None). Both return paths now produce (StatusCode, Json<Value>).
  • crates/librefang-api/tests/workflow_lifecycle_test.rs — regression test list_workflow_runs_is_scoped_to_path_workflow: creates two workflows, seeds one run on A and two on B via engine.create_run, then asserts GET /api/workflows/{A}/runs returns only A's run, {B}/runs returns B's two, and an invalid id returns 400.

Verification

  • cargo test -p librefang-api --test workflow_lifecycle_test — 13 passed, incl. the new test.
  • cargo fmt -p librefang-api clean; pre-commit hooks (CHANGELOG [Unreleased] attribution, gitleaks) pass.

Notes

@github-actions github-actions Bot added size/M 50-249 lines changed area/docs Documentation and guides labels Jun 24, 2026
@github-actions github-actions Bot added the has-conflicts PR has merge conflicts that need resolution label Jun 24, 2026
Evan and others added 3 commits June 24, 2026 12:19
list_workflow_runs ignored its {id} path parameter and called list_runs(None), so it returned every workflow's runs instead of the one named in the path.
Each run carries its initial input string, so the unscoped list also exposed unrelated workflows' run inputs to any caller of one workflow's runs endpoint.
Parse the id, filter list_runs(None) by workflow_id, and return 400 on an unparseable id to match the other workflow endpoints.
Adds a regression integration test that creates two workflows, seeds runs on each, and asserts each {id}/runs endpoint returns only its own runs.
CLAUDE.md rule: 'Never write multi-paragraph docstrings or multi-line
comment blocks — one short line max.'

- workflow.rs: 3-line inline comment → 1 line
- workflow_lifecycle_test.rs: 2-line doc comment → 1 line
@houko
houko force-pushed the fix/workflow-runs-id-scope branch from 1d00c9b to c2471fe Compare June 24, 2026 03:22
@houko
houko enabled auto-merge (squash) June 24, 2026 03:22
@github-actions github-actions Bot added ready-for-review PR is ready for maintainer review and removed has-conflicts PR has merge conflicts that need resolution labels Jun 24, 2026
@houko
houko merged commit 248ce66 into main Jun 24, 2026
31 checks passed
@houko
houko deleted the fix/workflow-runs-id-scope branch June 24, 2026 03:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/docs Documentation and guides ready-for-review PR is ready for maintainer review size/M 50-249 lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants