From c987bd687f727ee5ab18681121ca8e4c024c37a0 Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 13 Apr 2026 18:26:41 +0800 Subject: [PATCH] fix(sandbox): pass explicit user to docker exec for UID-mapped containers After tai sandbox containers start as root with dynamic UID mapping, docker exec defaults to root. Add User field to ExecOptions and hardcode "sandbox" in Box.Exec/Stream to ensure commands run as the correct user. Made-with: Cursor --- sandbox/v2/box.go | 2 ++ tai/runtime/docker_core.go | 2 ++ tai/runtime/sandbox.go | 1 + 3 files changed, 5 insertions(+) diff --git a/sandbox/v2/box.go b/sandbox/v2/box.go index 9e3a58c5..fc42a355 100644 --- a/sandbox/v2/box.go +++ b/sandbox/v2/box.go @@ -93,6 +93,7 @@ func (b *Box) Exec(ctx context.Context, cmd []string, opts ...ExecOption) (*Exec result, err := res.Runtime.Exec(ctx, b.containerID, cmd, tairuntime.ExecOptions{ WorkDir: cfg.WorkDir, Env: cfg.Env, + User: "sandbox", }) if err != nil { return nil, err @@ -123,6 +124,7 @@ func (b *Box) Stream(ctx context.Context, cmd []string, opts ...ExecOption) (*Ex handle, err := res.Runtime.ExecStream(ctx, b.containerID, cmd, tairuntime.ExecOptions{ WorkDir: cfg.WorkDir, Env: cfg.Env, + User: "sandbox", }) if err != nil { return nil, err diff --git a/tai/runtime/docker_core.go b/tai/runtime/docker_core.go index 27c99363..e6601e4a 100644 --- a/tai/runtime/docker_core.go +++ b/tai/runtime/docker_core.go @@ -106,6 +106,7 @@ func (d *dockerCore) exec(ctx context.Context, id string, cmd []string, opts Exe Cmd: cmd, WorkingDir: opts.WorkDir, Env: envSlice(opts.Env), + User: opts.User, AttachStdout: true, AttachStderr: true, } @@ -143,6 +144,7 @@ func (d *dockerCore) execStream(ctx context.Context, id string, cmd []string, op Cmd: cmd, WorkingDir: opts.WorkDir, Env: envSlice(opts.Env), + User: opts.User, AttachStdin: true, AttachStdout: true, AttachStderr: true, diff --git a/tai/runtime/sandbox.go b/tai/runtime/sandbox.go index 48da51a0..00d3af0f 100644 --- a/tai/runtime/sandbox.go +++ b/tai/runtime/sandbox.go @@ -70,6 +70,7 @@ type ContainerInfo struct { type ExecOptions struct { WorkDir string Env map[string]string + User string // container exec user; empty = container default (container.Config.User) } // ExecResult holds output from an exec command.