Agent Channel Directory Lookup Flow
Overview
An operator searches Slack users or channels while creating or editing an Agent. The Console uses the selected bot Secret to show names and workspace identity, then saves only the selected IDs in channel Configuration. OpenClaw Control Plane (OCC) authorizes and reads the Secret; the selected ChannelDriver owns provider calls. This flow ends when the Console displays candidates or an actionable error.
Entry Points
- Trigger: the Console Slack editor searches or resolves saved IDs, or an authorized caller posts to the Namespace channel directory route.
- Assumptions: the caller can create an Agent or update the exact Agent or Configuration, and can operate the selected same-Namespace Secret.
- Source:
apps/controller/src/console/agents/slack-directory.mjs:createSlackDirectoryField,packages/occ/src/index.ts:OpenClawController.lookupChannelDirectory, andapps/controller/src/drivers/channel/slack.ts:SlackChannelDriver.lookupDirectory.
Flow
graph TD
A["Operator selects bot Secret and searches"] --> B["OCC checks edit target and exact Secret operate"]
B -->|denied or missing| X["Return safe lookup error"]
B -->|authorized| P{"ChannelDriver selected?"}
P -->|no| U["Return 501; Console offers exact-ID entry"]
P -->|yes| C["SecretDriver reads current value"]
C --> D["OCC rechecks target, Secret grant, and backend identity"]
D -->|changed| X
D -->|current| M{"Managed Helm proxy?"}
M -->|yes| H["Tunnel through proxy Service DNS"]
M -->|no| I["Tunnel through external proxy IP"]
H --> E["Slack Driver reads workspace and bounded directory pages"]
I --> E
E -->|provider error| X
E --> F["Console shows names and exact IDs"]
F --> G["Configuration saves selected IDs"]Execution Trace
1. Authorize the selected Secret
packages/occ/src/index.ts:OpenClawController.channelDirectorySecret
The request names a same-Namespace Secret and optionally an Agent or
Configuration being edited. OCC checks the matching create or exact update
permission and Secret operate, then reads the resource and Secret from
platform state. A missing or foreign target is rejected before provider I/O.
2. Read and use the current value
packages/occ/src/index.ts:OpenClawController.lookupChannelDirectory
Production composition selects the bundled Slack ChannelDriver only when the
API has an approved OCC_CHANNEL_DIRECTORY_PROXY_URL. Without it, an authorized
lookup returns 501 before the Secret value is read. Development selects the
Driver directly. In production the Driver tunnels requests to slack.com:443
through the configured proxy. With the managed proxy enabled, Helm points the
API at the openclaw-enterprise-slack-proxy.<namespace>.svc Service, sets that
exact host in OCC_CHANNEL_DIRECTORY_MANAGED_PROXY_HOST, and limits API egress
to the proxy Pod selector. With an external literal IPv4 proxy, Helm limits API
egress to that IP and port. The managed proxy accepts CONNECT only for Slack
hostnames on port 443, while its NetworkPolicy allows upstream egress to public
IPv4 addresses on TCP 443, excluding private and reserved ranges.
The selected SecretDriver invokes withValue and verifies backend ownership.
OCC rechecks grants and Secret backend identity after the read. It passes the
token only in process to the ChannelDriver. The bundled Slack implementation
requires a bot identity from auth.test and pages through users.list or
conversations.list. Exact-ID searches and saved IDs use users.info or conversations.info.
The response contains bounded candidates and pagination state, never the token.
An incomplete page cannot establish that a name is absent or unique.
3. Display names and save IDs
apps/controller/src/console/channels/slack.mjs:appendFields,
apps/controller/src/console/agents/slack-directory.mjs:createSlackDirectoryField
The Console presents bot-token selection before channel access and explains that
name lookup needs that token. It debounces typing and shows each candidate's name,
exact ID, and workspace. The directory result panel overlays the form, following
the Secret picker pattern in apps/controller/src/console/console.css. Closing
results on focus loss cancels pending searches without moving the clicked control;
name-status hints retain their layout space while results are open. It buffers the provider's complete returned batch and divides it into
display pages. Previous and Next reuse
those pages before Next follows the provider cursor. An empty provider page with
a continuation still offers Next. New input, dismissal, or a changed Secret
cancels the queued search and its browser request; generation checks also discard
obsolete responses. Browser cancellation does not guarantee cancellation of
provider work already started by the API.
Selecting a result or confirming pasted IDs adds removable chips to the field; search text remains separate from committed IDs. Plugin approver fields accept raw Slack user IDs when lookup is unavailable; directory-selected approvers remain workspace-qualified. Arrow keys and Enter select results, and Escape closes the list. It resolves saved IDs again when the editor opens or the selected Secret changes. A denied or failed lookup leaves manual exact-ID entry available; no directory result changes the saved Configuration until the operator saves the channel edit.
When Agent detail performs a browser-refocus access check, it keeps the mounted
view. The picker keeps its open query and results while controls are temporarily
inert; moving focus to another Console control closes the list. Read-only
directory lookups do not invalidate tab retention, so a completed search can
keep its picker when switching Agent tabs and returning.
Those results are from the last authorized lookup. A new search rechecks the
exact edit target and Secret operate grant, and denied Agent access removes the
view.
Debugging and Verification
- A denied lookup requires checking the exact edit permission and Secret
operategrant. A token, scope, rate limit, or provider error returns a safe code without the token or upstream payload. - A
501lookup in production means the API has no directory proxy configured. Enable HelmslackProxy.enabledor set the approved external proxy IP and port inapi.channelDirectoryProxyUrl, then verify that the proxy permits CONNECT toslack.com:443. - Directory conformance tests cover provider pagination and safe errors. The OCC API integration test covers both authorization checks and response projection. Browser checks cover name display and exact-ID saving.
- The Agent plugin approver browser check holds the refocus access read and verifies that an open directory search remains available without a second lookup.
- Fixture and simulated provider tests do not prove a live Slack token, bot visibility, or channel message delivery.
