3 Commits
Author SHA1 Message Date
Duc Nguyenandntduc bb7712a9ff fix(collaboration): harden delegated task isolation (#1486)
* feat(collaboration): isolate delegated artifacts and child runs

Isolate delegated inputs and outputs behind secure artifact exchange lifecycles. Scope Agent Link tasks by tenant and root agent, and enforce delegation spawn-tree boundaries. Add process-wide child-run admission and preserve logical media paths across native, MCP, and sandbox execution.

* fix(collaboration): harden delegated task isolation

Enforce tenant and root-agent task scope across migrations and stores. Add exactly-once async completion delivery, delegated sandbox boundaries, and confined artifact and media recovery across runtime surfaces.

* fix(collaboration): recover interrupted async tasks

* fix(collaboration): normalize persisted child-run status

---------

Co-authored-by: ntduc <ntduc@cpp.ai.vn>
2026-07-30 14:17:40 +07:00
ad893908a5 fix(telegram): propagate local_key for forum topic routing in team notifications (#800)
* fix(telegram): propagate local_key for forum topic routing in team notifications

Team task status messages (dispatched, completed, progress) were always
delivered to the General topic in Telegram forum groups because the
notification pipeline had no access to the originating topic's local_key.

Root cause: wireTeamProgressNotifySubscriber in gateway_events.go published
OutboundMessage with no Metadata, so the Telegram adapter had no
message_thread_id to route to the correct forum topic.

Fix has two parts:

1. Team notify path (root cause):
   - Add LocalKey field to TeamTaskEventPayload (protocol)
   - Extract local_key from tool context in WithContextInfo()
   - Add LocalKey to NotifyRoutingMeta
   - Pass LocalKey through to OutboundMessage Metadata in both
     leader mode (InboundMessage) and direct mode (OutboundMessage)

2. MCP bridge context (supporting):
   - Propagate local_key and session_key through bridge HTTP headers
   - Add X-Local-Key and X-Session-Key to BridgeContext
   - Extract and inject into tool context in gateway middleware
   - Include in HMAC signature for integrity

Closes #798

* fix(telegram): pass LocalKey from task metadata in all dispatch/fail broadcast sites

The initial fix added LocalKey to the event payload and WithContextInfo(),
but 4 broadcast call sites use individual With* options instead of
WithContextInfo — so LocalKey was never populated for:

- fallback_dispatch (team_tasks_create.go)
- dispatch_unblocked (team_tool_dispatch.go)
- post_turn dispatch (team_tool_validation.go)
- blocker/fail (team_tasks_blocker.go)

Add WithLocalKey() option function and extract TaskMetaLocalKey from task
metadata at each site, matching the existing TaskMetaPeerKind pattern.

* test(mcp): add HMAC verification tests for extra params (localKey, sessionKey)

- Add tests for SignBridgeContext/VerifyBridgeContext with extra params
- Test backward compat fallback for pre-localKey sessions
- Test that param order matters in signature
- Add clarifying comment for routing context injection security model

---------

Co-authored-by: Jens Henke <jens@henke.dk>
Co-authored-by: viettranx <viettranx@gmail.com>
2026-04-12 19:03:47 +07:00
viettranx d9087fd0b7 fix(security): harden MCP bridge tenant_id propagation
- Guard uuid.Nil before converting to string in loop.go to avoid
  sending zero UUID as X-Tenant-ID header when no tenant is set
- Return (ok, tenantVerified) from VerifyBridgeContext so callers
  only inject tenant_id when HMAC actually covers it (level 1)
- Add unit tests for SignBridgeContext and VerifyBridgeContext
  including security test for tenant injection via HMAC fallback
2026-03-27 23:23:14 +07:00