Skip to content

🔐 feat: Add Admin-Assigned Slack Bot Managers - #17836

Merged
dustinhealy merged 6 commits into
fix/slack-workspace-member-connectionsfrom
feat/slack-bot-managers
Nov 11, 2026
Merged

dustinhealy merged 6 commits into
fix/slack-workspace-member-connectionsfrom
feat/slack-bot-managers

Conversation

@dustinhealy

@dustinhealy dustinhealy commented Nov 5, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Agent sharing permission currently lets a member claim an unassigned destination for any organization-installed Slack bot. A connection's creator then controls replacement, rather than an administrator choosing who may manage the bot.

Administrators can now select Manage bot access on a connected workspace and grant named users management of that app/workspace installation. Those managers can assign agents and explicitly replace another manager's assignment, provided they also have permission to share the agent they choose. Managing a bot does not grant Slack credentials, installation administration, Agent access or permission to manage other managers.

How it works

  • Reuses tenant-scoped ACL entries with a distinct slackBot resource and direct user grants. Dedicated, fresh-admin-authorized endpoints manage membership; generic sharing does not support this resource.
  • Checks bot management inside the existing assignment transaction. Grant updates and assignments write the same workspace authority fence, so an assignment paused before revocation cannot commit afterward. Revision-checked updates prevent stale dialogs from overwriting another administrator's changes.
  • Offers members only bots they can manage, filtering before pagination. Manager search uses the same fresh administrator capabilities as grant updates, the existing user-search helpers and a tenant/account-scoped cache. It returns only current users from the active tenant.
  • Preserves existing assignments and conversations after management access is removed. A former manager can still remove assignments or delete their own connection. Active reauthorization preserves grants; disconnect and fresh installation clear them.
Administrator grants bot management
  → manager chooses a permitted bot in Agent Builder
  → Agent SHARE and Remote Agents USE remain required
  → assignment transaction checks the current bot grant
  → Slack senders still link and use their own LibreChat accounts

Testing

  • Real MongoDB tests cover tenant-local grants, stale revisions, paused assignment versus revocation, co-manager replacement, filtered pagination, token refresh and disconnect/reinstallation.
  • HTTP tests cover capability-authorized administrators without legacy VIEW_USERS, tenant-local candidate filtering, administrator-only grants, forged permissions, member assignment and cleanup after revocation; generic sharing remains denied.
  • Component tests cover selecting managers, cancellation, stale-save recovery, failed reads, visible search failure/retry and hiding ungranted bots.
  • Chrome exercises installation, manager selection/save/reopen, member assignment/replacement and cleanup in light and dark mode. External Slack/workspace HTTP responses are fixtures; storage authorization is exercised separately against MongoDB.
  • Provider configuration tests, owning workspace builds/typechecks, full pre-push checks and Lighthouse passed locally. The hook skips config-migration tests and optional depcheck is unavailable; the provider configuration suite passed all 601 cases.

Screenshots / recordings

The bot-access dialog is new; there is no corresponding dialog on the base revision. These captures show the running application with a selected manager, before saving.

Grant bot management

Light Dark
Administrator selecting a bot manager in light mode Administrator selecting a bot manager in dark mode

Retry a failed search

A failed lookup displays an actionable error and keeps unsaved management changes in the dialog.

Light Dark
Search failure with Retry in light mode Search failure with Retry in dark mode

Risk / compatibility

Non-administrators require an explicit bot-manager grant before creating or changing assignments, including previously unclaimed destinations. Existing assignments keep running. The configurable channels.maxBotManagers defaults to 50 per installation. No deployment configuration changes are required.

Checklist

  • I reviewed my own changes
  • Relevant tests have been added or updated
  • Existing relevant tests pass
  • The change does not introduce new warnings or errors
  • User-facing or complex behavior is documented where necessary
  • Required dependency changes have been merged/published
  • Required documentation PR: LibreChat documentation #892

@dustinhealy
dustinhealy added this pull request to stack #17807 November 5, 2026 16:04
@dustinhealy

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-05T16:42:38.483496Z 2d87f24 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 19fce38ac8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copilot AI balanced review requested due to automatic review settings November 5, 2026 16:33
@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Lighthouse CI failed. The last 80 log lines contain the measured budgets and assertion failures.

