Skip to content

Allow scoped Thread Debug operator access - #2630

Draft
3mdistal wants to merge 1 commit into
mainfrom
codex/dispatch-thread-debug-operators
Draft

Allow scoped Thread Debug operator access#2630
3mdistal wants to merge 1 commit into
mainfrom
codex/dispatch-thread-debug-operators

Conversation

@3mdistal

@3mdistal 3mdistal commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Problem

Slack-triggered runs are stored under a service-principal owner such as integration@slack. Thread Debug previously limited ordinary members to their own human-owned Dispatch threads, so a Builder operator could not inspect an organization-owned Slack-to-Content trace without broader Dispatch admin access. Failed or unavailable lookups could also appear as successful zero-result searches, hiding the distinction operators needed most.

Approach

Add a dedicated read-only Thread Debug operator permission. Cross-app organization IDs are local to each app, so the selected source resolves the caller's active organization through its stable allowed domain and permits the trace query only when that mapping identifies exactly one target organization. Service-principal ownership is then an optional filter inside that organization boundary—not a fake human membership.

This permission applies only to the existing read-only Thread Debug actions and does not grant any Dispatch mutation capability.

What changed

  • Added DISPATCH_THREAD_DEBUG_OPERATOR_EMAILS as a narrow operator allowlist for callers with an active organization.
  • Scoped current-app reads by the exact local organization ID and connected-app reads by one uniquely resolved target organization ID.
  • Return explicit 403 denials for unauthorized cross-app access, missing organization mappings, and zero or duplicate target mappings.
  • Kept request failures and unavailable sources distinct from successful empty results in both the store and Thread Debug UI.
  • Updated action descriptions and Dispatch guidance so agents understand the read-only operator boundary.
  • Added a Dispatch package changeset and user-facing changelog entry.

Safety and operations

  • No schema migration or production-data mutation is included.
  • The allowlist grants only the existing read-only Thread Debug action surface.
  • Cross-organization reads fail closed: the remote organization mapping must resolve to exactly one row.
  • Deployment configuration must add the approved operator email to DISPATCH_THREAD_DEBUG_OPERATOR_EMAILS before the production canary can exercise the new path.

Verification

  • pnpm --filter @agent-native/dispatch test — 61 files and 349 tests passed, covering the exact Slack canary marker shape, organization-owned service principals, zero and duplicate organization mappings, explicit 403 propagation, genuine empty results, and mixed unavailable results.
  • pnpm --filter @agent-native/dispatch typecheck — passed.
  • pnpm guards — all repository guards passed.
  • Independent authorization-boundary review — passed after correcting duplicate-domain handling, mixed-result truthfulness, action descriptions, and 403 propagation through aggregate failure lookup.
  • Production Slack canary — intentionally not rerun during Work; it remains the post-deploy acceptance check.

Review focus

  • Does the allowed-domain resolution fail closed under every ambiguous or missing mapping?
  • Can the operator allowlist reach any mutation surface or any organization outside the active organization?
  • Does every failed or partial load remain visibly distinguishable from a genuine empty result?

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Visual recap — skipped

The visual recap job did not run for this pull request. This is informational only and does not block the PR.

Recap skipped for 85b1c52: draft PR.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

@netlify

This comment has been minimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant