e2b-dev / e2b-dev/runtime

feat(events): add requester IP and user-agent to sandbox.lifecycle.killed event

Open
#3,461 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
1.6k
Forks
438
PR merge metrics
No merged PRs in 30d

Description

Problem

When a sandbox is killed with kill_reason: "request", the sandbox.lifecycle.killed ClickHouse event carries no information about who initiated the kill — no client IP, no SDK version, no User-Agent. The only caller-identifying data present is sandbox_metadata, which is written at sandbox creation time and reflects the creator, not the killer.

This makes it impossible to answer: "which IP or SDK client sent the DELETE request that killed this sandbox?"

Root Cause

The kill event is emitted inside the orchestrator node's gRPC Delete handler (packages/orchestrator/pkg/server/sandboxes.go). By the time execution reaches there, the original HTTP request context has been lost:

HTTP DELETE /sandboxes/{id}   ← gin context has ClientIP, User-Agent, SDK headers
  → RemoveOpts{Reason: "request"}   ← no IP/UA fields exist
    → gRPC SandboxDeleteRequest{sandbox_id, kill_reason}   ← proto has no IP/UA fields
      → orchestrator Delete handler emits killed event   ← no IP/UA available

Proposed Fix

Thread the requester info through the kill path in three layers:

  1. RemoveOpts — add RequesterIP string and UserAgent string fields
  2. SandboxDeleteRequest proto — add optional string requester_ip = 3 and optional string requester_user_agent = 4
  3. Orchestrator Delete handler — write both fields into eventData before emitting the killed event

Call site in handlers/sandbox_kill.go:

err = a.orchestrator.RemoveSandbox(ctx, teamID, sandboxID, sandbox.RemoveOpts{
    Action:      sandbox.StateActionKill,
    Reason:      sandbox.KillReasonRequest,
    RequesterIP: c.ClientIP(),
    UserAgent:   c.Request.UserAgent(),
})

Resulting ClickHouse event_data:

{
  "kill_reason": "request",
  "requester_ip": "1.2.3.4",
  "requester_user_agent": "e2b-js-sdk/1.9.0",
  "sandbox_metadata": { ... }
}

Files Affected

  • packages/api/internal/sandbox/sandboxtypes/states.go
  • packages/api/internal/handlers/sandbox_kill.go
  • packages/api/internal/orchestrator/delete_instance.go
  • packages/orchestrator/orchestrator.proto + regenerate packages/shared/pkg/grpc/orchestrator/
  • packages/orchestrator/pkg/server/sandboxes.go

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 at packages/api/internal/handlers/sandbox_kill.go and trace RemoveSandbox through packages/api/internal/orchestrator/delete_instance.go and packages/orchestrator/pkg/server/sandboxes.go. Update the listed RemoveOpts and orchestrator.proto paths, regenerate packages/shared/pkg/grpc/orchestrator/, and verify the killed event includes requester_ip and requester_user_agent for request-triggered kills.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
api, backend, distributed-systems
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
70/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.