syntax = "proto3"; // The steady-state contract between the on-host fleet agent and the // fleet-manager. ONE long-lived, host-dialed, mTLS bidi stream (health/metrics // up, desired-state down) — the design's resolved transport fork (bespoke gRPC, // not OTLP+Wazuh). See docs/fleet-management-design.md + tpm-enrolment-design.md. // // Identity is the mTLS peer cert (the host's reused TPM identity cert, fleet CA); // the manager derives the cert serial (= inventory key) from it, so AgentUp // messages carry NO self-asserted identity — a host can only ever be itself. package fleet.agent.v1; option go_package = "fleet-manager/proto;fleetpb"; service FleetAgent { // Session: the single bidirectional stream. The host opens it (dials out, no // inbound host port); the manager pushes desired-state/commands back over the // same connection. Closing/keepalive-timeout = the host's offline signal. rpc Session(stream AgentUp) returns (stream ManagerDown); } // ---- host -> manager ------------------------------------------------------ message AgentUp { oneof msg { Hello hello = 1; // first frame after connect HealthSnapshot snapshot = 2; // periodic telemetry (also written to InfluxDB) CommandResult result = 3; // outcome of a ManagerDown.Command } } // Hello — what the host is running, sent once on connect so the manager can // reconcile version drift immediately. message Hello { string image_version = 1; string rootfs_digest = 2; string kernel = 3; string kiosk_url = 4; string starship_name = 5; // advisory; manager already knows it from inventory } // HealthSnapshot — one telemetry sample. Cached as the latest value in inventory // AND written as a time-series point to InfluxDB (tagged with the authenticated // cert serial / hostnqn). message HealthSnapshot { int64 at_unix = 1; // sample time, unix seconds (0 = manager stamps now) double load_avg = 2; double cpu_pct = 3; double temp_c = 4; double mem_used_pct = 5; double tmpfs_used_pct = 6; // overlay RAM pressure string nvme_root = 7; // ok|degraded|down string auth = 8; // 802.1x/macsec: up|down string selinux = 9; // enforcing|permissive string chrony = 10; // synced|unsynced bool kiosk_active = 11; string session_uptime = 12; // KIOSK session uptime (advisory string) int32 chromium_crashes = 13; string display = 14; int64 uptime_seconds = 15; // HOST uptime (seconds since boot) — boot_time = // manager receive-time - this; drives reboot-pending } message CommandResult { string command_id = 1; bool ok = 2; string detail = 3; } // ---- manager -> host ------------------------------------------------------ message ManagerDown { oneof msg { DesiredState desired = 1; // full desired-state: sent on connect + on change Command command = 2; // imperative action } } // DesiredState — server-authoritative target the agent reconciles toward. message DesiredState { string target_version = 1; string kiosk_url = 2; int64 reboot_at_unix = 3; // 0 = no scheduled reboot bool drain = 4; } // Command — an imperative action pushed live (admin clicked a button in the SPA). message Command { string command_id = 1; Kind kind = 2; enum Kind { KIND_UNSPECIFIED = 0; REBOOT = 1; // reboot now (into desired target_version) DRAIN = 2; // stop taking work / prepare for maintenance RESYNC = 3; // re-fetch + re-apply desired-state now } }