Skip to content

Redesign Puppy agent #78

@FrodeHus

Description

@FrodeHus

Summary

Redesign PatchHound.Puppy from a minimal SSH job runner into a PatchHound-owned modular scan agent for authenticated, unauthenticated, and active network scanning.

The design should reuse the useful operational patterns from D:\scanner-reversed\reconstruction-spec.md while removing all dependencies on Microsoft Defender for Endpoint, Sense onboarding, Defender cloud services, Defender certificates, ETW-only telemetry, cluster resolution, and Defender updater behavior. Puppy should be controlled entirely by PatchHound: PatchHound API, PatchHound tenant model, PatchHound runner registration, PatchHound secrets, PatchHound audit/logging, and PatchHound scan result ingestion.

Problem

PatchHound.Puppy is currently a narrow worker:

  • YAML config with centralUrl and bearer token.
  • Polls /api/scan-runner/jobs/next.
  • Executes supplied scripts over SSH.
  • Posts raw stdout/stderr results back to PatchHound.

That is enough for the first authenticated Linux scan path, but it does not provide the agent architecture needed for broader vulnerability operations:

  • No formal command envelope or scanner plugin boundary.
  • No first-class Windows authenticated scanner module.
  • No network discovery/SNMP scanner module.
  • No active protocol scanner module.
  • No robust output sink/chunking model for partial results and target-level failures.
  • No runner identity lifecycle beyond a static bearer token.
  • No bounded queue, concurrency model, drain behavior, or watchdog behavior.
  • No structured scan telemetry suitable for PatchHound ingestion and audit trails.
  • No clear packaging/service story for Windows and Linux deployments.

Proposed Approach

Build a PatchHound-native Puppy v2 architecture with the same high-level worker pattern as the analyzed scanner design, but with PatchHound contracts and infrastructure throughout.

Principles

  • Puppy is a PatchHound agent, not a Defender-compatible agent.
  • PatchHound API is the only control plane.
  • PatchHound runner registration replaces Defender/Sense onboarding.
  • PatchHound tenant and runner IDs replace org/machine IDs from the source spec.
  • OpenBao-backed PatchHound secret references replace Key Vault and encrypted Defender payload assumptions.
  • ASP.NET/Core ILogger, structured JSON logs, and PatchHound audit events replace ETW-only reporting.
  • PatchHound scan result contracts replace Defender command output and ETW descriptor models.
  • Cross-platform worker service packaging replaces Windows-only LocalSystem assumptions where possible.

Target Architecture

PatchHound.Puppy.Host

Service/worker entry point responsible for:

  • Loading configuration from YAML, environment variables, and optional service-managed config.
  • Starting a generic host with scanner modules registered through DI.
  • Registering or validating runner identity with PatchHound API.
  • Starting command polling, output upload, heartbeat, watchdog, and graceful shutdown loops.
  • Supporting Windows Service and systemd deployments.

PatchHound.Puppy.Contracts

Shared DTOs and contracts for the runner-facing API:

  • Runner registration and heartbeat.
  • Command envelope.
  • Command types.
  • Scan options.
  • Target descriptors.
  • Credential/secret references.
  • Result chunks.
  • EOF/finalization markers.
  • Target-level success, partial success, failure, and fatal error statuses.

Suggested command types:

  • NetworkDiscovery
  • SnmpScan
  • WindowsAuthenticatedScan
  • LinuxAuthenticatedScan
  • ActiveProtocolScan
  • RunnerUpdateAvailable or RunnerConfigChanged as future-compatible control messages

PatchHound.Puppy.ApiClient

Typed HTTP client for PatchHound runner endpoints:

  • POST /api/scan-runner/register
  • POST /api/scan-runner/heartbeat
  • GET /api/scan-runner/commands/next or batched equivalent
  • POST /api/scan-runner/commands/{commandId}/heartbeat
  • POST /api/scan-runner/commands/{commandId}/result-chunks
  • POST /api/scan-runner/commands/{commandId}/complete

Requirements:

  • No hardcoded external service URLs.
  • Base URL comes from config.
  • Auth uses PatchHound-issued runner credentials.
  • Requests include queue depth, runner version, capabilities, and supported scanner modules.
  • Retries should be deliberate and bounded; do not duplicate non-idempotent result uploads.

PatchHound.Puppy.CommandProcessing

Command orchestration layer:

  • Bounded in-memory queue.
  • Configurable concurrency per scanner type.
  • Lease heartbeat while command is active.
  • Cancellation and timeout handling.
  • Graceful stop that drains active work up to a bounded timeout.
  • Scanner dispatch through IScanner<TCommand> or equivalent non-generic dispatcher.
  • Every accepted command ends in a terminal result, even on scanner exceptions.

PatchHound.Puppy.Output

Output sink responsible for:

  • Normalizing scanner results into PatchHound result chunks.
  • Uploading partial results as they are produced.
  • Preserving target-level errors instead of dropping failed targets.
  • Sending a final EOF/completion marker with counts.
  • Applying size limits and chunk boundaries consistently.
  • Recording upload failures and retry state.

PatchHound.Puppy.Secrets

Secret resolution layer:

  • Prefer server-side secret resolution where safe, using short-lived job payloads.
  • Support PatchHound/OpenBao secret references when the runner must resolve secrets directly.
  • Keep secret values out of logs, command echo, result payloads, and crash dumps.
  • Define explicit lifetime and zeroization expectations for in-memory secret material where practical.

Scanner Modules

Linux Authenticated Scanner

Build on the current SSH executor, but move it behind a scanner interface.

Capabilities:

  • Password and private-key SSH auth.
  • Host key verification policy.
  • Remote script execution with cleanup.
  • Command timeout and cancellation.
  • Structured result parsing for PatchHound ingestion.
  • Localhost/loopback guard unless explicitly allowed.

