Skip to content

test(discord): clarify and guardrail gateway proxy selection#98272

Closed
svuppala2006 wants to merge 2 commits into
openclaw:mainfrom
svuppala2006:discord-gateway-env-proxy
Closed

test(discord): clarify and guardrail gateway proxy selection#98272
svuppala2006 wants to merge 2 commits into
openclaw:mainfrom
svuppala2006:discord-gateway-env-proxy

Conversation

@svuppala2006

@svuppala2006 svuppala2006 commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

Restricted Kubernetes/OpenShift deployments need Discord Gateway and Discord REST traffic to leave the Gateway pod through the managed proxy, not through broad direct :443 egress.

This PR intentionally keeps Discord Gateway proxying explicit. Discord does not auto-inherit ambient HTTP_PROXY / HTTPS_PROXY / ALL_PROXY for Gateway sessions. Instead, deployments configure channels.discord.proxy, and OpenClaw now permits a non-loopback proxy URL only when it exactly matches the effective configured process proxy URL.

That gives operators a safe MITM proxy path for Discord without accepting arbitrary remote proxy hosts in Discord config.

Why This Change Was Made

The existing Discord proxy validator only accepted loopback proxy hosts. That blocked operator-managed proxy services such as:

{
  channels: {
    discord: {
      proxy: "http://some-proxy:8080",
    },
  },
}

The new validation allows this only when the configured proxy matches the effective process proxy endpoint, including normalized full URL, credentials, port, and lower/upper-case env precedence. Arbitrary DNS hosts and non-loopback IPs remain rejected.

User Impact

Users in restricted-egress environments can run Discord through a configured proxy without granting broad Gateway pod :443 egress.

Supported path:

{
  channels: {
    discord: {
      proxy: "http://some-proxy:8080",
    },
  },
}

Deployment environments that set HTTPS_PROXY=http://higgins-proxy:8080 can use the same endpoint explicitly in channels.discord.proxy. The Gateway does not silently opt into proxying just because proxy env vars are present.

Evidence

Automated Tests

Focused local tests passed:

node scripts/run-vitest.mjs \
  extensions/discord/src/client.proxy.test.ts \
  extensions/discord/src/send.webhook.proxy.test.ts \
  extensions/discord/src/monitor/provider.proxy.test.ts \
  extensions/discord/src/monitor/provider.rest-proxy.test.ts

git diff --check passed.

Autoreview passed after fixes:

autoreview clean: no accepted/actionable findings reported
overall: patch is correct (0.86)

Real Behavior Proof

Environment: K8s cluster, namespace sallyom-claw, Claw higgins, Discord test server Test Claws, bot Test.

Image under test:

init:init-volume=quay.io/sallyom/openclaw:latest policy=Always
init:init-config=quay.io/sallyom/openclaw:latest policy=Always
container:gateway=quay.io/sallyom/openclaw:latest policy=Always

The Discord plugin loaded from the rebuilt OpenClaw image:

{
  "source": "/app/dist/extensions/discord/index.js",
  "origin": "bundled",
  "status": "loaded"
}

Gateway logs showed both proxy paths enabled:

[discord] [default] starting provider
[discord] rest proxy enabled
[discord] gateway proxy enabled
[gateway] ready
[discord] client initialized as 1500860555307520212; awaiting gateway readiness
[discord] [default] Discord bot probe resolved @Test

Discord channel status showed the bot connected:

{
  "channels": {
    "discord": {
      "configured": true,
      "running": true,
      "lastError": null
    }
  },
  "channelAccounts": {
    "discord": [
      {
        "accountId": "default",
        "running": true,
        "connected": true,
        "tokenStatus": "available",
        "bot": {
          "username": "Test"
        }
      }
    ]
  }
}

The Gateway egress NetworkPolicy had no broad :443 rule. It allowed only the proxy pod on :8080 plus DNS:

egress:
- ports:
  - port: 8080
    protocol: TCP
  to:
  - podSelector:
      matchLabels:
        app: claw-proxy
        claw.sandbox.com/instance: higgins
- ports:
  - port: 53
    protocol: UDP
  - port: 53
    protocol: TCP
  - port: 5353
    protocol: UDP
  - port: 5353
    protocol: TCP
  to:
  - namespaceSelector: {}

A live Discord REST proof message was posted through the MITM proxy:

{
  "proxy": "http://some-proxy:8080",
  "guild": "Test",
  "textChannel": "general",
  "messageCreated": true,
  "content": "OpenClaw final Discord proxy proof 2026-07-01T23:17:06.190Z"
}