│ 23      │ 'http://localhost:3080/api/mcp/servers'                                                                         │ 2971.95000000007   │ 4239.038000000059  │ 200    │
│ 24      │ 'http://localhost:3080/api/permissions/mcpServer/effective/all'                                                 │ 2973.094000000041  │ 3739.6040000000503 │ 200    │
│ 25      │ 'http://localhost:3080/api/prompts/groups?limit=10'                                                             │ 2973.286000000022  │ 4244.257000000041  │ 200    │
│ 26      │ 'http://localhost:3080/api/keys?name=openAI'                                                                    │ 3503.067000000039  │ 4023.1110000000335 │ 200    │
│ 27      │ 'http://localhost:3080/api/presets'                                                                             │ 3505.585000000021  │ 4023.369000000006  │ 200    │
│ 28      │ 'http://localhost:3080/api/tags'                                                                                │ 3506.645000000077  │ 4023.65200000006   │ 200    │
│ 29      │ 'http://localhost:3080/api/share/link/16390000-0000-4000-8000-000000000001'                                     │ 3506.8790000000736 │ 4247.908000000054  │ 200    │
│ 30      │ 'http://localhost:3080/api/messages/16390000-0000-4000-8000-000000000001?toolPreviews=1'                        │ 3507.116000000038  │ 4538.844000000041  │ 200    │
│ 31      │ 'http://localhost:3080/api/user/settings/favorites/tools'                                                       │ 3511.51800000004   │ 4539.362000000081  │ 200    │
│ 32      │ 'http://localhost:3080/api/endpoints/token-config'                                                              │ 3511.82500000007   │ 4497.655000000028  │ 200    │
│ 33      │ 'http://localhost:3080/api/user/settings/skills/active'                                                         │ 3512.0410000000265 │ 4538.580000000016  │ 200    │
│ 34      │ 'http://localhost:3080/api/agents/tools/web_search/auth'                                                        │ 3512.2420000000275 │ 7276.530000000028  │ 200    │
│ 35      │ 'http://localhost:3080/api/agents/tools/calls?conversationId=16390000-0000-4000-8000-000000000001'              │ 3512.4160000000265 │ 4756.115000000049  │ 200    │
│ 36      │ 'http://localhost:3080/api/agents/chat/status/16390000-0000-4000-8000-000000000001?generationProtocolVersion=2' │ 4673.74700000009   │ 4930.535000000033  │ 200    │
└─────────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴────────────────────┴────────────────────┴────────┘

Inspect .lighthouse HTML/JSON and e2e/lighthouse/README.md. Reuse loaded user/config data; overlap independent reads without bypassing authorization.

┌─────────┬────────────────────────────┬──────────────────────┬───────┐
│ (index) │ audit                      │ median               │ limit │
├─────────┼────────────────────────────┼──────────────────────┼───────┤
│ 0       │ 'largest-contentful-paint' │ 4557.391             │ 4500  │
│ 1       │ 'cumulative-layout-shift'  │ 0.017901164685666746 │ 0.1   │
│ 2       │ 'total-blocking-time'      │ 416.596              │ 500   │
└─────────┴────────────────────────────┴──────────────────────┴───────┘

  1) [chromium] › e2e/lighthouse/load.spec.ts:10:5 › serial database latency stays within web-vitals budgets 

    Error: Median largest-contentful-paint must stay within 4500

    expect(received).toBeLessThanOrEqual(expected)

    Expected: <= 4500
    Received:    4557.391

       at audit.ts:127

      125 |   console.table(measured);
      126 |   for (const { audit, median, limit } of measured) {
    > 127 |     expect(median, `Median ${audit} must stay within ${limit}`).toBeLessThanOrEqual(limit);
          |                                                                 ^
      128 |   }
      129 |   return results;
      130 | }
        at auditPage (/home/runner/work/LibreChat/LibreChat/e2e/lighthouse/audit.ts:127:65)
        at /home/runner/work/LibreChat/LibreChat/e2e/lighthouse/load.spec.ts:33:19

    attachment #1: screenshot (image/png) ──────────────────────────────────────────────────────────
    e2e/lighthouse/.test-results/load-serial-database-latency-stays-within-web-vitals-budgets-chromium/test-failed-1.png
    ────────────────────────────────────────────────────────────────────────────────────────────────

    Error Context: e2e/lighthouse/.test-results/load-serial-database-latency-stays-within-web-vitals-budgets-chromium/error-context.md

    attachment #3: trace (application/zip) ─────────────────────────────────────────────────────────
    e2e/lighthouse/.test-results/load-serial-database-latency-stays-within-web-vitals-budgets-chromium/trace.zip
    Usage:

        npx playwright show-trace e2e/lighthouse/.test-results/load-serial-database-latency-stays-within-web-vitals-budgets-chromium/trace.zip

    ────────────────────────────────────────────────────────────────────────────────────────────────


