Skip to content

feat(dispatch): Start DM dispatches for linked provider identities - #2217

Open
sentry-junior[bot] wants to merge 1 commit into
mainfrom
feat/identity-dispatch
Open

sentry-junior[bot] wants to merge 1 commit into
mainfrom
feat/identity-dispatch

Conversation

@sentry-junior

@sentry-junior sentry-junior Bot commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

Step 2 of #2207. Plugin webhook routes get ctx.agent.dispatchForIdentity({ subjectId, idempotencyKey, input, replyAttribution? }). It starts private work in a Slack DM for the person behind one provider account. The result is { status: "created" | "already_exists", id } or { status: "not_linked" }. The call does not throw because the person is untrusted.

Core decides who counts, in code and before any model call:

  • The provider is always the plugin that calls. A plugin cannot name another provider's Identity. Core namespaces (junior, slack) never match.
  • The match uses only the exact provider account id that the OAuth account-linking flow stored (empty tenant, kind user, linked user). Handles, emails, and display names never match.
  • That user must have exactly one Slack Identity in the bot workspace. If there are none or more than one, the result is not_linked.
  • users.info must show a current human member of the bot team: same team, not deleted, not a bot. This repeats the revocation check from Slack ingress.
  • No Slack bot or no team id also gives not_linked. Other Slack and storage errors reach the route.

On a match, core opens the bot DM and creates a normal plugin dispatch with private visibility and a private-direct-conversation credential subject for that Slack user. Binding, validation, and enqueue use the same code as heartbeat dispatches. No second authority path exists.

Not in this PR:

  • Step 3 (action review provenance for the person's instruction) and step 4 (connecting the GitHub webhook and adding the optional reply) come next.
  • Per-plugin rate limits for route dispatches. The route context lives for the whole app, so a heartbeat-style counter does not fit. Today every created dispatch needs a distinct linked member and its own idempotency key. A limit can follow when step 4 shows real traffic.

via BYK.

--

View Junior Session [Sentry]

Plugin webhook routes can call ctx.agent.dispatchForIdentity with a
provider account id. Core binds the provider to the calling plugin and
starts a private Slack DM dispatch only when that Identity is linked
through OAuth to exactly one current Slack member of the bot workspace.
Otherwise it returns not_linked before any model call.

Refs #2207

Co-Authored-By: BYK <burak.kaya@sentry.io>
@vercel

vercel Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
junior-docs Ready Ready Preview Oct 23, 2026 11:12pm UTC

Request Review

This branch was successfully deployed

1 active deployment
Preview – junior-docs — 81c0da14 Deployed Oct 23, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk: high PR risk score: high

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants