Repository navigation
fix(relay): reject unreadable write targets as missing - #8249
Draft
wpfleger96 wants to merge 7 commits into
Draft
wpfleger96 wants to merge 7 commits into
wpfleger96 wants to merge 7 commits into
Conversation
Reactions, edits, forum votes, reports, replies, artifact revisions and workflow triggers answered differently for a missing target and one the sender cannot use or read, revealing whether, where and what it was. Each now checks access first through event_visible_to_reader and the channel, and gives the missing-target response for any target the sender cannot use. Reactions to and reports on unreadable events are now rejected. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Run and approval reads returned 403 for a workflow in a channel the caller cannot read (or with no channel) but 404 for a missing one, revealing which workflow IDs exist. Both now get the missing-workflow 404. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
A reaction derives its channel from the target, so the archived-channel error revealed that a target existed and where. It now gets the reaction's not-found denial; writes whose channel comes from the request keep the archived error. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
POST /hooks/{id} needs no login, yet before the secret check it split into 404, 400 for a non-webhook trigger, 500 for a corrupt definition and two 401s, revealing that a workflow existed and its trigger type. The secret is now checked first and every failure before it returns the missing-workflow 404.
Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Covers the archived-channel reaction, the unauthenticated webhook boundary, and workflow replies to parents the owner cannot use. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
The unreadable reply parent is now an author-only deletion, and an owner-only parent proves the resolver reads as the workflow owner rather than the relay. Webhook and workflow-read positive controls now assert a 202 with a run_id and the owner's approvals read for that real run. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
This branch has not been deployed
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.
Stack: #8197 → this PR
🤖 A sender who cannot use or read a referenced event, artifact or workflow now gets exactly the response it would get for an ID that does not exist. #8197 set this rule for deletions; this applies it to the other writes that look up a target, plus the workflow read and webhook endpoints. Artifact
createand workflow definition saves are the exceptions, described below. Access is checked before any message that depends on the target, readability goes throughevent_visible_to_reader(including #8197's private-deletion rule), and soft-deleted targets keep matching missing ones.event_visible_to_reader→ every channel gate for the derived channel, including archivedinvalid: reaction target event not foundhchannel and readable → author / agent-owner checkinvalid: edit target not found or not editable by youhchannel and readable → kind checkinvalid: vote target event not founde)event_visible_to_reader→ token channel scope → channel membership or openinvalid: report target event not foundsend_messagereplies)reply parent not foundh(move: in the source the sender can write) → revision, type, deleted and root checksconflict: artifact head unavailableinvalid: workflow not foundGET /workflows/{id}/runsand/runs/{run_id}/approvals404 {"error":"workflow not found"}POST /hooks/{id}404 {"error":"workflow not found"}Two of these reject writes that used to be accepted: a reaction to an event the sender cannot read (such as someone else's author-only event), and a report on an event the reporter cannot read. Reports by pubkey and by blob are unchanged. In an archived channel, writes whose channel comes from their target (reactions and deletions) get that target's not-found response, and an artifact move out of an archived source channel gets
conflict: artifact head unavailablelike any other source the sender cannot write; every other write keepsinvalid: channel is archived. A webhook call with an absent or wrong secret, or to a workflow without a webhook secret, now gets404instead of401/400. Artifactcreateand workflow definition saves still report a taken ID, as NIP-AR allows for artifacts.Removed messages, none of which any client depends on from these endpoints:
edit target event not found,must be event author to edit,target event belongs to a different channel,target event has no channel,parent event belongs to a different channel,parent event has no channel association,artifact home changed,workflow is not accessible,workflow is not channel-scoped, the webhook'sauthentication failedandwebhook secret required but not configured, andforbidden: not authorized to trigger this workflowfor non-owners (it remains for an owner whose channel authority lapsed).e2e_existence_oraclechecks each event write over HTTP and WS, and the workflow read and webhook endpoints over HTTP, against missing, soft-deleted, other-channel, private-channel, archived, author-only and wrong-kind targets as applicable, with a positive control per path. It runs in the Backend Integration job alongsidee2e_author_only_deletion. In the PostgreSQL suite,head_outside_authorized_channel_matches_missing_headcovers the artifact transaction andworkflow_reply_to_unusable_parent_matches_missingcovers workflow replies throughRelayActionSink::send_message.