--- id: grpc-api title: gRPC API sidebar_label: gRPC API --- The agent-facing API, on port `9090`, over TLS. Agents dial **out** to it; nothing dials an agent. ## Service ```protobuf service Vantage { rpc Register(RegisterRequest) returns (RegisterResponse); rpc SyncKeys(SyncRequest) returns (SyncResponse); rpc UploadGeneratedKey(UploadKeyRequest) returns (UploadKeyResponse); rpc ReportUpdates(ReportUpdatesRequest) returns (ReportUpdatesResponse); rpc ReportInventory(InventoryReport) returns (InventoryReportResponse); rpc SyncMonitors(SyncMonitorsRequest) returns (SyncMonitorsResponse); rpc ReportChecks(ReportChecksRequest) returns (ReportChecksResponse); rpc CommandStream(stream AgentMessage) returns (stream ServerCommand); } ``` The full message definitions live in `proto/vantage/v1/vantage.proto`. ## Authentication `Register` presents the single-use, one-hour pre-registration token and receives a permanent agent token. Every other call presents that agent token. The control plane stores only the SHA-256 of the agent token. The plaintext exists in the agent's `0600` config file and nowhere else, so a token cannot be read back out of the control plane. ## Unary calls | RPC | Direction | Frequency | | --- | --- | --- | | `Register` | once, at enrolment | once | | `SyncKeys` | agent asks for desired key state | every 30s (`poll_interval`) | | `UploadGeneratedKey` | agent returns a keypair it generated | on demand | | `ReportUpdates` | pending OS package updates | hourly | | `ReportInventory` | CPU, memory, disk, kernel | metrics 30s, static 15 min | | `SyncMonitors` | agent asks which checks it should run | periodically | | `ReportChecks` | agent returns check results | after each check cycle | `SyncKeys` doubles as the heartbeat. A server that stops calling it is marked `offline` by a sweep that runs every two minutes. ## The command stream `CommandStream` is the only streaming RPC and the only push path. ```mermaid sequenceDiagram participant A as Agent participant S as Server A->>S: AgentReady (authenticate) S-->>A: ServerCommand (RunStepCmd) A-->>S: StepOutputChunk (repeated) A-->>S: StepResult S-->>A: ServerCommand (CleanupWorkspaceCmd) A-->>S: CommandResult ``` The agent authenticates once with `AgentReady`, then the server pushes commands and the agent replies with `CommandResult`, `StepResult` or `StepOutputChunk`. ### Commands | Command | Effect | | --- | --- | | `GenerateKeyCmd` | Generate an SSH keypair on the machine | | `DeleteKeyCmd` | Remove a generated key by label | | `UpdateAgentCmd` | Download and replace the agent binary with a target version | | `ApplyUpdatesCmd` | Apply pending OS package updates | | `RunStepCmd` | Execute one workflow step | | `CleanupWorkspaceCmd` | Recursively remove the run's working directory | ## Why poll for keys and push for commands A 30-second delay on a key change is fine, and polling needs no reconnection logic to survive a dropped link. Clicking **Run** on a workflow and waiting up to 30 seconds is not fine. Hence one of each. ## Network requirements Every managed machine needs outbound TCP to `GRPC_HOST`. Nothing needs to reach the machine. Watch for middleboxes that permit the short `Register` call but drop the long-lived command stream — that failure looks like a server that registers and then goes offline.