Discord status then showed inbound Gateway activity:

{
  "connected": true,
  "lastInboundAt": 1782947826282,
  "lastTransportActivityAt": 1782947816644,
  "lastError": null
}

Related

@openclaw-barnacle openclaw-barnacle Bot added channel: discord Channel integration: discord size: XS labels Jun 30, 2026
@clawsweeper

clawsweeper Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Codex review: found issues before merge. Reviewed July 1, 2026, 7:52 PM ET / 23:52 UTC.

Summary
The branch broadens Discord proxy validation so channels.discord.proxy may use a non-loopback endpoint only when it matches configured process proxy environment, and adds docs plus focused Discord proxy tests.

PR surface: Source +65, Tests +299, Docs +1. Total +365 across 6 files.

Reproducibility: yes. Source inspection shows current main keeps channels.discord.proxy loopback-only, and the PR body includes live K8s/Discord proof for the proposed explicit process-proxy path.

Review metrics: 1 noteworthy metric.

  • Discord proxy validation rule: 1 broadened. The PR changes which channels.discord.proxy endpoints can carry Discord bot traffic, which is a security-boundary decision before merge.

Stored data model
Persistent data-model change detected: serialized state: extensions/discord/src/send.webhook.proxy.test.ts. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🦞 diamond lobster
Patch quality: 🦐 gold shrimp
Result: needs maintainer review before merge.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Regenerate docs/docs_map.md so check-docs passes.
  • Get owner/security acceptance for the explicit process-proxy Discord trust boundary.

Risk before merge

  • [P1] The PR intentionally expands accepted Discord proxy endpoints beyond loopback when the endpoint matches process proxy environment, so token-bearing Gateway, REST, and webhook traffic may traverse a non-loopback proxy after merge.
  • [P1] check-docs is failing because docs/docs_map.md was not regenerated after editing Discord docs.

Maintainer options:

  1. Approve explicit process-proxy routing (recommended)
    Have owner/security accept the non-loopback process-proxy policy, then regenerate docs/docs_map.md before merge.
  2. Keep loopback-only validation
    If maintainers do not want Discord bot traffic routed through non-loopback process proxies, close or rework the branch to preserve the current boundary.
  3. Narrow the proxy policy further
    If the direction is acceptable but under-specified, add focused policy tests or docs for precedence, credentials, and bypass semantics before merge.

Next step before merge

  • [P2] The remaining blocker is maintainer/security acceptance of the Discord proxy trust boundary plus a docs-map repair, so this should not be handled as an automation-only fix lane.

Security
Needs attention: No supply-chain issue is visible, but the diff changes a Discord bot-token proxy trust boundary and needs owner/security acceptance.

Review findings

  • [P2] Regenerate the Discord docs map — docs/channels/discord.md:930
Review details

Best possible solution:

Land this after owner/security review accepts the explicit process-proxy trust boundary and the generated docs map is refreshed; keep broader proxy semantics in #60035.

Do we have a high-confidence way to reproduce the issue?

Yes. Source inspection shows current main keeps channels.discord.proxy loopback-only, and the PR body includes live K8s/Discord proof for the proposed explicit process-proxy path.

Is this the best way to solve the issue?

Unclear until owner/security review accepts the policy. The explicit proxy guardrail is narrower than ambient env fallback and matches the closed related decision, but the docs map must be regenerated before this is merge-ready.

Full review comments:

  • [P2] Regenerate the Discord docs map — docs/channels/discord.md:930
    check-docs now fails because docs/docs_map.md is out of date after this Discord docs edit. Include the generated docs map update so the docs gate can pass.
    Confidence: 0.9

Overall correctness: patch is incorrect
Overall confidence: 0.86

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 17482a402680.

Label changes

Label changes:

  • remove merge-risk: 🚨 other: Current PR review merge-risk labels are merge-risk: 🚨 security-boundary.

Label justifications:

  • P2: This is a bounded Discord restricted-egress improvement with proof, but it still needs docs repair and security-boundary review rather than urgent incident handling.
  • merge-risk: 🚨 security-boundary: The diff allows explicit non-loopback proxy endpoints for token-bearing Discord traffic when they match process proxy environment.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🦐 gold shrimp.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (logs): The PR body includes after-fix K8s Gateway logs, channel status, NetworkPolicy scope, and live Discord message output for the explicit proxy path.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix K8s Gateway logs, channel status, NetworkPolicy scope, and live Discord message output for the explicit proxy path.
Evidence reviewed

PR surface:

Source +65, Tests +299, Docs +1. Total +365 across 6 files.

View PR surface stats
Area Files Added Removed Net
Source 1 67 2 +65
Tests 4 311 12 +299
Docs 1 3 2 +1
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 6 381 16 +365

Security concerns:

  • [medium] Confirm process-proxy trust boundary — extensions/discord/src/proxy-fetch.ts:69
    The PR allows non-loopback Discord proxy URLs when they exactly match process proxy environment, which can route Gateway, REST, and webhook traffic carrying credentials through that proxy.
    Confidence: 0.86

What I checked:

Likely related people:

  • vincentkoc: Merged PR metadata and git history tie this person to the Discord proxy hardening that introduced the current loopback-only validation boundary. (role: security hardening contributor; confidence: high; commits: 50e1eb56d761, b02baf0b243a, d442faf54cad; files: extensions/discord/src/proxy-fetch.ts, extensions/discord/src/monitor/provider.proxy.test.ts)
  • steipete: Merged history shows recent Discord Gateway metadata proxy work in the same Gateway proxy area. (role: recent adjacent contributor; confidence: high; commits: 7d8a19d19a3f, 41b563e0c1ad; files: extensions/discord/src/monitor/gateway-plugin.ts, extensions/discord/src/monitor/provider.proxy.test.ts)
  • ludd50155: The original Discord Gateway proxy support came from the merged Discord gateway proxy PR before the code moved under extensions. (role: introduced behavior; confidence: medium; commits: d079681aaedf; files: src/discord/monitor/provider.ts, docs/channels/discord.md)
  • thewilloftheshadow: PR metadata for the original Discord Gateway proxy support shows this person merged the feature and authored follow-up docs/tests. (role: merger and docs/test contributor; confidence: medium; commits: 8743355b1ae8; files: docs/channels/discord.md, src/discord/monitor/provider.ts)
  • scoootscooob: Merged history moved the Discord implementation into the current extensions boundary, carrying the affected proxy code forward. (role: major refactor contributor; confidence: medium; commits: 5682ec37fada, d1c837b9c135; files: extensions/discord/src/monitor/gateway-plugin.ts, extensions/discord/src/proxy-fetch.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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 keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. labels Jun 30, 2026
@sallyom sallyom self-assigned this Jul 1, 2026
@sallyom

sallyom commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

@clawsweeper review

@clawsweeper

clawsweeper Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

…bSocket

Discord Gateway WebSocket connections now honor HTTP_PROXY/HTTPS_PROXY
environment variables as fallback before direct connection, matching the
existing pattern from Discord REST API and WhatsApp.

This enables Discord channel deployment in Kubernetes/OpenShift environments
with network policy egress restrictions, removing the need for broad :443
egress as a workaround.

- Add createEnvProxyDiscordGatewayAgent() helper (mirrors rest-fetch.ts pattern)
- Try env proxy before direct HttpsAgent in createDiscordGatewayPlugin()
- Explicit channels.discord.proxy still overrides env proxy
- Add formatErrorMessage and resolveEnvHttpProxyAgentOptions imports

Fixes #98266
@sallyom
sallyom force-pushed the discord-gateway-env-proxy branch 2 times, most recently from 9974fb8 to 605b9eb Compare July 1, 2026 20:22
@clawsweeper clawsweeper Bot added merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. and removed merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. labels Jul 1, 2026
@sallyom sallyom changed the title feat(discord): add HTTP_PROXY/HTTPS_PROXY env fallback for gateway WebSocket test(discord): clarify and guardrail gateway proxy selection Jul 1, 2026
@sallyom

sallyom commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

I'm testing that proxy can be configured with channels.discord.proxy and if so, this PR will be modified to clarify that path and prevent from adding HTTP/HTTPS_PROXY env fallback.

@sallyom
sallyom force-pushed the discord-gateway-env-proxy branch from 605b9eb to 0add562 Compare July 1, 2026 23:25
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation size: M and removed size: S labels Jul 1, 2026
@clawsweeper clawsweeper Bot added the merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. label Jul 1, 2026
@sallyom

sallyom commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

@clawsweeper review

@clawsweeper

clawsweeper Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. labels Jul 1, 2026
@svuppala2006 svuppala2006 closed this by deleting the head repository Jul 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: discord Channel integration: discord docs Improvements or additions to documentation merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. size: M status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants