Commit e623802
feat: channel-based agent authorization for Slack (#2033)
* feat: add channel-based agent authorization for Slack
Enable linked Slack users in channels with configured default agents to
execute those agents without explicit SpiceDB project membership.
Changes:
- Extend JWT schema with channel auth claims (authorized, authSource,
channelId, authorizedProjectId)
- Add SpiceDB bypass in trySlackUserJwtAuth when channel-authorized with
project binding verification (D8)
- Extend BaseExecutionContext metadata with slack auth context
- Switch app-mention.ts from resolveChannelAgentConfig to
resolveEffectiveAgent (D7) and pass channel auth params
- Update slash command background exec to pass channel auth params
- Add comprehensive tests for bypass logic, project mismatch rejection,
and graceful fallback
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: replace non-null assertion with safe fallback in auth metadata
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: update app-mention tests to use resolveEffectiveAgent
Tests were mocking the old resolveChannelAgentConfig from utils, but the
implementation now imports resolveEffectiveAgent from agent-resolution.
Updated all test cases to mock the correct module and include the
required `source` field in mock return values.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: address PR review feedback - schema invariant, tests, changeset
Review feedback addressed:
Major:
- Add .refine() to SlackAccessTokenPayloadSchema enforcing that when
authorized=true, authorizedProjectId and authSource are required
- Add changeset for agents-core (patch)
- Add signSlackUserToken channel auth param verification in app-mention test
Minor:
- Change BaseExecutionContext.metadata.slack.authorized to literal `true`
since the field is only populated when authorization is granted
Consider:
- Add debug log in runAuth.ts when channel auth bypass is not applied
- Add test for authSource default fallback to 'channel'
- Add schema invariant enforcement tests (authorized without
authorizedProjectId, authorized without authSource)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add Phase 2 channel auth — modal/command slackAuthorized:false + OTel spans
- Modal submissions (call sites 3-4): explicit slackAuthorized: false
- /inkeep run and /inkeep list (call sites 6-7): explicit slackAuthorized: false
- OTel: add AUTHORIZED and AUTH_SOURCE to SLACK_SPAN_KEYS
- Set slack.authorized and slack.auth_source span attributes in app-mention and modal-submission handlers
- Add modal-submission test file verifying slackAuthorized: false and span attributes
- Add workspace auth source test to app-mention tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add configurable grantAccessToMembers toggle for channel agent auth
Adds a per-channel-config boolean (default: true) that controls whether
channel members get implicit project access via the Slack auth bypass.
When disabled, members need explicit project access even if an agent is
configured for the channel.
Full stack: DB schema + migration, data access, agent resolution, JWT
signing, API validation, and Manage UI toggle in channel agent popover.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: address PR review feedback for grantAccessToMembers
- Add aria-hidden to decorative ShieldCheck icon
- Add grantAccessToMembers to listChannels API return type
- Explicitly set grantAccessToMembers: true in bulk set operations
- Add test for workspace config with explicit grantAccessToMembers: false
- Add command-question tests verifying JWT authorization for
grantAccessToMembers true/false cases
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: update changeset to cover grantAccessToMembers DB column and full-stack toggle
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: add channel-based authorization and grantAccessToMembers toggle to Slack docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: update OpenAPI snapshot to include grantAccessToMembers field
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: trigger CI
* fix formatting
* fix: remove incomplete handleRunCommand and handleAgentListCommand handlers
These handlers referenced three undefined functions (findAgentByIdentifier,
fetchAgentsFromManageApi, createAgentListMessage) that were never implemented,
breaking CI typecheck. The handlers were also not wired into the handleCommand
switch statement. Removed them along with the orphaned createAgentListMessage
test mock. The /inkeep run and /inkeep list commands can be added in a follow-up PR.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: docs mismatch and toggle clarity for grant access setting
- Update configuration.mdx to say workspace defaults "grant access by
default" instead of "always grant access", matching the implementation
which supports explicit false via API
- Replace double-negative toggle logic (!== false) with nullish coalescing
(?? true) for clearer intent in channel-agent-cell.tsx
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* better iconigraphy
* [US-001] Add tests for API error message surfacing in Slack responses
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: surface API errors, add workspace grant toggle, add Slack profile links
- Surface actual API error messages in Slack instead of generic "Something
went wrong" by parsing response body. Falls back to classified errors when
body can't be parsed. Applied to streaming, commands, and modal submissions.
- Add grantAccessToMembers toggle to workspace default section, mirroring
the channel-level toggle. Includes handler, toast feedback, and read-only
state for non-admins.
- Add "View in Slack" profile link to MyLinkStatus and LinkedUsersSection
using https://app.slack.com/team/{slackUserId}. Opens in new tab.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: add PR screenshots for channel auth UX
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: clarify workspace grant access toggle messaging
Make it explicit that the toggle grants access to any Slack workspace
member, not just vaguely "workspace members".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add aria-hidden to icons inside accessible span
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: use mockFetch instead of global.fetch in streaming tests
The streaming code uses getInProcessFetch() not global.fetch.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: update api-key-auth test assertions to include tenantId
The canUseProjectStrict call now includes tenantId after a change on main.
Update test expectations to match.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix pixel match
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Andrew Mikofalvy <5668128+amikofalvy@users.noreply.github.com>1 parent 4cd35aa commit e623802
File tree
50 files changed
+5496
-121
lines changed- .changeset
- .github/pr-assets
- agents-api
- __snapshots__
- src
- __tests__/run/middleware
- middleware
- agents-docs/content/talk-to-your-agents/slack
- agents-manage-ui
- src
- __screenshots__
- components/icons
- features/work-apps/slack
- api
- components
- agent-configuration-card
- packages
- agents-core
- drizzle/runtime
- meta
- src
- __tests__/utils
- data-access/runtime
- db/runtime
- types
- utils
- agents-work-apps/src
- __tests__/slack
- slack
- routes
- services
- commands
- events
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
50 files changed
+5496
-121
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
Loading
Loading
Loading
Loading
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
38491 | 38491 | | |
38492 | 38492 | | |
38493 | 38493 | | |
| 38494 | + | |
| 38495 | + | |
| 38496 | + | |
38494 | 38497 | | |
38495 | 38498 | | |
38496 | 38499 | | |
| |||
38597 | 38600 | | |
38598 | 38601 | | |
38599 | 38602 | | |
| 38603 | + | |
| 38604 | + | |
| 38605 | + | |
38600 | 38606 | | |
38601 | 38607 | | |
38602 | 38608 | | |
| |||
38765 | 38771 | | |
38766 | 38772 | | |
38767 | 38773 | | |
| 38774 | + | |
| 38775 | + | |
| 38776 | + | |
38768 | 38777 | | |
38769 | 38778 | | |
38770 | 38779 | | |
| |||
38947 | 38956 | | |
38948 | 38957 | | |
38949 | 38958 | | |
| 38959 | + | |
| 38960 | + | |
| 38961 | + | |
38950 | 38962 | | |
38951 | 38963 | | |
38952 | 38964 | | |
| |||
39018 | 39030 | | |
39019 | 39031 | | |
39020 | 39032 | | |
| 39033 | + | |
| 39034 | + | |
| 39035 | + | |
39021 | 39036 | | |
39022 | 39037 | | |
39023 | 39038 | | |
| |||
39192 | 39207 | | |
39193 | 39208 | | |
39194 | 39209 | | |
| 39210 | + | |
| 39211 | + | |
| 39212 | + | |
39195 | 39213 | | |
39196 | 39214 | | |
39197 | 39215 | | |
| |||
39249 | 39267 | | |
39250 | 39268 | | |
39251 | 39269 | | |
| 39270 | + | |
| 39271 | + | |
| 39272 | + | |
39252 | 39273 | | |
39253 | 39274 | | |
39254 | 39275 | | |
| |||
0 commit comments