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.
This commit is contained in:
2026-08-06 13:17:44 +01:00
parent 3a6d24fe0e
commit a92c3190c2
3 changed files with 163 additions and 0 deletions
+46
View File
@@ -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 {