FlowDrop Workflow Specification 1.0-draft

Snapshot access is decided on the snapshot, and absence answered first

The rule

Normative: this is the rule
  1. 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 is 403, and absence is answered before denial.
  2. A read that finds the record but no readable payload answers 404 as well, never a partial document.
  3. 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

A snapshot nobody stored404 — refused
GET /api/flowdrop-runtime/snapshot/{execution_id}

{ "success": false, "error": "Snapshot not found" }
A snapshot that exists but belongs to someone else403 — refused
GET /api/flowdrop-runtime/snapshot/{execution_id}

{ "success": false, "error": "Access denied" }
Rule identifiers are permanent and are never renumbered. Each implementation publishes its own standing against these rules; this specification does not.spec 1.0-draft · SNAP-2 · changed in spec 1.0