feat: mint desktop-self tokens on agent update (UPDATE-002)
This commit is contained in:
parent
f6bb28e9cd
commit
b2319e15ed
3 changed files with 83 additions and 11 deletions
|
|
@ -28,6 +28,7 @@ type AgentUpdateHandler struct {
|
|||
nonceService *services.UpdateNonceService
|
||||
agentHandler *AgentHandler
|
||||
securitySettings *services.SecuritySettingsService // optional; reads policy.require_nonce
|
||||
capabilityTokens *queries.CapabilityTokenQueries // optional; enables desktop-self minting (UPDATE-002)
|
||||
}
|
||||
|
||||
// NewAgentUpdateHandler creates a new agent update handler
|
||||
|
|
@ -49,6 +50,57 @@ func (h *AgentUpdateHandler) SetSecuritySettings(s *services.SecuritySettingsSer
|
|||
h.securitySettings = s
|
||||
}
|
||||
|
||||
// SetCapabilityTokenQueries enables desktop-self token minting (UPDATE-002).
|
||||
// Nil leaves agent updates working without tray delivery.
|
||||
func (h *AgentUpdateHandler) SetCapabilityTokenQueries(q *queries.CapabilityTokenQueries) {
|
||||
h.capabilityTokens = q
|
||||
}
|
||||
|
||||
// mintDesktopSelfToken creates and stores a desktop-self capability token for
|
||||
// the given agent+version so the agent's polling loop picks it up and upgrades
|
||||
// the systray app. Nil capabilityTokens (not wired) or a missing desktop
|
||||
// package for this version are not errors — the agent update proceeds without
|
||||
// desktop delivery.
|
||||
func (h *AgentUpdateHandler) mintDesktopSelfToken(agentID uuid.UUID, version string) error {
|
||||
if h.capabilityTokens == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
desktopPkg, err := h.agentUpdateQueries.GetUpdatePackageByVersion(version, "desktop-linux", "amd64")
|
||||
if err != nil || desktopPkg == nil {
|
||||
return nil // no desktop package for this version — normal
|
||||
}
|
||||
|
||||
closure := []capability.ClosureEntry{{
|
||||
Name: "redflag-desktop",
|
||||
Version: version,
|
||||
SHA256: desktopPkg.Checksum,
|
||||
Source: "desktop-self",
|
||||
}}
|
||||
|
||||
now := time.Now().UTC()
|
||||
token := &capability.Token{
|
||||
Version: capability.Version,
|
||||
TokenID: uuid.Must(uuid.NewV4()).String(),
|
||||
AgentID: agentID.String(),
|
||||
PackageType: "desktop-self",
|
||||
Operation: "upgrade",
|
||||
Closure: closure,
|
||||
IssuedAt: now.Unix(),
|
||||
NotBefore: now.Unix(),
|
||||
ExpiresAt: now.Add(24 * time.Hour).Unix(), // desktop restart may lag
|
||||
}
|
||||
if err := h.signingService.SignCapabilityToken(token); err != nil {
|
||||
return fmt.Errorf("sign desktop-self token: %w", err)
|
||||
}
|
||||
if err := h.capabilityTokens.Insert(token, uuid.Nil); err != nil {
|
||||
return fmt.Errorf("store desktop-self token: %w", err)
|
||||
}
|
||||
|
||||
log.Printf("[INFO] [server] [agent_update] desktop_self_token_minted agent_id=%s version=%s token_id=%s", agentID, version, token.TokenID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// mintAgentSelfToken signs an agent-self capability token authorizing the
|
||||
// privileged helper to swap the agent binary to the given version/checksum. The
|
||||
// helper verifies this signature and the new binary's hash before installing.
|
||||
|
|
@ -294,6 +346,12 @@ func (h *AgentUpdateHandler) UpdateAgent(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
// Mint a desktop-self token so the agent's polling loop also upgrades the
|
||||
// systray app. Non-fatal: the agent update proceeds without desktop delivery.
|
||||
if err := h.mintDesktopSelfToken(agentIDUUID, req.Version); err != nil {
|
||||
log.Printf("[WARNING] [server] [agent_update] desktop_self_token_failed agent_id=%s error=%v", agentIDUUID, err)
|
||||
}
|
||||
|
||||
// Create update command for agent
|
||||
commandType := "update_agent"
|
||||
commandParams := map[string]interface{}{
|
||||
|
|
@ -466,6 +524,11 @@ func (h *AgentUpdateHandler) BulkUpdateAgents(c *gin.Context) {
|
|||
continue
|
||||
}
|
||||
|
||||
// Desktop-self token: non-fatal, delivered via the capability-token poll.
|
||||
if err := h.mintDesktopSelfToken(agentID, req.Version); err != nil {
|
||||
log.Printf("[WARNING] [server] [agent_update] desktop_self_token_failed agent_id=%s error=%v", agentID, err)
|
||||
}
|
||||
|
||||
// Create update command
|
||||
command := &models.AgentCommand{
|
||||
ID: uuid.Must(uuid.NewV4()),
|
||||
|
|
|
|||
Loading…
Reference in a new issue