Skip to main content

Asset Heartbeat Ingestion v1

Status

Implemented as a narrow ingestion foundation. Full asset discovery is not implemented.

  • SRS references: RMM asset inventory and unmanaged device visibility.
  • Client response references: agents/connectors run inside tenant environments; active/passive discovery is Phase 1 but requires separate authorization contracts.
  • ADR references: asset discovery contracts and platform stack ADR.
  • Task board references: OP-026, OP-030, OP-011, OP-035.

Problem Statement

OneProtect needs the first real path from tenant-scoped asset signals into the canonical asset read model without jumping directly into scanners or agent runtime complexity.

Architectural Intent

Asset discovery remains event-driven. Heartbeat ingestion emits valid asset events, projections update tenant-scoped read models, and the UI/API show the resulting asset state.

What Was Implemented

  • Minimal heartbeat ingestion source.
  • Event-driven projection for asset and collector read models.
  • last_seen updates for assets and collectors.
  • Deterministic merge behavior that preserves stronger identifiers.
  • Safe IP/interface updates.
  • Narrow unmanaged/unauthorized detection using existing alert/evidence/audit foundations.
  • Asset APIs and lightweight Assets console rendering real ingested fields.
  • Agent-enrolled assets are marked managed through the verified agent_identities binding even when there is no separate approved_inventory allowlist row. The allowlist remains the trust check for agentless/unknown discovery observations.

Components Involved

  • poc/ingest_api/asset_heartbeat_ingestion.py
  • poc/ingest_api/asset_read_model.py
  • poc/ingest_api/rule_evaluation.py
  • Asset storage migration under db/postgres/
  • Assets console page.

APIs / Events / Schemas

  • GET /api/v1/assets
  • GET /api/v1/assets/{asset_id}
  • GET /api/v1/assets/{asset_id}/timeline
  • GET /api/v1/collectors
  • GET /api/v1/commands
  • Events include agent.enrolled, collector.enrolled, asset.discovered, asset.updated, asset.classified, asset.fingerprint.updated, and asset.telemetry.received.

Deployment Notes

This runs through the existing API, worker/event, and Postgres paths. It does not require osquery, Fleet, Nmap, SNMP, WMI, or NetFlow runtime.

Security / Tenant Isolation

  • Asset tables are tenant-owned and RLS-protected.
  • Projections use tenant-scoped event envelopes.
  • Duplicate events remain idempotent.
  • Unmanaged detection uses existing alert/evidence/audit path.
  • Agent-backed heartbeat data must not be treated as an unauthorized discovery solely because no approved_inventory row exists; the enrolled or active agent identity is the tenant-scoped management proof.

Validation Steps

UI Validation

  1. Trigger asset ingestion using the smoke target.
  2. Open /console/assets.
  3. Confirm hostname, classification, lifecycle state, last seen, source confidence, collector, and source type are visible when available.
  4. Confirm enrolled/heartbeating agents show as managed even with no approved inventory row.
  5. Confirm unmanaged/unauthorized state appears for the narrow detection rule only for agentless or untrusted discovery observations.

API Validation

curl -H "Authorization: Bearer <tenant-token>" \
http://127.0.0.1:8000/api/v1/assets

Smoke Validation

make test-asset-storage
make test-asset-ingestion
make smoke-asset-ingestion

Known Limitations

  • No real collector runtime.
  • No osquery/Fleet/OTel integration.
  • No network scanning, SNMP, WMI, DHCP, ARP, or NetFlow ingestion.
  • No topology mapping.
  • No command execution.

Follow-Up Work

  • Freeze agent enrollment and mTLS contracts.
  • Implement active/passive discovery runtime from ADR-0012 after safety-limit, redaction, and source-confidence tests exist.
  • Add approved collector runtimes after contracts are accepted.

Acceptance Criteria Mapping

Acceptance criterionEvidence
Heartbeat creates/updates assetsmake test-asset-ingestion
last_seen updates safelyIngestion tests
Strong identifiers are preservedMerge/confidence tests
Assets are visible through API/UIAssets APIs and /console/assets
Enrolled agents are managed inventoryAPI returns management_status=managed and agent_managed=true after heartbeat