🤖: global teardown has been started
2026-11-05 16:37:13 �[32minfo�[39m: �[32mMongo Connection options�[39m
2026-11-05 16:37:13 �[32minfo�[39m: �[32m{�[39m
�[32m  "bufferCommands": false�[39m
�[32m}�[39m
🤖:  ✅  Connected to Database
🤖:  ✅  Found user in Database
🤖:  ✅  Deleted 1 convos & 2 messages
🤖:  ✅  Deleted user from Database
🤖: global teardown has been started
2026-11-05 16:37:14 �[32minfo�[39m: �[32mMongo Connection options�[39m
2026-11-05 16:37:14 �[32minfo�[39m: �[32m{�[39m
�[32m  "bufferCommands": false�[39m
�[32m}�[39m
🤖:  ✅  Connected to Database
🤖:  ⚠️  User not found in Database
  1 failed
    [chromium] › e2e/lighthouse/load.spec.ts:10:5 › serial database latency stays within web-vitals budgets 

Open the full run

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The revocation guarantee depends on MongoDB retries and shared write fences across ACL updates and assignments, requiring confirmation through replica-set concurrency tests that could not run in this review environment.

No open issues 🎉

What changed in this PR

Adds administrator-assigned managers for organization-installed Slack bots, separating bot assignment authority from agent-sharing permission while preserving existing assignments after access is revoked.

Changes:

  • Adds tenant-scoped bot-manager grants, revision-checked updates, and transactional assignment authorization.
  • Adds an administrator management dialog and limits members’ bot choices to installations they can manage.
  • Extends storage, HTTP, component, and browser tests for grants, revocation, replacement, and recovery.
File Description
packages/​data-schemas/​src/​methods/​slackWorkspace.ts Integrates grants, filters workspace lists, and clears grants on disconnect.
packages/​data-schemas/​src/​methods/​slackRoute.ts Checks bot-management authority inside assignment transactions.
packages/​data-schemas/​src/​methods/​slackRoute.spec.ts Tests grants, revocation races, replacement, pagination, and installation lifecycle.
packages/​data-schemas/​src/​methods/​slackBotAccess.ts Implements tenant-scoped manager search, reads, and revision-checked writes.
packages/​data-schemas/​src/​admin/​capabilities.ts Maps Slack bot resources to agent-management capability.
packages/​data-provider/​src/​types/​channels.ts Adds manager types and bot-management metadata.
packages/​data-provider/​src/​data-service.ts Adds manager read, search, and update API clients.
packages/​data-provider/​src/​config.ts Adds the configurable manager limit, defaulting to 50.
packages/​data-provider/​src/​accessPermissions.ts Defines the Slack bot resource type.
packages/​api/​src/​middleware/​share.ts Excludes Slack bots from generic sharing.
packages/​api/​src/​middleware/​share.spec.ts Tests generic-sharing rejection for Slack bots.
packages/​api/​src/​channels/​workspaces.spec.ts Tests administrator-only manager endpoints and tenant isolation.
packages/​api/​src/​channels/​workspaceRuntime.ts Supplies the configured manager limit to handlers.
packages/​api/​src/​channels/​workspaceHttp.ts Adds manager endpoints and permission-aware workspace responses.
packages/​api/​src/​channels/​workspaceBindings.ts Requires bot-management authority for connection creation and assignment.
packages/​api/​src/​channels/​slackDispatch.spec.ts Tests manager assignment, forged authority rejection, and post-revocation cleanup.
e2e/​specs/​mock/​scenarios/​slack-workspaces.spec.ts Exercises manager selection, search recovery, saving, and reopening across themes.
client/​src/​utils/​channelErrors.ts Maps bot-access failures to localized guidance.
client/​src/​locales/​en/​translation.json Adds manager-dialog copy and updates assignment guidance.
client/​src/​components/​SidePanel/​Agents/​WorkspaceChannel.tsx Gates assignment controls on bot access and explains missing permission.
client/​src/​components/​SidePanel/​Agents/​Channels.tsx Offers only active, manageable bots for new connections.
client/​src/​components/​SidePanel/​Agents/​__tests__/​Channels.spec.tsx Tests hidden ungranted bots and revoked-access handling.
client/​src/​components/​Channels/​Workspaces.tsx Adds the administrator’s Manage bot access entry point.
client/​src/​components/​Channels/​BotManagers.tsx Implements manager selection, removal, saving, and error recovery.
client/​src/​components/​Channels/​BotManagers.spec.tsx Tests dialog actions, stale saves, and read/search failures.
api/​server/​routes/​slack-workspaces.js Registers authenticated manager routes with same-origin protection for writes.
api/​server/​controllers/​__tests__/​deleteUserResourceCoverage.spec.js Records existing principal cleanup as handling bot grants.

Review effort: Balanced

@dustinhealy

Copy link
Copy Markdown
Collaborator Author

@codex review

@dustinhealy

Copy link
Copy Markdown
Collaborator Author

Replica-set validation completed locally: all 45 storage cases passed using MongoMemoryReplSet. The revocation test pauses the original database write, commits manager revocation, then releases it; MongoDB retries the conflicted assignment transaction and the revoked grant is denied, leaving no route. Grant refresh, disconnect/reinstallation and tenant-isolation cases also pass. The final HTTP suite additionally verifies that an administrator retains capability-based authority when a redundant direct manager grant is removed during preflight.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: 2d87f241e2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@dustinhealy
dustinhealy force-pushed the feat/slack-bot-managers branch from de813e1 to d18355b Compare November 11, 2026 04:27
@dustinhealy
dustinhealy merged commit 67fd560 into dev Nov 11, 2026
13 of 55 checks passed
@dustinhealy
dustinhealy deleted the feat/slack-bot-managers branch November 11, 2026 05:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants