Skip to content

fix(slack): use SLACK_USER_TOKEN when connecting to Slack#28103

Merged
Takhoffman merged 2 commits intoopenclaw:mainfrom
Glucksberg:fix/issue-26480
Mar 1, 2026
Merged

fix(slack): use SLACK_USER_TOKEN when connecting to Slack#28103
Takhoffman merged 2 commits intoopenclaw:mainfrom
Glucksberg:fix/issue-26480

Conversation

@Glucksberg
Copy link
Contributor

Summary

fix(slack): use SLACK_USER_TOKEN when connecting to Slack (closes #26480)

fix(providers): extend sanitizeToolsForGoogle to cover google-generative-ai provider (closes #20197)

Diff: 12 files changed, 42 insertions(+), 16 deletions(-)

Fixes #26480

🤖 Generated with Claude Code

@openclaw-barnacle openclaw-barnacle bot added channel: slack Channel integration: slack commands Command implementations agents Agent runtime and tooling size: S experienced-contributor labels Feb 27, 2026
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 27, 2026

Greptile Summary

Refactored Slack user token handling to centralize resolution at account level (supporting SLACK_USER_TOKEN env var) and extended Google provider schema sanitization to all google-* providers.

  • Slack user tokens now resolved consistently via resolveSlackUserToken and stored in account.userToken field
  • Added SLACK_USER_TOKEN environment variable support for default account
  • Updated 10 core files to use centralized account.userToken instead of account.config.userToken?.trim()
  • Extended sanitizeToolsForGoogle to cover all providers starting with "google" (not just google-gemini-cli)
  • Added test coverage for google-generative-ai provider

Issue: The Slack extension plugin (extensions/slack/src/channel.ts) was not updated and still uses the old account.config.userToken pattern, which won't work with the new SLACK_USER_TOKEN environment variable.

Confidence Score: 3/5

  • Safe to merge with follow-up fix needed for extension plugin
  • Core implementation is correct and well-tested, but the extension plugin needs updating for consistency and full SLACK_USER_TOKEN support
  • extensions/slack/src/channel.ts needs to be updated to use the new userToken pattern

Last reviewed commit: ba6d3b9

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

12 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 27, 2026

Additional Comments (2)

extensions/slack/src/channel.ts
inconsistent with core changes - should use account.userToken instead of accessing account.config.userToken directly (this won't work with SLACK_USER_TOKEN env var)

Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/slack/src/channel.ts
Line: 42

Comment:
inconsistent with core changes - should use `account.userToken` instead of accessing `account.config.userToken` directly (this won't work with SLACK_USER_TOKEN env var)

How can I resolve this? If you propose a fix, please make it concise.

extensions/slack/src/channel.ts
inconsistent with core changes - should use account.userToken instead of accessing account.config.userToken directly (this won't work with SLACK_USER_TOKEN env var)

Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/slack/src/channel.ts
Line: 207

Comment:
inconsistent with core changes - should use `account.userToken` instead of accessing `account.config.userToken` directly (this won't work with SLACK_USER_TOKEN env var)

How can I resolve this? If you propose a fix, please make it concise.

@bmendonca3
Copy link

The account.userToken plumbing looks right, but I’d like one more regression here for the env-only/default-account path. Most of the call sites changed from account.config.userToken to account.userToken, so a test that proves SLACK_USER_TOKEN works when there is no explicit channels.slack.userToken config would make this much easier to trust.

@bmendonca3
Copy link

The SLACK_USER_TOKEN direction looks right, but I think the coverage should go one step further than capabilities tests. It would help to add an env-only / default-account regression for the actual runtime call path that consumes the token, so we know this still works when the token is provided outside a fully populated account config block. That is the path most likely to regress later.

@Takhoffman Takhoffman mentioned this pull request Mar 1, 2026
18 tasks
@aisle-research-bot
Copy link

aisle-research-bot bot commented Mar 1, 2026

🔒 Aisle Security Analysis

We found 2 potential security issue(s) in this PR:

# Severity Title
1 🟡 Medium Slack action reads now implicitly use env-sourced user token (SLACK_USER_TOKEN), expanding data access beyond bot token
2 🔵 Low Implicit SLACK_USER_TOKEN env var enables user-token Slack API usage in monitor provider (least-privilege regression)

1. 🟡 Slack action reads now implicitly use env-sourced user token (SLACK_USER_TOKEN), expanding data access beyond bot token

Property Value
Severity Medium
CWE CWE-200
Location src/agents/tools/slack-actions.ts:105-121

Description

The Slack actions tool now uses account.userToken (which can be resolved from process.env.SLACK_USER_TOKEN for the default account) rather than only account.config.userToken.

This creates an implicit privilege expansion:

  • Input/source: SLACK_USER_TOKEN environment variable is accepted for the default Slack account in resolveSlackAccount().
  • Behavior change: handleSlackAction() now prefers the resolved user token for read operations (readMessages, reactions, pins, emojiList, etc.).
  • Impact: If SLACK_USER_TOKEN is a full user token with broader workspace/channel access than the bot token, users/agents who can invoke Slack actions can cause the service to read from channels the bot would not normally be able to access (e.g., public channels the bot is not a member of, or private channels the user token can access). This can lead to unintended sensitive data exposure via tool outputs.

Vulnerable code:

const account = resolveSlackAccount({ cfg, accountId });// ...
const userToken = account.userToken;

const getTokenForOperation = (operation: "read" | "write") => {
  if (operation === "read") {
    return userToken ?? botToken; // user token is preferred for reads
  }// ...
};

Related enabling change (env user token resolution):

const envUser = allowEnv ? resolveSlackUserToken(process.env.SLACK_USER_TOKEN) : undefined;
const userToken = configUser ?? envUser;

Even though userTokenReadOnly defaults to true (preventing user-token writes), the expanded read surface can still be security-relevant in deployments where the Slack user token is highly privileged and Slack action outputs are exposed to less-trusted users.

Recommendation

Require explicit opt-in before using an environment-provided Slack user token for tool operations.

Options:

  1. Only use userToken when explicitly configured in config (revert behavior for tools):
// Use config-provided token only (explicit opt-in)
const userToken = account.config.userToken?.trim() || undefined;
  1. Or gate env user-token usage behind an explicit config flag, e.g. channels.slack.allowEnvUserToken === true:
const userToken = account.config.allowEnvUserToken
  ? account.userToken
  : account.config.userToken?.trim() || undefined;
  1. Consider also preferring bot token for reads by default and only using user token for reads when explicitly enabled, to maintain least privilege.

Additionally, document clearly that setting SLACK_USER_TOKEN will affect tool behavior and can broaden read access.


2. 🔵 Implicit SLACK_USER_TOKEN env var enables user-token Slack API usage in monitor provider (least-privilege regression)

Property Value
Severity Low
CWE CWE-250
Location src/slack/monitor/provider.ts:121

Description

The Slack monitor provider now prefers account.userToken over the bot token when performing Slack Web API lookups used to resolve channel/user allowlists.

Because account.userToken can be sourced from the SLACK_USER_TOKEN environment variable (via resolveSlackAccount), merely having that env var present for the default account can silently switch these Slack API calls from bot-token context to user-token context.

Impact:

  • Privilege/visibility expansion: user tokens commonly have broader scopes/visibility than bot tokens, potentially allowing:
    • resolving/listing private channels and other conversations not visible to the bot
    • resolving/listing users (and profile fields like email) beyond what the bot could access
  • Opt-in bypass/confusion: previously, user-token usage required setting channels.slack.userToken in config (slackCfg.userToken?.trim()); now an environment variable can implicitly enable it without any explicit config opt-in.
  • These user-token-backed lookups are then used to rewrite/patch effective allowlists (channelsConfig, allowFrom) at runtime, which can change effective monitoring/allowlist semantics and the data the process can access.

Vulnerable change (token selection):

const resolveToken = account.userToken || botToken;

Example sinks using resolveToken:

await resolveSlackChannelAllowlist({ token: resolveToken, entries });
await resolveSlackUserAllowlist({ token: resolveToken, entries: allowEntries });

Recommendation

Require explicit opt-in before using a user token (especially if sourced from environment), and default to bot token for monitor operations.

Options:

  1. Keep prior behavior (config-only) for monitor allowlist resolution:
const resolveToken = slackCfg.userToken?.trim() || botToken;
  1. Add an explicit flag (e.g. channels.slack.useUserTokenForLookups: true) and gate env/config user token usage behind it:
const allowUserToken = slackCfg.useUserTokenForLookups === true;
const resolveToken = allowUserToken && account.userToken ? account.userToken : botToken;
  1. At minimum, if account.userTokenSource === "env", emit a prominent warning and require a second explicit enable flag to avoid accidental escalation.

Analyzed PR: #28103 at commit ad09b44

Last updated on: 2026-03-01T17:47:44Z

@Takhoffman Takhoffman merged commit 6dbbc58 into openclaw:main Mar 1, 2026
9 checks passed
@Takhoffman
Copy link
Contributor

Merged via squash in 6dbbc58.

Thanks for the contribution. I pushed a small follow-up fix commit (ad09b4419928d3417c307a7958cc050ff4b082c7) before merge to keep this PR landable:

  • added missing userTokenSource in typed Slack account test fixtures
  • added the changelog entry for this fix

Verification run on the merged head:

  • pnpm check
  • pnpm build
  • pnpm test:macmini

All three passed.

zooqueen added a commit to hanzoai/bot that referenced this pull request Mar 1, 2026
ansh pushed a commit to vibecode/openclaw that referenced this pull request Mar 2, 2026
…8103)

* fix(slack): use SLACK_USER_TOKEN when connecting to Slack (closes openclaw#26480)

* test(slack): fix account fixture typing for user token source

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
steipete pushed a commit to Sid-Qin/openclaw that referenced this pull request Mar 2, 2026
…8103)

* fix(slack): use SLACK_USER_TOKEN when connecting to Slack (closes openclaw#26480)

* test(slack): fix account fixture typing for user token source

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
safzanpirani pushed a commit to safzanpirani/clawdbot that referenced this pull request Mar 2, 2026
…8103)

* fix(slack): use SLACK_USER_TOKEN when connecting to Slack (closes openclaw#26480)

* test(slack): fix account fixture typing for user token source

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
steipete pushed a commit to Sid-Qin/openclaw that referenced this pull request Mar 2, 2026
…8103)

* fix(slack): use SLACK_USER_TOKEN when connecting to Slack (closes openclaw#26480)

* test(slack): fix account fixture typing for user token source

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
amitmiran137 pushed a commit to amitmiran137/openclaw that referenced this pull request Mar 2, 2026
…8103)

* fix(slack): use SLACK_USER_TOKEN when connecting to Slack (closes openclaw#26480)

* test(slack): fix account fixture typing for user token source

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
hanqizheng pushed a commit to hanqizheng/openclaw that referenced this pull request Mar 2, 2026
…8103)

* fix(slack): use SLACK_USER_TOKEN when connecting to Slack (closes openclaw#26480)

* test(slack): fix account fixture typing for user token source

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
execute008 pushed a commit to execute008/openclaw that referenced this pull request Mar 2, 2026
…8103)

* fix(slack): use SLACK_USER_TOKEN when connecting to Slack (closes openclaw#26480)

* test(slack): fix account fixture typing for user token source

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
dorgonman pushed a commit to kanohorizonia/openclaw that referenced this pull request Mar 3, 2026
…8103)

* fix(slack): use SLACK_USER_TOKEN when connecting to Slack (closes openclaw#26480)

* test(slack): fix account fixture typing for user token source

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
sachinkundu pushed a commit to sachinkundu/openclaw that referenced this pull request Mar 6, 2026
…8103)

* fix(slack): use SLACK_USER_TOKEN when connecting to Slack (closes openclaw#26480)

* test(slack): fix account fixture typing for user token source

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
…8103)

* fix(slack): use SLACK_USER_TOKEN when connecting to Slack (closes openclaw#26480)

* test(slack): fix account fixture typing for user token source

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
zooqueen added a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling channel: slack Channel integration: slack commands Command implementations size: XS

Projects

None yet

3 participants