From 81182ee8cf7b1e456fd193754f1351e2863cf444 Mon Sep 17 00:00:00 2001 From: domrichardson <100129001+domrichardson@users.noreply.github.com> Date: Mon, 15 Jun 2026 13:58:45 +0100 Subject: [PATCH 01/21] first commit --- proto/keymanager/v1/keymanager.proto | 43 ++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 proto/keymanager/v1/keymanager.proto diff --git a/proto/keymanager/v1/keymanager.proto b/proto/keymanager/v1/keymanager.proto new file mode 100644 index 0000000..3ac5ad3 --- /dev/null +++ b/proto/keymanager/v1/keymanager.proto @@ -0,0 +1,43 @@ +syntax = "proto3"; + +package keymanager.v1; + +option go_package = "github.com/mrhid6/keymanager/server/internal/grpc/pb"; + +service KeyManager { + rpc Register(RegisterRequest) returns (RegisterResponse); + rpc SyncKeys(SyncRequest) returns (SyncResponse); + rpc UploadGeneratedKey(UploadKeyRequest) returns (UploadKeyResponse); +} + +message RegisterRequest { + string server_id = 1; + string pre_reg_token = 2; + string hostname = 3; + string ip_address = 4; + string os_info = 5; +} + +message RegisterResponse { + string agent_token = 1; +} + +message SyncRequest { + string server_id = 1; + string agent_token = 2; +} + +message SyncResponse { + repeated string public_keys = 1; +} + +message UploadKeyRequest { + string server_id = 1; + string agent_token = 2; + string public_key = 3; + string label = 4; +} + +message UploadKeyResponse { + string key_id = 1; +} From baf99e79b6dfeabb0c3b3e332831699d3b4a3077 Mon Sep 17 00:00:00 2001 From: domrichardson <100129001+domrichardson@users.noreply.github.com> Date: Tue, 16 Jun 2026 09:37:32 +0100 Subject: [PATCH 02/21] updates --- proto/keymanager/v1/keymanager.proto | 38 +++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/proto/keymanager/v1/keymanager.proto b/proto/keymanager/v1/keymanager.proto index 3ac5ad3..296c802 100644 --- a/proto/keymanager/v1/keymanager.proto +++ b/proto/keymanager/v1/keymanager.proto @@ -5,9 +5,11 @@ package keymanager.v1; option go_package = "github.com/mrhid6/keymanager/server/internal/grpc/pb"; service KeyManager { - rpc Register(RegisterRequest) returns (RegisterResponse); - rpc SyncKeys(SyncRequest) returns (SyncResponse); - rpc UploadGeneratedKey(UploadKeyRequest) returns (UploadKeyResponse); + rpc Register(RegisterRequest) returns (RegisterResponse); + rpc SyncKeys(SyncRequest) returns (SyncResponse); + rpc UploadGeneratedKey(UploadKeyRequest) returns (UploadKeyResponse); + // Bidirectional stream: agent sends auth once, server pushes commands. + rpc CommandStream(stream AgentMessage) returns (stream ServerCommand); } message RegisterRequest { @@ -41,3 +43,33 @@ message UploadKeyRequest { message UploadKeyResponse { string key_id = 1; } + +// CommandStream messages + +message AgentMessage { + string server_id = 1; + string agent_token = 2; + oneof payload { + AgentReady ready = 3; + CommandResult result = 4; + } +} + +message AgentReady {} + +message CommandResult { + string command_id = 1; + bool success = 2; + string message = 3; +} + +message ServerCommand { + string command_id = 1; + oneof command { + GenerateKeyCmd generate_key = 2; + } +} + +message GenerateKeyCmd { + string label = 1; +} From d6f4a807d032b4deb6bad140edf2c68ab242ed07 Mon Sep 17 00:00:00 2001 From: domrichardson <100129001+domrichardson@users.noreply.github.com> Date: Tue, 16 Jun 2026 10:28:46 +0100 Subject: [PATCH 03/21] updates --- proto/keymanager/v1/keymanager.proto | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/proto/keymanager/v1/keymanager.proto b/proto/keymanager/v1/keymanager.proto index 296c802..754b93d 100644 --- a/proto/keymanager/v1/keymanager.proto +++ b/proto/keymanager/v1/keymanager.proto @@ -71,5 +71,9 @@ message ServerCommand { } message GenerateKeyCmd { - string label = 1; + string label = 1; + string key_type = 2; // ed25519 | rsa | ecdsa (default: ed25519) + int32 key_size = 3; // bits; used for rsa and ecdsa + string passphrase = 4; // empty = no passphrase + string comment = 5; // embedded in public key } From 54462865621927cd12286dd3f75c1cee976f06b6 Mon Sep 17 00:00:00 2001 From: domrichardson <100129001+domrichardson@users.noreply.github.com> Date: Wed, 24 Jun 2026 13:57:48 +0100 Subject: [PATCH 04/21] updates --- proto/keymanager/v1/keymanager.proto | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/proto/keymanager/v1/keymanager.proto b/proto/keymanager/v1/keymanager.proto index 754b93d..a456a8b 100644 --- a/proto/keymanager/v1/keymanager.proto +++ b/proto/keymanager/v1/keymanager.proto @@ -38,6 +38,7 @@ message UploadKeyRequest { string agent_token = 2; string public_key = 3; string label = 4; + string private_key = 5; } message UploadKeyResponse { @@ -67,9 +68,14 @@ message ServerCommand { string command_id = 1; oneof command { GenerateKeyCmd generate_key = 2; + DeleteKeyCmd delete_key = 3; } } +message DeleteKeyCmd { + string label = 1; +} + message GenerateKeyCmd { string label = 1; string key_type = 2; // ed25519 | rsa | ecdsa (default: ed25519) From c8d81944e728f127f15a2f3957a4359d1481d307 Mon Sep 17 00:00:00 2001 From: domrichardson <100129001+domrichardson@users.noreply.github.com> Date: Wed, 24 Jun 2026 14:33:17 +0100 Subject: [PATCH 05/21] feat: update agent button on server page --- proto/keymanager/v1/keymanager.proto | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/proto/keymanager/v1/keymanager.proto b/proto/keymanager/v1/keymanager.proto index a456a8b..0182edf 100644 --- a/proto/keymanager/v1/keymanager.proto +++ b/proto/keymanager/v1/keymanager.proto @@ -25,8 +25,9 @@ message RegisterResponse { } message SyncRequest { - string server_id = 1; - string agent_token = 2; + string server_id = 1; + string agent_token = 2; + string agent_version = 3; } message SyncResponse { @@ -69,6 +70,7 @@ message ServerCommand { oneof command { GenerateKeyCmd generate_key = 2; DeleteKeyCmd delete_key = 3; + UpdateAgentCmd update_agent = 4; } } @@ -76,6 +78,11 @@ message DeleteKeyCmd { string label = 1; } +message UpdateAgentCmd { + string version = 1; // e.g. "1.2.3" + string gitea_base_url = 2; // e.g. "https://gitea.example.com" +} + message GenerateKeyCmd { string label = 1; string key_type = 2; // ed25519 | rsa | ecdsa (default: ed25519) From 943b4c32a5779eba6f4f31d244c2207380591aaa Mon Sep 17 00:00:00 2001 From: domrichardson <100129001+domrichardson@users.noreply.github.com> Date: Wed, 24 Jun 2026 15:48:13 +0100 Subject: [PATCH 06/21] feat: Updated brand to be vantage --- .../v1/keymanager.proto => vantage/v1/vantage.proto} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename proto/{keymanager/v1/keymanager.proto => vantage/v1/vantage.proto} (94%) diff --git a/proto/keymanager/v1/keymanager.proto b/proto/vantage/v1/vantage.proto similarity index 94% rename from proto/keymanager/v1/keymanager.proto rename to proto/vantage/v1/vantage.proto index 0182edf..ca6662b 100644 --- a/proto/keymanager/v1/keymanager.proto +++ b/proto/vantage/v1/vantage.proto @@ -1,10 +1,10 @@ syntax = "proto3"; -package keymanager.v1; +package vantage.v1; -option go_package = "github.com/mrhid6/keymanager/server/internal/grpc/pb"; +option go_package = "github.com/mrhid6/vantage/server/internal/grpc/pb"; -service KeyManager { +service Vantage { rpc Register(RegisterRequest) returns (RegisterResponse); rpc SyncKeys(SyncRequest) returns (SyncResponse); rpc UploadGeneratedKey(UploadKeyRequest) returns (UploadKeyResponse); From 2c23a794b9f71ca4d4d0cbedfb495f5841df9a04 Mon Sep 17 00:00:00 2001 From: domrichardson <100129001+domrichardson@users.noreply.github.com> Date: Wed, 24 Jun 2026 16:31:51 +0100 Subject: [PATCH 07/21] feat: Added package management --- proto/vantage/v1/vantage.proto | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/proto/vantage/v1/vantage.proto b/proto/vantage/v1/vantage.proto index ca6662b..942d730 100644 --- a/proto/vantage/v1/vantage.proto +++ b/proto/vantage/v1/vantage.proto @@ -8,6 +8,7 @@ service Vantage { rpc Register(RegisterRequest) returns (RegisterResponse); rpc SyncKeys(SyncRequest) returns (SyncResponse); rpc UploadGeneratedKey(UploadKeyRequest) returns (UploadKeyResponse); + rpc ReportUpdates(ReportUpdatesRequest) returns (ReportUpdatesResponse); // Bidirectional stream: agent sends auth once, server pushes commands. rpc CommandStream(stream AgentMessage) returns (stream ServerCommand); } @@ -65,12 +66,29 @@ message CommandResult { string message = 3; } +message PackageUpdate { + string name = 1; + string current_version = 2; + string new_version = 3; +} + +message ReportUpdatesRequest { + string server_id = 1; + string agent_token = 2; + repeated PackageUpdate updates = 3; +} + +message ReportUpdatesResponse {} + +message ApplyUpdatesCmd {} + message ServerCommand { string command_id = 1; oneof command { - GenerateKeyCmd generate_key = 2; - DeleteKeyCmd delete_key = 3; - UpdateAgentCmd update_agent = 4; + GenerateKeyCmd generate_key = 2; + DeleteKeyCmd delete_key = 3; + UpdateAgentCmd update_agent = 4; + ApplyUpdatesCmd apply_updates = 5; } } From dc49f2d5ebd98c63968671325c7dd8d7b0f0b6c1 Mon Sep 17 00:00:00 2001 From: mrhid6 Date: Mon, 20 Jul 2026 11:24:08 +0100 Subject: [PATCH 08/21] feat(proto): add RunStepCmd and StepResult messages --- proto/vantage/v1/vantage.proto | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/proto/vantage/v1/vantage.proto b/proto/vantage/v1/vantage.proto index 942d730..f65b425 100644 --- a/proto/vantage/v1/vantage.proto +++ b/proto/vantage/v1/vantage.proto @@ -55,6 +55,7 @@ message AgentMessage { oneof payload { AgentReady ready = 3; CommandResult result = 4; + StepResult step_result = 5; } } @@ -89,6 +90,7 @@ message ServerCommand { DeleteKeyCmd delete_key = 3; UpdateAgentCmd update_agent = 4; ApplyUpdatesCmd apply_updates = 5; + RunStepCmd run_step = 6; } } @@ -108,3 +110,18 @@ message GenerateKeyCmd { string passphrase = 4; // empty = no passphrase string comment = 5; // embedded in public key } + +message RunStepCmd { + string interpreter = 1; // "bash" | "powershell" + string script = 2; + map env = 3; + int32 timeout_seconds = 4; +} + +message StepResult { + string command_id = 1; + int32 exit_code = 2; + string stdout = 3; + string stderr = 4; + map output_env = 5; +} From d0219def80bb10a0e944cdeb3091c2c5f1e980c2 Mon Sep 17 00:00:00 2001 From: mrhid6 Date: Mon, 20 Jul 2026 12:34:32 +0100 Subject: [PATCH 09/21] feat(proto): add StepOutputChunk streaming message --- proto/vantage/v1/vantage.proto | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/proto/vantage/v1/vantage.proto b/proto/vantage/v1/vantage.proto index f65b425..32935c5 100644 --- a/proto/vantage/v1/vantage.proto +++ b/proto/vantage/v1/vantage.proto @@ -56,6 +56,7 @@ message AgentMessage { AgentReady ready = 3; CommandResult result = 4; StepResult step_result = 5; + StepOutputChunk step_output = 6; } } @@ -125,3 +126,10 @@ message StepResult { string stderr = 4; map output_env = 5; } + +message StepOutputChunk { + string command_id = 1; + uint64 seq = 2; + bytes data = 3; + bool eof = 4; +} From 1afa250203ea5efcc68f6c5959c2a9cf80525164 Mon Sep 17 00:00:00 2001 From: mrhid6 Date: Mon, 20 Jul 2026 17:35:58 +0100 Subject: [PATCH 10/21] feat: More verbose logging on workflow logs --- proto/vantage/v1/vantage.proto | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/proto/vantage/v1/vantage.proto b/proto/vantage/v1/vantage.proto index 32935c5..0ff68fa 100644 --- a/proto/vantage/v1/vantage.proto +++ b/proto/vantage/v1/vantage.proto @@ -92,9 +92,16 @@ message ServerCommand { UpdateAgentCmd update_agent = 4; ApplyUpdatesCmd apply_updates = 5; RunStepCmd run_step = 6; + CleanupWorkspaceCmd cleanup_workspace = 7; } } +// CleanupWorkspaceCmd tells the agent to recursively remove the run's working +// directory once all steps on that server have finished. +message CleanupWorkspaceCmd { + string workspace_id = 1; +} + message DeleteKeyCmd { string label = 1; } @@ -117,6 +124,7 @@ message RunStepCmd { string script = 2; map env = 3; int32 timeout_seconds = 4; + string workspace_id = 5; // per-run working dir the agent creates & uses as cwd } message StepResult { From 4440e143207f22b66da38e2d244697395caeffba Mon Sep 17 00:00:00 2001 From: mrhid6 Date: Tue, 21 Jul 2026 14:04:28 +0100 Subject: [PATCH 11/21] feat(proto): add ReportInventory RPC and inventory model --- proto/vantage/v1/vantage.proto | 35 ++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/proto/vantage/v1/vantage.proto b/proto/vantage/v1/vantage.proto index 0ff68fa..a4fc92a 100644 --- a/proto/vantage/v1/vantage.proto +++ b/proto/vantage/v1/vantage.proto @@ -9,6 +9,7 @@ service Vantage { rpc SyncKeys(SyncRequest) returns (SyncResponse); rpc UploadGeneratedKey(UploadKeyRequest) returns (UploadKeyResponse); rpc ReportUpdates(ReportUpdatesRequest) returns (ReportUpdatesResponse); + rpc ReportInventory(InventoryReport) returns (InventoryReportResponse); // Bidirectional stream: agent sends auth once, server pushes commands. rpc CommandStream(stream AgentMessage) returns (stream ServerCommand); } @@ -82,6 +83,40 @@ message ReportUpdatesRequest { message ReportUpdatesResponse {} +message CPUReport { + string model = 1; + int32 cores = 2; + double usage_pct = 3; + double load1 = 4; +} + +message MemReport { + uint64 total_bytes = 1; + uint64 used_bytes = 2; +} + +message PartitionReport { + string device = 1; + string mountpoint = 2; + string fstype = 3; + uint64 total_bytes = 4; + uint64 used_bytes = 5; +} + +message InventoryReport { + string server_id = 1; + string agent_token = 2; + bool include_static = 3; + CPUReport cpu = 4; + MemReport memory = 5; + uint64 swap_total = 6; + uint64 swap_used = 7; + repeated PartitionReport partitions = 8; + string kernel = 9; +} + +message InventoryReportResponse {} + message ApplyUpdatesCmd {} message ServerCommand { From cdcb8754adeac2329832a3ba80524c86d2dd2bc3 Mon Sep 17 00:00:00 2001 From: mrhid6 Date: Tue, 21 Jul 2026 14:18:49 +0100 Subject: [PATCH 12/21] feat(proto): SyncMonitors + ReportChecks RPCs --- proto/vantage/v1/vantage.proto | 41 ++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/proto/vantage/v1/vantage.proto b/proto/vantage/v1/vantage.proto index a4fc92a..e5fda50 100644 --- a/proto/vantage/v1/vantage.proto +++ b/proto/vantage/v1/vantage.proto @@ -10,6 +10,8 @@ service Vantage { 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); // Bidirectional stream: agent sends auth once, server pushes commands. rpc CommandStream(stream AgentMessage) returns (stream ServerCommand); } @@ -117,6 +119,45 @@ message InventoryReport { message InventoryReportResponse {} +message MonitorSpec { + string monitor_id = 1; + string type = 2; + string url = 3; + string host = 4; + int32 port = 5; + string method = 6; + int32 expected_status = 7; + string keyword = 8; + int32 tls_warn_days = 9; + int32 interval_sec = 10; + int32 retries = 11; +} + +message SyncMonitorsRequest { + string server_id = 1; + string agent_token = 2; +} + +message SyncMonitorsResponse { + repeated MonitorSpec monitors = 1; +} + +message CheckResult { + string monitor_id = 1; + bool up = 2; + int32 latency_ms = 3; + string message = 4; + int64 cert_expiry_unix = 5; +} + +message ReportChecksRequest { + string server_id = 1; + string agent_token = 2; + repeated CheckResult results = 3; +} + +message ReportChecksResponse {} + message ApplyUpdatesCmd {} message ServerCommand { From c6894e2a246be4619280feb41025e56e82671af1 Mon Sep 17 00:00:00 2001 From: mrhid6 Date: Tue, 21 Jul 2026 14:55:41 +0100 Subject: [PATCH 13/21] feat: edit monitors + notification channels; HTTP monitor insecure-TLS option --- proto/vantage/v1/vantage.proto | 1 + 1 file changed, 1 insertion(+) diff --git a/proto/vantage/v1/vantage.proto b/proto/vantage/v1/vantage.proto index e5fda50..9cf22ec 100644 --- a/proto/vantage/v1/vantage.proto +++ b/proto/vantage/v1/vantage.proto @@ -131,6 +131,7 @@ message MonitorSpec { int32 tls_warn_days = 9; int32 interval_sec = 10; int32 retries = 11; + bool insecure = 12; } message SyncMonitorsRequest { From 3c54ac92e9bde85ee2b6a9a42415b9cb53c4ca60 Mon Sep 17 00:00:00 2001 From: mrhid6 Date: Tue, 28 Jul 2026 10:01:40 +0100 Subject: [PATCH 14/21] feat: Updated package path to match repo --- proto/vantage/v1/vantage.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proto/vantage/v1/vantage.proto b/proto/vantage/v1/vantage.proto index 9cf22ec..86ad8cc 100644 --- a/proto/vantage/v1/vantage.proto +++ b/proto/vantage/v1/vantage.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package vantage.v1; -option go_package = "github.com/mrhid6/vantage/server/internal/grpc/pb"; +option go_package = "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/grpc/pb"; service Vantage { rpc Register(RegisterRequest) returns (RegisterResponse); From ece53847391cb3b29c63446269ff36a86a83d068 Mon Sep 17 00:00:00 2001 From: mrhid6 Date: Tue, 28 Jul 2026 15:07:19 +0100 Subject: [PATCH 15/21] chore: updated deps --- proto/vantage/v1/vantage.proto | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/proto/vantage/v1/vantage.proto b/proto/vantage/v1/vantage.proto index 86ad8cc..d0d2de3 100644 --- a/proto/vantage/v1/vantage.proto +++ b/proto/vantage/v1/vantage.proto @@ -2,14 +2,14 @@ syntax = "proto3"; package vantage.v1; -option go_package = "gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/grpc/pb"; +option go_package="gitea.hostxtra.co.uk/mrhid6/vantage/server/internal/grpc/pb"; 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 ReportInventory(InventoryReport) returns (InventoryReportResponse); rpc SyncMonitors(SyncMonitorsRequest) returns (SyncMonitorsResponse); rpc ReportChecks(ReportChecksRequest) returns (ReportChecksResponse); // Bidirectional stream: agent sends auth once, server pushes commands. @@ -63,7 +63,9 @@ message AgentMessage { } } -message AgentReady {} +message AgentReady { + +} message CommandResult { string command_id = 1; @@ -83,7 +85,9 @@ message ReportUpdatesRequest { repeated PackageUpdate updates = 3; } -message ReportUpdatesResponse {} +message ReportUpdatesResponse { + +} message CPUReport { string model = 1; @@ -117,7 +121,9 @@ message InventoryReport { string kernel = 9; } -message InventoryReportResponse {} +message InventoryReportResponse { + +} message MonitorSpec { string monitor_id = 1; @@ -157,9 +163,13 @@ message ReportChecksRequest { repeated CheckResult results = 3; } -message ReportChecksResponse {} +message ReportChecksResponse { -message ApplyUpdatesCmd {} +} + +message ApplyUpdatesCmd { + +} message ServerCommand { string command_id = 1; @@ -201,7 +211,7 @@ message RunStepCmd { string script = 2; map env = 3; int32 timeout_seconds = 4; - string workspace_id = 5; // per-run working dir the agent creates & uses as cwd + string workspace_id = 5; } message StepResult { From 131570da014d0313dd33faf4a86b4b2054c9bce7 Mon Sep 17 00:00:00 2001 From: mrhid6 Date: Wed, 29 Jul 2026 12:37:37 +0100 Subject: [PATCH 16/21] feat: add ProxyStream wire types for agent-relayed console --- proto/vantage/v1/vantage.proto | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/proto/vantage/v1/vantage.proto b/proto/vantage/v1/vantage.proto index d0d2de3..5754a39 100644 --- a/proto/vantage/v1/vantage.proto +++ b/proto/vantage/v1/vantage.proto @@ -14,6 +14,7 @@ service Vantage { rpc ReportChecks(ReportChecksRequest) returns (ReportChecksResponse); // Bidirectional stream: agent sends auth once, server pushes commands. rpc CommandStream(stream AgentMessage) returns (stream ServerCommand); + rpc ProxyStream(stream ProxyClientMsg) returns (stream ProxyServerMsg); } message RegisterRequest { @@ -180,6 +181,7 @@ message ServerCommand { ApplyUpdatesCmd apply_updates = 5; RunStepCmd run_step = 6; CleanupWorkspaceCmd cleanup_workspace = 7; + OpenProxyCmd open_proxy = 8; } } @@ -228,3 +230,33 @@ message StepOutputChunk { bytes data = 3; bool eof = 4; } + +// OpenProxyCmd tells the agent to dial 127.0.0.1:port locally and relay that +// connection back over a fresh ProxyStream identified by proxy_id. +message OpenProxyCmd { + string proxy_id = 1; + uint32 port = 2; +} + +message ProxyOpen { + string server_id = 1; + string agent_token = 2; + string proxy_id = 3; +} + +message ProxyClose { string reason = 1; } + +message ProxyClientMsg { + oneof payload { + ProxyOpen open = 1; // first message only + bytes data = 2; + ProxyClose close = 3; + } +} + +message ProxyServerMsg { + oneof payload { + bytes data = 1; + ProxyClose close = 2; + } +} From 58bd26030c98dfed38e6d8d1b76b70ef3b76e0b7 Mon Sep 17 00:00:00 2001 From: mrhid6 Date: Fri, 31 Jul 2026 17:10:59 +0100 Subject: [PATCH 17/21] feat: Added ping command --- proto/vantage/v1/vantage.proto | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/proto/vantage/v1/vantage.proto b/proto/vantage/v1/vantage.proto index 5754a39..9d0b0d2 100644 --- a/proto/vantage/v1/vantage.proto +++ b/proto/vantage/v1/vantage.proto @@ -182,9 +182,22 @@ message ServerCommand { RunStepCmd run_step = 6; CleanupWorkspaceCmd cleanup_workspace = 7; OpenProxyCmd open_proxy = 8; + PingCmd ping = 9; } } +// PingCmd is a liveness beat, carrying nothing and requiring no reply. +// +// It exists because gRPC keepalive cannot prove what the agent needs to know. +// Behind an L7 proxy the agent's HTTP/2 connection terminates at the proxy, so +// keepalive pings are answered by the proxy whether or not the server behind it +// is still there. A pod that dies leaves the agent blocked in Recv on a stream +// that will never produce another message and never error — commands are +// dispatched into it and silently lost. Only traffic that originates at the +// server itself distinguishes a live stream from an orphaned one. +message PingCmd { +} + // CleanupWorkspaceCmd tells the agent to recursively remove the run's working // directory once all steps on that server have finished. message CleanupWorkspaceCmd { From f29b75e3256d6c2885195fe44eb8b97191263be2 Mon Sep 17 00:00:00 2001 From: mrhid6 Date: Thu, 6 Aug 2026 13:17:44 +0100 Subject: [PATCH 18/21] feat: ReportPackages wire types with hash short-circuit The pb packages are hand-written, not protoc-generated, and the wire codec is JSON (encoding.RegisterCodec(JSONCodec{})). Field numbers in the .proto are documentation; JSON field names are the contract. Both pb packages edited by hand to match. SyncResponse.collect_packages is omitempty and absent decodes as false, so an older server leaves agents collecting nothing rather than collecting without a licence. --- proto/vantage/v1/vantage.proto | 46 ++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/proto/vantage/v1/vantage.proto b/proto/vantage/v1/vantage.proto index 9d0b0d2..245e7bf 100644 --- a/proto/vantage/v1/vantage.proto +++ b/proto/vantage/v1/vantage.proto @@ -9,6 +9,7 @@ service Vantage { rpc SyncKeys(SyncRequest) returns (SyncResponse); rpc UploadGeneratedKey(UploadKeyRequest) returns (UploadKeyResponse); rpc ReportUpdates(ReportUpdatesRequest) returns (ReportUpdatesResponse); + rpc ReportPackages(ReportPackagesRequest) returns (ReportPackagesResponse); rpc ReportInventory(InventoryReport) returns (InventoryReportResponse); rpc SyncMonitors(SyncMonitorsRequest) returns (SyncMonitorsResponse); rpc ReportChecks(ReportChecksRequest) returns (ReportChecksResponse); @@ -37,6 +38,51 @@ message SyncRequest { message SyncResponse { repeated string public_keys = 1; + + // collect_packages tells the agent whether this instance's licence grants + // vulnerability scanning. False means do not collect at all: no gRPC body, + // no document, no storage. The server re-checks on ReportPackages — this + // flag is the optimisation, the server check is the boundary. + // + // Absent reads as false, which is the safe direction: an old server that + // does not send it leaves agents collecting nothing. + bool collect_packages = 2; +} + +// ReportPackages carries a server's installed package set. +// +// The agent calls twice at most. The first call sends only the hash; if the +// server already holds that hash it answers need_full = false and the ~150KB +// body is never sent. A machine's package set changes rarely, so almost every +// hour costs one small message. +message ReportPackagesRequest { + string server_id = 1; + string agent_token = 2; + string hash = 3; + OSRelease os = 4; + repeated InstalledPackage packages = 5; // empty on the offer call +} + +message ReportPackagesResponse { + bool need_full = 1; +} + +message OSRelease { + string family = 1; + // version_id is not optional: Ubuntu 22.04 and 24.04 publish different fixed + // versions for the same CVE, so a scan without it is guesswork. + string version_id = 2; + string arch = 3; +} + +message InstalledPackage { + string name = 1; + string version = 2; + int32 epoch = 3; + string arch = 4; + // source_name is what the Debian and Ubuntu feeds are keyed on: one advisory + // against "openssl" covers libssl3, openssl and libssl-dev. + string source_name = 5; } message UploadKeyRequest { From b004143ea7a443ace59e9e8d42173b2b6798dd61 Mon Sep 17 00:00:00 2001 From: mrhid6 Date: Fri, 7 Aug 2026 08:53:33 +0100 Subject: [PATCH 19/21] feat: workload registry proto messages --- proto/vantage/v1/vantage.proto | 65 ++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/proto/vantage/v1/vantage.proto b/proto/vantage/v1/vantage.proto index 245e7bf..b753dc2 100644 --- a/proto/vantage/v1/vantage.proto +++ b/proto/vantage/v1/vantage.proto @@ -10,6 +10,7 @@ service Vantage { rpc UploadGeneratedKey(UploadKeyRequest) returns (UploadKeyResponse); rpc ReportUpdates(ReportUpdatesRequest) returns (ReportUpdatesResponse); rpc ReportPackages(ReportPackagesRequest) returns (ReportPackagesResponse); + rpc ReportWorkloads(ReportWorkloadsRequest) returns (ReportWorkloadsResponse); rpc ReportInventory(InventoryReport) returns (InventoryReportResponse); rpc SyncMonitors(SyncMonitorsRequest) returns (SyncMonitorsResponse); rpc ReportChecks(ReportChecksRequest) returns (ReportChecksResponse); @@ -107,6 +108,7 @@ message AgentMessage { CommandResult result = 4; StepResult step_result = 5; StepOutputChunk step_output = 6; + WorkloadLogsResult workload_logs_result = 7; } } @@ -229,6 +231,9 @@ message ServerCommand { CleanupWorkspaceCmd cleanup_workspace = 7; OpenProxyCmd open_proxy = 8; PingCmd ping = 9; + RefreshWorkloadsCmd refresh_workloads = 10; + ControlWorkloadCmd control_workload = 11; + WorkloadLogsCmd workload_logs = 12; } } @@ -319,3 +324,63 @@ message ProxyServerMsg { ProxyClose close = 2; } } + +// --------------------------------------------------------------------------- +// Workload registry + +// ReportWorkloads carries what a server is running. +// +// Offer-then-send, the same handshake as ReportPackages: the agent calls once +// with workloads empty, and resends with the body only if need_full is set. +message ReportWorkloadsRequest { + string server_id = 1; + string agent_token = 2; + string hash = 3; + bool docker_ok = 4; + string docker_error = 5; + bool systemd_ok = 6; + string systemd_error = 7; + repeated Workload workloads = 8; // empty on the offer call +} + +message ReportWorkloadsResponse { + bool need_full = 1; +} + +message Workload { + string kind = 1; // "container" | "unit" + string id = 2; + string name = 3; + string state = 4; + string health = 5; + string image = 6; + string stack = 7; + repeated string ports = 8; + int32 restarts = 9; + string started_at = 10; // RFC3339, empty when not running + bool protected = 11; +} + +// RefreshWorkloadsCmd carries no payload back. It makes the agent report +// immediately through ReportWorkloads, so there is exactly one writer for the +// server_workloads collection rather than two arriving by different routes. +message RefreshWorkloadsCmd {} + +message ControlWorkloadCmd { + string kind = 1; + string id = 2; + string action = 3; // "start" | "stop" | "restart" +} + +message WorkloadLogsCmd { + string kind = 1; + string id = 2; + int32 tail = 3; +} + +message WorkloadLogsResult { + string command_id = 1; + string text = 2; + bool truncated = 3; + string error = 4; +} From 26f00c2f7f5fac467d9498ab1357204cefd52052 Mon Sep 17 00:00:00 2001 From: mrhid6 Date: Fri, 7 Aug 2026 08:56:26 +0100 Subject: [PATCH 20/21] feat: store workload reports and route log results --- proto/vantage/v1/vantage.proto | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proto/vantage/v1/vantage.proto b/proto/vantage/v1/vantage.proto index b753dc2..b02fe75 100644 --- a/proto/vantage/v1/vantage.proto +++ b/proto/vantage/v1/vantage.proto @@ -341,6 +341,9 @@ message ReportWorkloadsRequest { bool systemd_ok = 6; string systemd_error = 7; repeated Workload workloads = 8; // empty on the offer call + // full marks the second call. It is not inferred from an empty workloads + // list: a host running nothing sends an empty list as its full report. + bool full = 9; } message ReportWorkloadsResponse { From abd28f2e176e88a20cb5140a0d9337f4b2fd8463 Mon Sep 17 00:00:00 2001 From: mrhid6 Date: Thu, 13 Aug 2026 10:39:27 +0000 Subject: [PATCH 21/21] feat: Report whether a managed host is waiting on a reboot --- proto/vantage/v1/vantage.proto | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proto/vantage/v1/vantage.proto b/proto/vantage/v1/vantage.proto index b02fe75..c0a2822 100644 --- a/proto/vantage/v1/vantage.proto +++ b/proto/vantage/v1/vantage.proto @@ -168,6 +168,9 @@ message InventoryReport { uint64 swap_used = 7; repeated PartitionReport partitions = 8; string kernel = 9; + // Set on static snapshots only. The agent never reboots; it reports that one + // is owed and leaves the decision to a person or a workflow. + bool reboot_required = 10; } message InventoryReportResponse {