Bug: channels add <messaging> does not apply the channel's network policy preset; messaging bridge has no egress after rebuild
Summary
Running nemoclaw <sandbox> channels add <channel> (e.g. telegram, slack, discord) registers the bridge with the OpenShell gateway and triggers a rebuild, but never applies the channel's
egress policy preset. After the rebuild the bridge boots with no allow-list entry for its upstream API hosts, so all outbound traffic to api.telegram.org / slack.com / discord.com is
blocked by the SSRF engine and the channel silently fails to deliver messages.
Reproduction
nemoclaw onboard <sandbox> without selecting a messaging channel.
- After onboarding completes, run e.g.
nemoclaw <sandbox> channels add telegram.
- Provide the bot token when prompted; accept the rebuild prompt.
- After the sandbox comes back up, send a DM to the bot.
Expected
The bridge can reach api.telegram.org:443 and the bot responds.
Actual
Outbound requests from the bridge are denied with policy:- engine:ssrf. nemoclaw <sandbox> policy list shows the telegram preset is not in the applied list. Running nemoclaw <sandbox> policy-add telegram followed by another rebuild fixes it.
Root cause
addSandboxChannel in src/lib/actions/sandbox/policy-channel.ts:398-456 (current main) does the following:
- Acquires tokens
persistChannelTokens(acquired) (line 447)
applyChannelAddToGatewayAndRegistry(...) (line 453)
promptAndRebuild(...) (line 455)
It never calls policies.applyPreset(sandboxName, channelArg). Because the channel's preset is never applied, it is also not captured in the rebuild's backup manifest, so Step 5.5: Restore policy presets in src/lib/actions/sandbox/rebuild.ts:657-690 has nothing to restore for that channel. The bridge boots without egress for its upstream.
The nemoclaw onboard path does not have this gap — it applies channel presets implicitly via getSuggestedPolicyPresets. The bug is specific to channels add invoked after onboarding.
Affected channels
All channels in KNOWN_CHANNELS (src/lib/sandbox/channels.ts:32) that ship a matching preset under nemoclaw-blueprint/policies/presets/:
telegram → telegram.yaml
slack → slack.yaml
discord → discord.yaml
wechat → wechat.yaml (separately fixed on the wechat-integration branch)
Workaround
After channels add <channel> and the rebuild, manually run:
nemoclaw <sandbox> policy-add <channel>
…and accept another rebuild.
Suggested fix
After applyChannelAddToGatewayAndRegistry and before promptAndRebuild, look up the channel's matching preset and apply it idempotently so the rebuild's backup manifest captures it. A
working implementation already exists on branch u/sdang/wechat-integration at src/lib/actions/sandbox/policy-channel.ts:606-622 (commit 2cbbd76); it is generic over channel name and would
close this for all three channels. That branch currently scopes the change to the wechat integration PR — this issue tracks porting the generic part to main so telegram/slack/discord get the
same fix.
Acceptance
channels add telegram on a fresh post-onboard sandbox results in telegram appearing in policy list after the rebuild, with no manual policy-add step.
- Same for
slack and discord.
- A regression test under
test/ exercises the post-onboard channels add → rebuild flow and asserts the preset is applied.
Bug:
channels add <messaging>does not apply the channel's network policy preset; messaging bridge has no egress after rebuildSummary
Running
nemoclaw <sandbox> channels add <channel>(e.g.telegram,slack,discord) registers the bridge with the OpenShell gateway and triggers a rebuild, but never applies the channel'segress policy preset. After the rebuild the bridge boots with no allow-list entry for its upstream API hosts, so all outbound traffic to
api.telegram.org/slack.com/discord.comisblocked by the SSRF engine and the channel silently fails to deliver messages.
Reproduction
nemoclaw onboard <sandbox>without selecting a messaging channel.nemoclaw <sandbox> channels add telegram.Expected
The bridge can reach
api.telegram.org:443and the bot responds.Actual
Outbound requests from the bridge are denied with
policy:- engine:ssrf.nemoclaw <sandbox> policy listshows thetelegrampreset is not in the applied list. Runningnemoclaw <sandbox> policy-add telegramfollowed by another rebuild fixes it.Root cause
addSandboxChannelinsrc/lib/actions/sandbox/policy-channel.ts:398-456(currentmain) does the following:persistChannelTokens(acquired)(line 447)applyChannelAddToGatewayAndRegistry(...)(line 453)promptAndRebuild(...)(line 455)It never calls
policies.applyPreset(sandboxName, channelArg). Because the channel's preset is never applied, it is also not captured in the rebuild's backup manifest, soStep 5.5: Restore policy presetsinsrc/lib/actions/sandbox/rebuild.ts:657-690has nothing to restore for that channel. The bridge boots without egress for its upstream.The
nemoclaw onboardpath does not have this gap — it applies channel presets implicitly viagetSuggestedPolicyPresets. The bug is specific tochannels addinvoked after onboarding.Affected channels
All channels in
KNOWN_CHANNELS(src/lib/sandbox/channels.ts:32) that ship a matching preset undernemoclaw-blueprint/policies/presets/:telegram→telegram.yamlslack→slack.yamldiscord→discord.yamlwechat→wechat.yaml(separately fixed on the wechat-integration branch)Workaround
After
channels add <channel>and the rebuild, manually run:…and accept another rebuild.
Suggested fix
After
applyChannelAddToGatewayAndRegistryand beforepromptAndRebuild, look up the channel's matching preset and apply it idempotently so the rebuild's backup manifest captures it. Aworking implementation already exists on branch
u/sdang/wechat-integrationatsrc/lib/actions/sandbox/policy-channel.ts:606-622(commit2cbbd76); it is generic over channel name and wouldclose this for all three channels. That branch currently scopes the change to the wechat integration PR — this issue tracks porting the generic part to
mainso telegram/slack/discord get thesame fix.
Acceptance
channels add telegramon a fresh post-onboard sandbox results intelegramappearing inpolicy listafter the rebuild, with no manualpolicy-addstep.slackanddiscord.test/exercises the post-onboardchannels add → rebuildflow and asserts the preset is applied.