mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-19 16:02:14 +00:00
89a7a37776
* fix(backend): authorize single-job read endpoints by job/flow visibility Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(jobs): share read links + cached access checks for run visibility - Cache the job read-access RLS probe (size-bounded LRU keyed by the caller's authz-relevant identity + job id; no TTL since job-side inputs are immutable). - Inherit visibility along the full parent_job chain so any flow you can see lets you read its (deeply nested) steps. - Share read links: GET /jobs/job_view_token/{id} mints a stateless HMAC(workspace_key, job_id) token (only if the caller can read the job); the token grants an authenticated member read of that job and its flow subtree via a ?view_token query param or X-View-Token header. Run page gains a Share button and honors a ?view_token link. - Denied-but-existing reads now return 403 with guidance to request a share link (vs 404 for non-existent), and the run page renders that case with instructions. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(jobs): address PR review — scope-tag check on mint, constant-time view-token verify - P1 (Codex): get_job_view_token now enforces the caller's if_jobs:filter_tags scope before minting, so a tag-scoped token can't mint a transferable link for a job outside its tags. Adds a scoped-token regression test (allowed + denied). - Constant-time view-token verification (HmacSha256::verify_slice) instead of comparing hex strings (Claude/Pi nit). - get_completed_job_result: an authed reader passing an invalid suspended-secret triple now falls through to the normal visibility gate instead of erroring out (Claude nit); unauthenticated callers still rejected. - Length-prefix the read-access cache key fields so no input values can collide. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(api): add job_view_token to openapi spec; use generated client in run page Addresses Codex review nit: the new GET /jobs/job_view_token/{id} endpoint was missing from openapi.yaml (the source the frontend client is generated from). Adds the path + operationId getJobViewToken, and switches the run page's Share button from a raw fetch to JobService.getJobViewToken. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): carry view_token on share-link downloads Addresses Codex review: download actions bypass the request interceptor that adds X-View-Token (downloadViaClient uses raw fetch; cookie-mode downloads use plain hrefs), so a share-link viewer got 403 downloading logs/results/args. Append the view_token query param to the job download paths (result/logs/args/flow-all-logs) via a new appendViewToken() helper, covering both client-fetch and href modes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(jobs): enforce tag scope in require_job_read_access (view-token use side) Addresses Codex P1: the view_token use-side bypassed if_jobs:filter_tags on handlers that don't tag-filter their data query (result_by_id, get_flow_job_debug_info, get_otel_traces) — a tag-scoped token could use someone else's valid share token to read out-of-scope job data. Move the tag-scope check into require_job_read_access (runs before any created_by/view_token/RLS grant), so it applies uniformly to every gated handler; removes the now-redundant explicit check in get_job_view_token. Adds a use-side regression test (scoped token + valid out-of-scope view_token denied on otel/result_by_id; in-scope still allowed). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): include workspace in share read link Addresses Codex P1: the copied share URL omitted the workspace. The token is signed with the run's workspace key and the logged layout only switches $workspaceStore when the URL carries workspace=, so a recipient whose persisted active workspace differs would open the link against the wrong workspace and the token would fail validation. Pin workspace= alongside view_token in the link. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(jobs): authorize get_result_maybe get_started branch for queued jobs Addresses Codex P1: get_completed_job_result_maybe only gated when a completed row existed; with ?get_started=true a non-reader reached the fallback branch and got started:true for a running private job. Now fetches created_by and authorizes (created_by/view_token/RLS, or anonymous for unauth) before disclosing running-state; a non-existent job still returns started:false (leaks nothing). Adds a regression test with a queued (no completed row) private job. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>