feat(slack): support alternate Web API roots#97154
Conversation
|
Codex review: needs maintainer review before merge. Reviewed June 28, 2026, 9:48 PM ET / 01:48 UTC. Summary PR surface: Source +22, Tests +275. Total +297 across 8 files. Reproducibility: not applicable. as a bug reproduction; this PR adds a Slack routing feature. The changed behavior is source-verifiable and covered by PR-head tests that route real Review metrics: 3 noteworthy metrics.
Stored data model Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land the env-only Slack API-root seam only after maintainer acceptance of the trusted Do we have a high-confidence way to reproduce the issue? Not applicable as a bug reproduction; this PR adds a Slack routing feature. The changed behavior is source-verifiable and covered by PR-head tests that route real Is this the best way to solve the issue? Yes, conditionally: using Slack SDK AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 4a4657a1828f. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +22, Tests +275. Total +297 across 8 files. View PR surface stats
Security concerns:
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
8a44502 to
26988b8
Compare
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
7430b67 to
258b831
Compare
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@clawsweeper re-review |
1 similar comment
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
* Allow Slack to target alternate Web API roots * Protect Slack API URL routing * Simplify Slack API URL routing * Use env-only Slack API root routing * Remove Slack client option alias * Keep Slack API URL dotenv test inline * Remove leftover Slack PR churn * Block workspace Slack API URL dotenv * Preserve Slack proxy HTTPS protocol * Keep Slack option resolution explicit * Remove Slack probe formatting diff * fix(slack): preserve explicit API root precedence * fix(slack): narrow cached write client options
* Allow Slack to target alternate Web API roots * Protect Slack API URL routing * Simplify Slack API URL routing * Use env-only Slack API root routing * Remove Slack client option alias * Keep Slack API URL dotenv test inline * Remove leftover Slack PR churn * Block workspace Slack API URL dotenv * Preserve Slack proxy HTTPS protocol * Keep Slack option resolution explicit * Remove Slack probe formatting diff * fix(slack): preserve explicit API root precedence * fix(slack): narrow cached write client options
* Allow Slack to target alternate Web API roots * Protect Slack API URL routing * Simplify Slack API URL routing * Use env-only Slack API root routing * Remove Slack client option alias * Keep Slack API URL dotenv test inline * Remove leftover Slack PR churn * Block workspace Slack API URL dotenv * Preserve Slack proxy HTTPS protocol * Keep Slack option resolution explicit * Remove Slack probe formatting diff * fix(slack): preserve explicit API root precedence * fix(slack): narrow cached write client options
* Allow Slack to target alternate Web API roots * Protect Slack API URL routing * Simplify Slack API URL routing * Use env-only Slack API root routing * Remove Slack client option alias * Keep Slack API URL dotenv test inline * Remove leftover Slack PR churn * Block workspace Slack API URL dotenv * Preserve Slack proxy HTTPS protocol * Keep Slack option resolution explicit * Remove Slack probe formatting diff * fix(slack): preserve explicit API root precedence * fix(slack): narrow cached write client options
What Problem This Solves
PR #95920 was too broad to review because Slack channel extensibility, WhatsApp channel extensibility, and QA Lab Crabline wiring were bundled together.
This PR isolates the Slack foundation: the Slack plugin can route Slack Web API traffic to an alternate Slack-compatible API root without adding Crabline-specific code to Slack.
Why This Change Was Made
A fake Slack API only works if all Slack WebClient construction paths can use the same alternate root. This change centralizes Slack WebClient option resolution so send, action, probe, scope, directory, allowlist, monitor, and cached write-client paths all inherit the same routing behavior.
The production contract preserves normal Slack SDK precedence: explicit
WebClientOptions.slackApiUrlwins, otherwise trusted runtime env can setSLACK_API_URLas the default API root.OPENCLAW_SLACK_API_URLis intentionally not supported as a channel config-style alias.Security / Operator Contract
SLACK_API_URLis a trusted operator/global runtime override. It must not be loaded from an untrusted workspace.env; this PR blocks workspaceSLACK_API_URLinjection while preserving trusted global/state.envand process env behavior.Any process that sets
SLACK_API_URLis choosing the fallback destination for Slack Web API bearer-token requests when a caller has not supplied an explicit SDK API root.User Impact
Normal Slack users keep the default Slack API behavior. QA and integration harnesses can run Slack against a Slack-compatible mock API by setting
SLACK_API_URLin trusted runtime env, while direct SDK callers can still override the route explicitly withWebClientOptions.slackApiUrl.The cached write-client helper remains intentionally narrow: it only accepts the API-root option it keys on, while the uncached write-client constructor still accepts full
WebClientOptions.Stack:
Evidence
node scripts/run-vitest.mjs extensions/slack/src/client.test.ts extensions/slack/src/client.web-api.test.ts src/infra/dotenv.test.ts extensions/slack/src/config-schema.test.tspnpm tsgo:extensionspnpm tsgo:extensions:testPATH="$HOME/.opengrep/cli/latest:$HOME/.local/bin:$PATH" scripts/run-opengrep.sh --changed --sarif --errorgit diff --check742981f59a: setSLACK_API_URLto CrabLine's manifestendpoints.apiRoot; OpenClaw's Slack client successfully ranauth.test,chat.postMessage, andconversations.history; CrabLine recorder observedPOST /api/auth.test,POST /api/chat.postMessage, andPOST /api/conversations.history. Commite2a707746aonly narrows the cached helper type contract and does not change runtime routing behavior.