Windows Authenticated Scanner

Add a Windows scanner module for:

  • WMI/CIM queries.
  • Registry queries.
  • SMB-backed registry access where required.
  • NTLM, Kerberos, and Negotiate options if supported by the deployment model.
  • Query-level timeouts and target-level partial failures.
  • Normalized result rows for software, services, OS, installed updates, and vulnerability evidence.

This module may be Windows-only at runtime. The host should expose capabilities so the API does not assign unsupported commands to a runner.

Network Discovery and SNMP Scanner

Add modules for:

  • Target range expansion and validation.
  • ICMP/TCP liveness checks where permitted.
  • ARP/MAC enrichment when available on the host OS.
  • SNMP v1/v2 community and SNMPv3 auth/privacy support.
  • Target-level success/failure records.

Active Protocol Scanner

Add a safe active scanner module for selected protocols, gated by profile configuration:

  • HTTP/HTTPS/TLS banner and certificate collection.
  • SSH/FTP/Telnet banners.
  • SNMP probing.
  • Optional industrial protocol probes only when explicitly enabled by policy.
  • Global and per-target concurrency limits.
  • safe mode defaults that avoid intrusive behavior.

Backend/API Work Required

  • Extend runner registration to include capabilities, OS, version, hostname, and deployment metadata.
  • Replace one-job polling with command polling that can return typed scanner commands.
  • Add command/result chunk tables or extend existing scan job tables to support partial output and target-level records.
  • Add scheduler/dispatcher logic that only assigns commands to compatible runners.
  • Integrate Puppy result chunks with the existing ingestion flow so assets, software, vulnerabilities, and scan evidence are normalized into PatchHound entities.
  • Add audit events for registration, command assignment, command completion, failed command, and runner capability changes.

Packaging and Operations

  • Support single-file publish for Linux and Windows.
  • Provide sample runner.yaml for development, but allow environment-variable overrides for deployment.
  • Provide systemd unit guidance for Linux.
  • Provide Windows Service install guidance for Windows runners.
  • Include health endpoints or local diagnostics where practical.
  • Keep auto-update out of scope for the first v2 implementation unless a separate PatchHound-managed updater design is approved.

Security Requirements

  • No dependency on Defender onboarding, Defender registry keys, Defender certificates, Defender cloud endpoints, or Defender-specific auth flows.
  • Runner credentials must be PatchHound-issued and revocable.
  • Secrets must be redacted from all logs and result payloads.
  • Host key verification must be explicit; insecure modes must be opt-in and auditable.
  • Commands must be scoped to tenant and runner assignment.
  • Runner must reject commands for unsupported capabilities.
  • Result uploads must be associated with the assigned command and runner.
  • Scanner errors must not leak credential material.

Acceptance Criteria

  • PatchHound.Puppy has a clear modular architecture with host, API client, command processing, output sink, secret resolution, and scanner modules.
  • The runner no longer assumes any Defender/MDE/Sense registry, cloud, certificate, ETW, or updater dependency.
  • The runner advertises scanner capabilities during registration/heartbeat.
  • PatchHound API assigns only compatible commands to a runner.
  • Linux SSH scanning still works through the new scanner boundary.
  • At least one Windows authenticated scanner path is implemented or stubbed behind a capability-gated module with tests proving unsupported platforms are not assigned Windows commands.
  • Network/SNMP and active protocol scanner contracts are defined even if implementation is staged.
  • Result chunking supports partial target results, terminal EOF, and command-level completion.
  • Failed targets and scanner exceptions are returned as structured results.
  • Runner shutdown drains active work up to a bounded timeout.
  • Unit tests cover command dispatch, output chunking, runner capability matching, secret redaction, and scanner failure handling.
  • Integration tests cover API polling, command lease heartbeat, result upload, and completion flow with mocked scanner modules.

Suggested Implementation Slices

  1. Define PatchHound-native runner command/result contracts.
  2. Refactor current Puppy SSH flow behind scanner and command processor interfaces.
  3. Add output sink with chunked result upload and EOF completion.
  4. Extend backend runner API for capabilities and typed commands.
  5. Add scheduler/dispatcher compatibility checks.
  6. Add Linux scanner parity tests for the current behavior.
  7. Add Windows scanner module boundary and first WMI/registry implementation slice.
  8. Add network discovery/SNMP scanner contracts and initial implementation.
  9. Add active protocol scanner contracts with safe-mode defaults.
  10. Add service packaging docs for systemd and Windows Service.

Out of Scope

  • Defender/MDE compatibility.
  • Defender cloud registration or cluster URL resolution.
  • Defender certificate migration or certificate copier behavior.
  • ETW-specific result output as the primary telemetry channel.
  • Microsoft Key Vault as a required secret source.
  • Auto-update via MSI download/signature validation. A PatchHound-managed updater can be designed separately.

Additional Context

Source analysis file: D:\scanner-reversed\reconstruction-spec.md

Current Puppy files:

  • src/PatchHound.Puppy/Program.cs
  • src/PatchHound.Puppy/RunnerWorker.cs
  • src/PatchHound.Puppy/ApiClient.cs
  • src/PatchHound.Puppy/SshJobExecutor.cs
  • src/PatchHound.Puppy/ApiModels.cs

Related authenticated scan planning docs:

  • docs/superpowers/specs/2026-04-06-authenticated-scans-plan2-design.md
  • docs/superpowers/plans/2026-04-06-authenticated-scans-02-scheduler-runner-api.md
  • docs/superpowers/plans/2026-04-06-authenticated-scans-03-scan-runner-binary.md

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions