Problem: canceling a job owned by another user returns 503 flux unavailable instead of 403.
flux.job.cancel() raises PermissionError (EPERM) when the requesting user does not own the job. _jobs_cancel() catches only FileNotFoundError, so PermissionError propagates to do_DELETE's except OSError handler, which is written for the broker-unreachable case.
Reproducer (server handle forced into the guest role):
$ FLUX_HANDLE_USERID=9999 FLUX_HANDLE_ROLEMASK=0x2 \
flux python src/cmd/flux-rest-server.py --socket /tmp/t.sock &
$ curl -s --unix-socket /tmp/t.sock -X DELETE "http://localhost/api/v1/jobs/$job
id" \
-w '\nHTTP %{http_code}\n'
{"error": "flux unavailable", "detail": "[Errno 1] guests can only raise excepti
ons on their own jobs"}
HTTP 503
This is reachable in the deployment described in REST_API.md: the server connects to the system instance in the guest role, so any user can name a job id belonging to someone else. The response is both the wrong status class (server fault vs. client fault) and misleading — it says Flux is down when Flux is up and working correctly.
_jobs_submit() already set the precedent for mapping errno to status (the errno.EINVAL -> 400 check). The same shape applies here:
except PermissionError as err:
return 403, {"error": str(err)}
Also needs:
- a
"403" response in spec/v1/openapi.yaml under /jobs/{jobid} delete, and
a Forbidden entry in components/responses
- a test in
t/t1004-jobs-cancel.t
Note this would be the server's first 403; there is no permission-denied path in any existing endpoint.
Found while reviewing #17; not a regression, present since the endpoint was added.
Assisted-by: Claude:opus-5
Problem: canceling a job owned by another user returns
503 flux unavailableinstead of403.flux.job.cancel()raisesPermissionError(EPERM) when the requesting user does not own the job._jobs_cancel()catches onlyFileNotFoundError, soPermissionErrorpropagates todo_DELETE'sexcept OSErrorhandler, which is written for the broker-unreachable case.Reproducer (server handle forced into the guest role):
This is reachable in the deployment described in REST_API.md: the server connects to the system instance in the guest role, so any user can name a job id belonging to someone else. The response is both the wrong status class (server fault vs. client fault) and misleading — it says Flux is down when Flux is up and working correctly.
_jobs_submit()already set the precedent for mapping errno to status (theerrno.EINVAL-> 400 check). The same shape applies here:Also needs:
"403"response inspec/v1/openapi.yamlunder/jobs/{jobid}delete, anda
Forbiddenentry incomponents/responsest/t1004-jobs-cancel.tNote this would be the server's first 403; there is no permission-denied path in any existing endpoint.
Found while reviewing #17; not a regression, present since the endpoint was added.
Assisted-by: Claude:opus-5