Import the wilm agent store, WINC adoption work and batches CLI, with four fixes

This commit is contained in:
2026-09-03 08:16:38 -04:00
parent 4b21aa3887
commit b0bd73f62d
51 changed files with 5107 additions and 90 deletions

View File

@@ -49,7 +49,7 @@ CURATED_EVENT_IDS = frozenset(EVENT_CATALOG)
KNOWN_PAYLOAD_KEYS = frozenset({
'hostname', 'adopt', 'loggedinuser', 'serialnumber', 'pctype',
'machinenumber', 'vendorname', 'modelnumber', 'osname', 'ipaddress',
'agentversion', 'lastboottime', 'uptimeseconds', 'idleseconds',
'agentversion', 'trayversion', 'lastboottime', 'uptimeseconds', 'idleseconds',
'cpupercent', 'memorypercent', 'services', 'ports', 'interfaces',
'scheduledtasks', 'applications', 'events',
})
@@ -167,19 +167,40 @@ class EndpointsPlugin(BasePlugin):
# running a staged script or pushing an installer is a strictly
# heavier grant than a routine service/process toggle.
('endpoints.deploy',
'Run staged scripts and push application installers to endpoints', 'endpoints'),
# Packaging the agent is a heavier grant than deploying to one, and
# it is not the same job either: the generated ZIP carries a live
# collector key stamped into its install script, so whoever holds
# this can mint a distributable artefact containing the fleet-wide
# command-channel credential. It was require_role('admin'), which
# this codebase otherwise reserves for the few genuinely
# role-shaped checks - and a role cannot be granted to one person
# for one job the way a permission can.
('endpoints.agentpackage',
'Generate and download an agent or adoption-tool package '
'(contains a live collector key)', 'endpoints'),
# Collector service scope for the endpoint agent. A managed token
'Run staged scripts and push application installers to endpoints', 'endpoints'),
# Packaging the agent is a heavier grant than deploying to one, and
# it is not the same job either: the generated ZIP carries a live
# collector key stamped into its install script, so whoever holds
# this can mint a distributable artefact containing the fleet-wide
# command-channel credential. It was require_role('admin'), which
# this codebase otherwise reserves for the few genuinely
# role-shaped checks - and a role cannot be granted to one person
# for one job the way a permission can.
# It now also governs SUPPLYING the binary, not just wrapping it.
# Before the agent store, the exe could only be staged by someone
# with filesystem access to instance/siteagent/; the upload routes
# put that behind this same grant, so a holder chooses the file
# every future package installs and runs as SYSTEM. Whoever grants
# this has to be able to see that from the description.
('endpoints.agentpackage',
'Upload the agent binary the fleet installs, and generate or '
'download an agent or adoption-tool package (supplies an '
'executable that runs as SYSTEM; the package contains a live '
'collector key)', 'endpoints'),
# Pushing an agent REPLACEMENT to running endpoints is a distinct,
# heavier job than either packaging (endpoints.agentpackage) or
# pushing an ordinary application installer (endpoints.deploy).
# Kept separate on purpose: the agent runs as SYSTEM and is the
# command channel itself, so replacing it is self-modifying the
# control plane. Folding it into endpoints.deploy would let anyone
# who can push an app silently swap the agent; folding it into
# endpoints.agentpackage would let a packager who only mints ZIPs
# also force a live fleet-wide swap. A future Operator role can
# hold upload without this, or this without upload.
('endpoints.agentupdate',
'Push agent/tray binary updates to running endpoints '
'(replaces the SYSTEM agent)', 'endpoints'),
# Collector service scope for the endpoint agent. A managed token
# scoped to ONLY this authorizes the endpoints collector and nothing
# else, so rotating/revoking it stops endpoint-agent traffic without
# touching computers/geenforce collectors. Minted from the settings
@@ -575,6 +596,7 @@ class EndpointsPlugin(BasePlugin):
},
'loggedinuser': {'type': 'string'},
'agentversion': {'type': 'string'},
'trayversion': {'type': 'string'},
'lastboottime': {'type': 'string', 'format': 'date-time'},
'uptimeseconds': {'type': 'integer'},
'idleseconds': {'type': 'integer'},
@@ -786,6 +808,8 @@ class EndpointsPlugin(BasePlugin):
state.loggedinuser = payload.get('loggedinuser')
if 'agentversion' in payload:
state.agentversion = payload.get('agentversion')
if 'trayversion' in payload:
state.trayversion = payload.get('trayversion')
if 'lastboottime' in payload:
state.lastboottime = _parse_dt(payload.get('lastboottime'))
if 'uptimeseconds' in payload: