nextlevelbuilder / nextlevelbuilder/goclaw

MCP bridge drops SenderID → cron / write_file unusable in Telegram groups (Claude CLI provider)

Open
#1,126 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

agent:github-maintain area:channels area:mcp area:security bug maintain:triaged P1-high status:needs-triage
Dominant language
Go
Stars
3.6k
Forks
1.1k
Avg merge
3d 5h
Merged PRs (30d)
24

Description

Symptom

In a Telegram group, every mcp__goclaw-bridge__* tool call from a Claude-CLI-backed agent is rejected with:

permission denied: only users with cron or file_writer permission can manage cron jobs in group chats
permission denied: system context cannot write files in group chats. If this is a legitimate user action, ensure the acting sender is preserved through the tool chain

…even when the calling user has all the right grants:

  • File Writer · All Groups · allow
  • Config Permissions: * (Global), cron · All Groups, context_files · All Groups, heartbeat · All Groups · allow

Repro

  1. Agent uses provider claude_cli.
  2. From a Telegram group, ask the agent to add/edit a cron job, or to write a file.
  3. Tool call returns the error above. DB grants are never consulted.

Root cause

The MCP bridge does not propagate the acting sender:

  • internal/providers/claude_cli_mcp.go:86-95BridgeContext carries AgentID, UserID, Channel, ChatID, PeerKind, Workspace, TenantID, LocalKeyno SenderID.
  • internal/providers/claude_cli_mcp.go:128-164writeMCPConfigInternal writes X-Agent-ID, X-User-ID, … — no X-Sender-ID header, no sender in the HMAC payload (SignBridgeContext at line 267).
  • internal/gateway/server.go:215-303bridgeContextMiddleware reads the headers above and calls store.WithAgentID / store.WithUserID / store.WithTenantIDnever store.WithSenderID.

Result: tools land with SenderID=="" and trip the empty-sender deny at internal/store/config_permission_store.go:84 (CheckFileWriterPermission) and :142 (CheckCronPermission) before any DB grant lookup runs.

Native providers (Anthropic, OpenAI-compat, DashScope, Codex, ACP) are unaffected: they invoke tools in-process with the agent-loop ctx where store.WithSenderID(ctx, req.SenderID) is already set (internal/agent/loop_context.go:63-64).

Expected

SenderID should flow through the bridge so per-user grants (file_writer, cron) are evaluated against the real Telegram sender.

Suggested fix (~4 files)

  1. Add SenderID to BridgeContext; emit X-Sender-ID header; include sender in SignBridgeContext payload.
  2. In bridgeContextMiddleware, read X-Sender-ID, verify HMAC, call store.WithSenderID(ctx, …).
  3. Extend VerifyBridgeContext with a sender-aware level; keep existing levels as fallback for in-flight sessions.
  4. At the bridge-context construction site (claude_cli_session.go:171 bridgeContextFromOpts), populate from store.SenderIDFromContext(ctx) / the corresponding option.

Workaround

Switch the agent's provider away from claude_cli (e.g. Anthropic native with the same Claude model). Tool calls then run in-process with sender preserved, and the existing grants work.

Related

CronJob row also has no SenderID field (internal/store/cron_store.go:20-38) and cmd/gateway_cron.go:98-111 re-fires jobs with an empty RunRequest.SenderID — same gate trips on every scheduled execution. Likely a separate follow-up.


Drafted by Claude (Claude Code) after end-to-end verification against the codebase at dev branch. File:line citations are from this commit. Reproduced and traced before filing.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with internal/providers/claude_cli_mcp.go and bridgeContextFromOpts in internal/providers/claude_cli_session.go, then trace bridgeContextMiddleware in internal/gateway/server.go and the permission checks in internal/store/config_permission_store.go. Verify the existing HMAC context tests or add focused coverage for a Telegram sender; done means SenderID reaches the bridge and cron and file-writer grants are evaluated for that sender.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
api, backend, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.