You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The public approval share link (/s/<token>, capability URL) currently gates BOTH reviewing and approving behind a no-login token, and the reviewer "response" field is text-only. Three gaps:
Approve = publish, with no auth. Clicking approve publishes the item to the owner's connected YouTube/LinkedIn (Buffer). A leaked/forwarded/logged link can publish AS the owner. (Reviewing is read-only and fine no-login; the mutation is the risk.)
No file/image upload in the response. Reviewers can only leave text. They can't attach an image/screenshot to say e.g. "show THIS image at the 'lonely' beat" — so feedback that references assets is impossible on-page.
Proposed: approval UX = public preview, authenticated rich-feedback approve
Auth-gate the mutation. Keep read-only review on the no-login token (treat as short-lived bearer secret). Require an authenticated workspace user (with publish permission) for APPROVE and for any publish-triggering decision. Token stays as "review context"; the decision endpoint checks auth. (codex security review concurred: separate read vs approve scope; short expiry; bind approval to item+workspace+action+version; audit log IP/user/action; revoke-on-publish.)
Attachments in the response. The approve/reject response accepts text notes AND image/file uploads. Reuse the existing _store_uploaded_blob + /approvals/{approval_id}/uploads machinery; persist attachments on the approval/decision so the worker can consume them.
Feedback → re-render loop. Reject-with-notes (text + attachments) flows into the worker's durable rules / a re-render, so the fixed version returns as a new approval. Generalizes the SF-vlog prototype (sf_feedback_loop) into the platform, on top of feat: persist rejection feedback as worker rules #2080.
Relevant code
engine/apps/api/routers/approvals.py — public decision endpoints (/approvals/public-batch/{token}/items/{id}/decision, /approvals/public/{id}/approve|reject), uploads (/approvals/{id}/uploads, /approvals/public/{id}/uploads), _store_uploaded_blob, emit_approval_decided, the share-link scope helpers.
Share-link scope: services/share_links.py + the ShareLinkRepository (read vs approve token scopes).
Engine changes here; the cloud dashboard public approval page (workeros-cloud) needs the matching UI ("Sign in to approve", attachment picker). File a linked cloud issue/PR.
Problem
The public approval share link (
/s/<token>, capability URL) currently gates BOTH reviewing and approving behind a no-login token, and the reviewer "response" field is text-only. Three gaps:Proposed: approval UX = public preview, authenticated rich-feedback approve
_store_uploaded_blob+/approvals/{approval_id}/uploadsmachinery; persist attachments on the approval/decision so the worker can consume them.Relevant code
engine/apps/api/routers/approvals.py— public decision endpoints (/approvals/public-batch/{token}/items/{id}/decision,/approvals/public/{id}/approve|reject), uploads (/approvals/{id}/uploads,/approvals/public/{id}/uploads),_store_uploaded_blob,emit_approval_decided, the share-link scope helpers.services/share_links.py+ theShareLinkRepository(read vs approve token scopes).worker_rulespath.Acceptance criteria
Companion
Engine changes here; the cloud dashboard public approval page (workeros-cloud) needs the matching UI ("Sign in to approve", attachment picker). File a linked cloud issue/PR.