Skip to content

feat: limit access to job file endpoints to only the same user as requester - #140

Open
Yash Shrivastava (alephys26) wants to merge 6 commits into
mainfrom
alephys26/access-control
Open

feat: limit access to job file endpoints to only the same user as requester#140
Yash Shrivastava (alephys26) wants to merge 6 commits into
mainfrom
alephys26/access-control

Conversation

@alephys26

@alephys26 Yash Shrivastava (alephys26) commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

PR details

Background

/job/{id}/result had no ownership check. Any caller who knew or guessed a job ID could read another user's job result, even without identifying themselves. Heimdall already identifies the caller via the auth_header plugin (X-Heimdall-User, stored as j.User on job creation), so the fix enforces that the requester matches the job's owner before serving the result file.

Changes

  • Added an ownership check in getJobFile (internal/pkg/heimdall/job.go), scoped to the result file: the job is looked up via getJobStatus and its User compared against getUsername(r) (the caller identity from the existing auth middleware); mismatches are rejected with ErrCallerNotAllowed (403). stdout/stderr are unaffected — no ownership restriction is added for those.
  • Extended queries/job/status_select.sql to also select j.username, and scan it into r.User in getJobStatus (job_dal.go), so the ownership check can run off the existing lightweight status query instead of the full getJob lookup (which loads job context/tags and would have made the file-download path heavier and introduced unrelated failure modes — per review feedback).
  • Minor cleanup: consolidated the type-assertion on the fetched job, trailing-whitespace/gofmt fix in job_dal.go.

Types of changes

  • Security fix / access control

Tests

Ran the backend locally (postgres + heimdall API), submitted a ping job as user alice, and hit /job/{id}/result and /job/{id}/stdout:

  • alice (owner) result: 200 OK, correct body
  • bob (non-owner) result: 403 caller is not allowed to run this command
  • no X-Heimdall-User header result: 403 caller is not allowed to run this command
  • alice stdout: 200 OK (unrestricted, as intended)
  • bob stdout: 200 OK (unrestricted, as intended)

go build ./internal/... ./pkg/... passes.

Impact

Restricts /job/{id}/result to the job's owner only; any other caller now gets 403 there. /job/{id}/stdout and /job/{id}/stderr remain unchanged (no access restriction). No schema or API contract changes beyond the new 403 response for result.

Copilot AI lite review requested due to automatic review settings August 26, 2026 17:13

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR closes an access-control gap in the Heimdall API’s job file endpoints by enforcing that only the job owner (as identified by the existing auth header middleware) can fetch a job’s stdout, stderr, or result payloads.

Changes:

  • Switched job lookup in getJobFile from getJobStatus to getJob so the job owner (User) is available for authorization checks.
  • Added an ownership check (j.User vs getUsername(r)) returning ErrCallerNotAllowed (403) on mismatch.
  • Consolidated the job type assertion and preserved the existing “result only when succeeded” guard.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread internal/pkg/heimdall/job.go
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants