Skip to content

FEATURE: allow runCommand to specify username or uid#181

Open
Pangjiping wants to merge 11 commits intoalibaba:mainfrom
Pangjiping:feat/run_command/uid
Open

FEATURE: allow runCommand to specify username or uid#181
Pangjiping wants to merge 11 commits intoalibaba:mainfrom
Pangjiping:feat/run_command/uid

Conversation

@Pangjiping
Copy link
Collaborator

@Pangjiping Pangjiping commented Feb 5, 2026

Summary

  • Add user field to /command run payload and status response in specs/execd-api.yaml, using oneOf to accept either a POSIX username string or numeric UID; defaults to the execd process user when omitted.

Testing

  • Not run (explain why)
  • Unit tests
  • Integration tests
  • e2e / manual verification

Breaking Changes

  • None
  • Yes (describe impact and migration path)

Checklist

@jwx0925
Copy link
Collaborator

jwx0925 commented Feb 5, 2026

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3cdade0b08

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@Pangjiping Pangjiping assigned hittyt and ninan-nn and unassigned hittyt and ninan-nn Feb 5, 2026
@Pangjiping Pangjiping requested a review from ninan-nn February 5, 2026 08:23
@Pangjiping
Copy link
Collaborator Author

image
Copy link
Collaborator

@hittyt hittyt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change summary: Added support for specifying a target username or uid in the runCommand API to execute commands as a different user within the sandbox.

This is a valuable addition to the sandbox capabilities. The implementation correctly integrates user switching into the command execution flow. However, there are a few important improvements needed for completeness and consistency, particularly regarding supplementary groups.

File: components/execd/pkg/runtime/command.go

L55: [LOW] Redundant and potentially inconsistent logging.

The initial logging of request.User is redundant because more detailed information (the resolved UID/GID) is logged later. Furthermore, if both UID and Username were present, it only logs one of them, which could be misleading.

Suggested change:

-	if request.User != nil {
-		if request.User.UID != nil {
-			log.Info("run_command request.User.UID=%d", *request.User.UID)
-		} else if request.User.Username != nil {
-			log.Info("run_command request.User.Username=%s", *request.User.Username)
-		}
-	}

L216: [LOW] Inconsistent logging in runBackgroundCommand.

The "setting Credential" log is present in runCommand but missing in runBackgroundCommand. Adding it here would improve observability.

File: components/execd/pkg/runtime/user_unix.go

L55: [HIGH] Missing supplementary groups in syscall.Credential.

The current implementation only sets Uid and Gid in the syscall.Credential. This causes the spawned process to lose all supplementary group memberships of the target user, which often leads to unexpected permission issues (e.g., unable to access devices or sockets that require specific group membership). It is critical to initialize the full group list for the target user.

Suggested change:

	uid, err := strconv.ParseUint(usr.Uid, 10, 32)
	if err != nil {
		return nil, nil, fmt.Errorf("parse uid %s: %w", usr.Uid, err)
	}
	gid, err := strconv.ParseUint(usr.Gid, 10, 32)
	if err != nil {
		return nil, nil, fmt.Errorf("parse gid %s: %w", usr.Gid, err)
	}

	gids, err := usr.GroupIds()
	if err != nil {
		return nil, nil, fmt.Errorf("lookup group ids for user %s: %w", usr.Username, err)
	}
	groups := make([]uint32, 0, len(gids))
	for _, g := range gids {
		groupUint, parseErr := strconv.ParseUint(g, 10, 32)
		if parseErr != nil {
			continue
		}
		groups = append(groups, uint32(groupUint))
	}

	cred := &syscall.Credential{
		Uid:    uint32(uid),
		Gid:    uint32(gid),
		Groups: groups,
	}

File: components/execd/pkg/web/model/command.go

L56: [LOW] Minor redundancy in validation logic.

The Validate() method calls r.User.validate() even if r.User is nil. While the method handles nil receivers safely, a clearer structure would be to check if r.User is nil before performing user-specific validations.

Copy link
Collaborator

@hittyt hittyt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added support for user switching in execd, but needs refinement on supplementary groups, error handling, and consistency.

Copy link
Collaborator

@hittyt hittyt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/execd feature New feature or request

4 participants