From f29b75e3256d6c2885195fe44eb8b97191263be2 Mon Sep 17 00:00:00 2001 From: mrhid6 Date: Thu, 6 Aug 2026 13:17:44 +0100 Subject: [PATCH] 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 {