fix(web_api): sign request body in Hawk auth for B01 /jobs writes#852
Merged
Lash-L merged 1 commit intoJun 20, 2026
Merged
Conversation
B01 /jobs writes (schedules, one-time room cleans) return 401 auth.err.invalid.token: _get_hawk_authentication only ever signs formdata in the Hawk payload slot, which is empty for a JSON body, so the MAC never covers the body the server receives. Sign md5(compact JSON body) in the payload slot for body-bearing writes, and send those same compact bytes via data= (json= would re-serialize with spaces and break the MAC). body=None keeps GET and form-post signing byte-identical. Add a create_job consumer in the existing get_* style. Fixes Python-roborock#849
Lash-L
approved these changes
Jun 20, 2026
Lash-L
left a comment
Collaborator
There was a problem hiding this comment.
All looks right by the app code!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #849.
B01
/jobswrites fail with401 auth.err.invalid.token. This is the REST path for schedules and anydeferred/cron job — the one place
/jobsis the only option (immediate room cleans now have an MQTT route via#851; scheduling a future clean still has to go through
/jobs)._get_hawk_authenticationalways derivesthe Hawk payload slot from
formdata, which is empty for a JSON body, so the MAC never covers the body theserver receives. GET and bodyless
DELETE /jobs/{id}are unaffected.The fix is two coupled parts:
bodyis signed, putmd5(compact-JSON body)in the payload slot.data=), sincejson=re-serializes with spaces and breaks the MAC.With
body=None, GET and form-post signing stay byte-identical.Verified on a Q10 S5+ (
roborock.vacuum.ss07): with body signing,POST/PUT /jobsreturn 200; the currentempty-payload-slot signature returns 401. The official Roborock iOS app sends the body compact (its
Content-Lengthof 179 equals the no-space serialization, not the longer spaced form), so the exact bytesmust be signed and sent (
data=, notjson=). The completePUT /jobsfrom the iOS app, observed via anHTTPS proxy — every line in its original order, only sensitive values redacted in place (
Authorization,X-UID,Cookie) and device identifiers placeheld:The auth change is generic for any body-bearing write; I've wired one
create_jobconsumer in the existingget_*style. Happy to adjust naming or scope in review.This is my first PR; AI-assisted, reviewed and refined with care by me: Andrew, a human.