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.

Assessment

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

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.

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
Dominant language
Go
Stars
1.6k
Forks
438
PR merge metrics
No merged PRs in 30d

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.

More from e2b-dev/runtime

All issues in e2b-dev/runtime

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.