Snapshot access is decided on the snapshot, and absence answered first
The rule
- Reading or deleting a snapshot loads it by execution id and asks it for view or delete authority: a snapshot that does not exist is
404, one the caller may not reach is403, and absence is answered before denial. - A read that finds the record but no readable payload answers
404as well, never a partial document. - The list door does not ask per record: it narrows the query by ownership, so a snapshot belonging to another principal is absent from the list rather than a denial on it.
What it means
Reading and deleting a snapshot both load the record first and ask it whether
this caller may view or delete it — the two questions are answered in a fixed
order. An id nobody stored gets 404 no matter who is asking, before the
door even considers whether the asker would have been let in. Only once a
record is found does its own access answer take over, and a record that
exists but is not the caller's own comes back 403, not 404 — the door
does not pretend a snapshot it can name does not exist.
A denial carries nothing about the record it denied: not the workflow that
produced it, not any other trace, only the fixed refusal message. Distinguish
this from the list door, which never reaches a per-record denial at all — it
narrows its query by ownership up front, so a snapshot belonging to someone
else is simply absent from the page rather than a 403 entry on it.
Example
GET /api/flowdrop-runtime/snapshot/{execution_id}
{ "success": false, "error": "Snapshot not found" }GET /api/flowdrop-runtime/snapshot/{execution_id}
{ "success": false, "error": "Access denied" }