Skip to content

Add implementation of PicoD#65

Merged
volcano-sh-bot merged 15 commits intovolcano-sh:mainfrom
acsoto:picod
Dec 12, 2025
Merged

Add implementation of PicoD#65
volcano-sh-bot merged 15 commits intovolcano-sh:mainfrom
acsoto:picod

Conversation

@acsoto
Copy link
Copy Markdown
Member

@acsoto acsoto commented Dec 8, 2025

This pull request introduces a new standalone PicoD server with REST endpoints for secure file operations and command execution. It adds a main entry point, implements handlers for file upload, download, and listing, and enables command execution with timeout and environment support. The implementation includes workspace scoping for security and updates dependencies.

New PicoD server implementation:

  • Added cmd/picod/main.go as the main entry point for the PicoD server, supporting configuration via flags and secure workspace scoping.

File operations REST API:

  • Implemented UploadFileHandler, DownloadFileHandler, and ListFilesHandler in pkg/picod/files.go for file upload (multipart and base64 JSON), download, and directory listing, with robust path sanitization and permission handling to prevent directory traversal.

Command execution REST API:

  • Added ExecuteHandler in pkg/picod/execute.go to execute shell commands with configurable timeout, working directory, and environment variables, returning detailed execution results.

Workspace security:

  • Introduced workspace management functions and path sanitization in pkg/picod/files.go to restrict all file operations to a configured root directory, preventing unauthorized access outside the workspace.

Dependency updates:

  • Updated go.mod to add github.com/golang-jwt/jwt/v5 and k8s.io/utils, and removed duplicate indirect dependency for k8s.io/utils. [1] [2] [3]

This commit introduces PicoD, a lightweight agent daemon designed for
remote execution and file management within the agentcube runtime environment.

Key features included:
- Secure initialization and authentication using RSA keys and JWT.
- Remote command execution with timeout and environment support.
- File system operations: upload, download, and listing.
- Workspace isolation for file access safety.
- Initial end-to-end tests.

Signed-off-by: Zhou Zihang <z@mcac.cc>
Copilot AI review requested due to automatic review settings December 8, 2025 12:54
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @acsoto, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request establishes the foundational implementation for a new PicoD server, designed to offer secure remote file management and command execution capabilities. The primary goal is to provide a tightly controlled and authenticated interface for interacting with a remote system's filesystem and shell, ensuring operations are confined to a secure workspace and validated through cryptographic means.

Highlights

  • New PicoD Server Implementation: Introduced a standalone PicoD server with a main entry point in cmd/picod/main.go and core server logic in pkg/picod/server.go, configurable via command-line flags for port, bootstrap key, and workspace.
  • Secure Authentication Mechanism: Implemented a robust RSA public key-based authentication system in pkg/picod/auth.go utilizing JWTs, featuring a two-stage initialization process with a bootstrap key for initial server setup and a session key for all subsequent authenticated requests.
  • REST API for File Operations: Added secure REST endpoints in pkg/picod/files.go for uploading (supporting both multipart form data and base64 JSON content), downloading, and listing files, incorporating path sanitization and workspace scoping to prevent directory traversal.
  • REST API for Command Execution: Provided a REST endpoint in pkg/picod/execute.go to execute shell commands, offering configurable timeouts, working directories, and environment variables, with detailed execution results.
  • Enhanced Workspace Security: Ensured all file operations are strictly confined to a designated workspace directory, preventing unauthorized access outside the defined boundaries and mitigating security risks like directory traversal.
  • Dependency Updates: Updated go.mod and go.sum to include github.com/golang-jwt/jwt/v5 for JWT handling and k8s.io/utils as a direct dependency, while also resolving a duplicate indirect dependency.
  • Comprehensive End-to-End Testing: Included extensive end-to-end tests in pkg/picod/picod_test.go to validate the server's health checks, initialization, command execution, file operations, and critical security features.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new standalone PicoD server, which is a significant addition. The implementation provides REST endpoints for file operations and command execution, secured by JWT authentication. The code is well-structured and includes a comprehensive set of end-to-end tests.

My review has identified several issues, with a focus on security and correctness. Most critically, the command execution endpoint is vulnerable to command injection and path traversal, which could allow an authenticated user to gain full control over the server. I have also found a bug in the command timeout logic and a minor race condition in file uploads. My comments provide specific suggestions to address these vulnerabilities and bugs to improve the overall security and robustness of the PicoD server.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a new PicoD server implementation that provides a REST API for secure remote command execution and file operations. The server uses JWT-based authentication with RSA public key cryptography, implementing a bootstrap-then-session key model for initialization and subsequent operations. All file operations are scoped to a configured workspace directory for security.

Key changes:

  • Added standalone PicoD server with JWT authentication and workspace-scoped file operations
  • Implemented REST endpoints for command execution, file upload/download, and directory listing
  • Added comprehensive end-to-end test coverage with security validation scenarios

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 17 comments.

