source: advance the checked projection

Source-Sha: 194a59adfd6c901635da7a9c18253bb2210e2426
Policy-Sha: b9b0be0ee74e55f561a803b8aef6be3c2134f5a83b46816a069a372f2eb04f4d
Tree-Digest: 4697f2e281c1c6ecafff17cf6eeb391a0a1ac0fa6e5fc429f5b473f4579c252c
This commit is contained in:
Source publisher 2026-09-21 14:39:08 +00:00
commit ffdccba10f
42 changed files with 2516 additions and 554 deletions

View file

@ -338,6 +338,38 @@ type RegisterResponse struct {
Config map[string]interface{} `json:"config"`
}
// FleetJoinRequest preserves a standalone Agent's UUID while registering that
// same machine with a Server. The seed stays on the host; only its current TOTP
// code crosses this endpoint.
type FleetJoinRequest struct {
RequestID uuid.UUID `json:"request_id"`
AgentID uuid.UUID `json:"agent_id"`
RegistrationToken string `json:"registration_token"`
TOTPCode string `json:"totp_code"`
Hostname string `json:"hostname"`
OSType string `json:"os_type"`
OSVersion string `json:"os_version"`
OSArchitecture string `json:"os_architecture"`
AgentVersion string `json:"agent_version"`
MachineID string `json:"machine_id"`
PublicKeyFingerprint string `json:"public_key_fingerprint"`
Metadata map[string]string `json:"metadata"`
AvailableScanners []string `json:"available_scanners"`
DeviceType string `json:"device_type"`
DeviceModel string `json:"device_model"`
OSDistro string `json:"os_distro"`
}
type FleetJoinResponse struct {
AgentID uuid.UUID `json:"agent_id"`
Token string `json:"token"`
RefreshToken string `json:"refresh_token"`
SigningPublicKey string `json:"signing_public_key"`
SigningKeyID string `json:"signing_key_id"`
ServerURL string `json:"server_url"`
Config map[string]interface{} `json:"config"`
}
// Register registers the agent with the server
func (c *Client) Register(req RegisterRequest) (*RegisterResponse, error) {
url := fmt.Sprintf("%s/api/v1/agents/register", c.baseURL)
@ -388,6 +420,36 @@ func (c *Client) Register(req RegisterRequest) (*RegisterResponse, error) {
return &result, nil
}
// JoinFleet calls the dedicated one-way standalone transition endpoint. It
// does not mutate this Client's token because the caller must first persist the
// returned credentials and replace local helper authority.
func (c *Client) JoinFleet(req FleetJoinRequest) (*FleetJoinResponse, error) {
endpoint := fmt.Sprintf("%s/api/v1/fleet-join", c.baseURL)
body, err := json.Marshal(req)
if err != nil {
return nil, fmt.Errorf("encode fleet join request: %w", err)
}
httpReq, err := http.NewRequest(http.MethodPost, endpoint, bytes.NewReader(body))
if err != nil {
return nil, fmt.Errorf("create fleet join request: %w", err)
}
httpReq.Header.Set("Content-Type", "application/json")
resp, err := c.http.Do(httpReq)
if err != nil {
return nil, fmt.Errorf("fleet join request failed: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusCreated {
bodyBytes, _ := io.ReadAll(io.LimitReader(resp.Body, 1<<20))
return nil, fmt.Errorf("fleet join failed: %s - %s", resp.Status, string(bodyBytes))
}
var result FleetJoinResponse
if err := json.NewDecoder(io.LimitReader(resp.Body, 1<<20)).Decode(&result); err != nil {
return nil, fmt.Errorf("decode fleet join response: %w", err)
}
return &result, nil
}
// TokenRenewalRequest is the payload for token renewal using refresh token
type TokenRenewalRequest struct {
AgentID uuid.UUID `json:"agent_id"`
@ -1072,7 +1134,7 @@ type SystemInfoReport struct {
IPAddress string `json:"ip_address,omitempty"`
Processes int `json:"processes,omitempty"`
Uptime string `json:"uptime,omitempty"`
DeviceType string `json:"device_type,omitempty"` // Re-reported so reinstalls reclassify (DEVICE-001)
DeviceType string `json:"device_type,omitempty"` // Re-reported so reinstalls reclassify (DEVICE-001)
DeviceModel string `json:"device_model,omitempty"`
OSDistro string `json:"os_distro,omitempty"`
Metadata map[string]interface{} `json:"metadata,omitempty"`