This page documents the Protocol Buffer (Protobuf) definitions that dictate how agents communicate with the management infrastructure. It covers the data structures and gRPC service definitions for agent registration, lifecycle management, and real-time bidirectional command execution.
[Unknown component: div]
Architecture and Data Flow
The agent infrastructure relies heavily on a persistent bidirectional stream. This allows the server to push commands to the agent in real-time without requiring the agent to constantly poll for new tasks.
Service Definitions
The protocol defines two primary gRPC services to separate agent-facing traffic from management panel traffic.
AgentService
The AgentService is the primary endpoint for all deployed agents. It handles authentication, state updates, and the core command stream.
PanelService
The PanelService is exposed to the management interface or upstream services that need to interact with agents.
Core Data Structures
Agent Lifecycle Messages
When an agent starts up or detects system changes, it communicates its state using the AgentRequest message.
The Agent message (returned in list responses) contains all the fields of AgentRequest, plus server-assigned fields like id, agent_key, status, and last_seen.
Command Execution Messages
The command execution pipeline uses a oneof wrapper to multiplex different message types over a single gRPC stream.
BidirectionalStream
The BidirectionalStream message is a wrapper that contains either a command to be executed or the result of an execution.
type BidirectionalStream struct {
state protoimpl.MessageState
// Types that are valid to be assigned to StreamMessage:
// *BidirectionalStream_Command
// *BidirectionalStream_Result
StreamMessage isBidirectionalStream_StreamMessage `protobuf_oneof:"stream_message"`
}UtmCommand
Represents a specific instruction sent to an agent.
Shell Selection
The shell field dictates how the command is evaluated. Supported values include "cmd" and "powershell" for Windows environments, and "sh" or "bash" for Linux/macOS. If left empty, the agent falls back to its default system shell.
CommandResult
Returned by the agent after attempting to execute a UtmCommand.
Execution State Machine
Commands pass through several states from creation to completion. These states are defined by the AgentCommandStatus enum.
Command Execution Flow
The Panel Service receives a request to execute a command. It generates a unique cmd_id and constructs a UtmCommand message. The status is set to QUEUE.
The server identifies the active AgentStream for the target agent_id. It wraps the UtmCommand in a BidirectionalStream message and pushes it down the gRPC stream. Status updates to PENDING.
The agent receives the message, extracts the UtmCommand, determines the appropriate shell, and executes the payload as a subprocess.
Upon completion, the agent captures the output, constructs a CommandResult message, wraps it in a BidirectionalStream, and pushes it back up the gRPC stream.
The server receives the result, updates the database record with the output, and changes the status to EXECUTED or ERROR.
Additional Message Definitions
The AgentCommand message represents the historical record of a command, typically used when querying past executions via ListAgentCommands.
type AgentCommand struct {
CreatedAt *timestamppb.Timestamp
UpdatedAt *timestamppb.Timestamp
AgentId uint32
Command string
CommandStatus AgentCommandStatus
Result string
ExecutedBy string
CmdId string
Reason string
OriginType string
OriginId string
}Both ListAgentsResponse and ListAgentsCommandsResponse follow a standard pagination pattern, returning an array of rows and a total count integer.
type ListAgentsResponse struct {
Rows []*Agent
Total int32
}