Show a summary per file
File Description
cmd/picod/main.go Main entry point for PicoD server with CLI flag parsing for port, bootstrap key, and workspace configuration
pkg/picod/server.go Server initialization, routing setup, and health check endpoint
pkg/picod/auth.go JWT-based authentication with RSA keys, implementing bootstrap initialization and session authentication middleware
pkg/picod/execute.go Command execution handler with timeout support and environment variable configuration
pkg/picod/files.go File upload (multipart and base64), download, and listing handlers with path sanitization for workspace security
pkg/picod/picod_test.go Comprehensive end-to-end tests covering authentication flow, file operations, command execution, and security scenarios
go.mod Added golang-jwt/jwt/v5 dependency and promoted k8s.io/utils from indirect to direct dependency
go.sum Updated checksums for new jwt dependency

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Signed-off-by: Zhou Zihang <z@mcac.cc>
@hzxuzhonghu
Copy link
Copy Markdown
Member

/ok-to-test


// Verify body hash if present in claims
// We mandate body_sha256 for requests with body to ensure integrity
if claimHash, ok := claims["body_sha256"].(string); ok {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we really need to verify the body? This means we need to sign different token each request

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

please explain

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

removed

Signed-off-by: Zhou Zihang <z@mcac.cc>
…iddleware

Signed-off-by: Zhou Zihang <z@mcac.cc>
…ror handling

Signed-off-by: Zhou Zihang <z@mcac.cc>
Copilot AI review requested due to automatic review settings December 10, 2025 09:15
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 9 changed files in this pull request and generated 21 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…and update related tests

Signed-off-by: Zhou Zihang <z@mcac.cc>
Signed-off-by: Zhou Zihang <z@mcac.cc>
… safety

Signed-off-by: Zhou Zihang <z@mcac.cc>
…eliminating the race window

Signed-off-by: Zhou Zihang <z@mcac.cc>
…unctions

Signed-off-by: Zhou Zihang <z@mcac.cc>
Copilot AI review requested due to automatic review settings December 11, 2025 14:06
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 9 changed files in this pull request and generated 16 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Signed-off-by: Zhou Zihang <z@mcac.cc>
Signed-off-by: Zhou Zihang <z@mcac.cc>
@acsoto
Copy link
Copy Markdown
Member Author

acsoto commented Dec 12, 2025

I've addressed all comments. Please take another look.
@hzxuzhonghu @YaoZengzeng

Signed-off-by: Zhou Zihang <z@mcac.cc>
Copilot AI review requested due to automatic review settings December 12, 2025 07:04
return am.savePublicKeyLocked(publicKeyStr)
}

func (am *AuthManager) savePublicKeyLocked(publicKeyStr string) error {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

can you explain why do need to save it into a file?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

To save the publick key and to check whether the sandbox is registered.


// Verify body hash if present in claims
// We mandate body_sha256 for requests with body to ensure integrity
if claimHash, ok := claims["body_sha256"].(string); ok {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

please explain

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 9 changed files in this pull request and generated 21 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +272 to +280
if !am.IsInitialized() {
c.JSON(http.StatusForbidden, gin.H{
"error": "Server not initialized",
"code": http.StatusForbidden,
"detail": fmt.Sprintf("Please initialize this Picod instance first via /init. Request path is %s", c.Request.URL.Path),
})
c.Abort()
return
}
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

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

The initialized flag is checked without holding the mutex in the AuthMiddleware. While am.IsInitialized() properly uses RLock, the subsequent read of am.publicKey at lines 315-317 acquires the lock again. Between these two operations, the state could theoretically change. Although in practice initialization happens once and the publicKey is never modified after being set, this creates a subtle race condition window. Consider holding a single read lock for the entire check-and-use operation, or document why this is safe due to write-once semantics.

Copilot uses AI. Check for mistakes.
Comment on lines +107 to +113
defer dst.Close()

// Copy content
if _, err := io.Copy(dst, src); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save file content", "code": http.StatusInternalServerError})
return
}
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

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

File handle may be writable as a result of data flow from a call to OpenFile and closing it may result in data loss upon failure, which is not handled explicitly.

Suggested change
defer dst.Close()
// Copy content
if _, err := io.Copy(dst, src); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save file content", "code": http.StatusInternalServerError})
return
}
// Defer is not used so we can check for errors on close
// Copy content
if _, err := io.Copy(dst, src); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save file content", "code": http.StatusInternalServerError})
dst.Close() // attempt to close, ignore error since copy already failed
return
}
// Check for errors on close
if err := dst.Close(); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to finalize file write", "code": http.StatusInternalServerError})
return
}

Copilot uses AI. Check for mistakes.
Signed-off-by: Zhou Zihang <z@mcac.cc>
@volcano-sh-bot
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

Approval requirements bypassed by manually added approval.

This pull-request has been approved by: hzxuzhonghu

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@volcano-sh-bot volcano-sh-bot merged commit bc0d6d2 into volcano-sh:main Dec 12, 2025
5 checks passed
@acsoto acsoto deleted the picod branch December 14, 2025 02:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants