Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

9.7 KiB

Scratchpad — Tanium Criticality Asset Facts

  • Plan slug: tanium-criticality-asset-facts
  • Created: 2026-04-29

What This Is

Working notes for adding CE asset facts and using them as the Tanium criticality display/persistence surface.

Decisions

  • (2026-04-29) Use the term facts for asset metadata that is observed/synced from a provider or system. Rationale: it avoids implying a full custom-fields platform while preserving a path to queryable workflow/AI/filtering consumers.
  • (2026-04-29) Put the generic asset_facts data structure in CE/base migrations, not EE-only. Rationale: integrations can remain feature-gated, but the neutral data primitive should be available broadly.
  • (2026-04-29) Keep Tanium criticality provider-sourced and read-only for day one. Do not promote it to a first-class Alga asset column yet.
  • (2026-04-29) Fetch Tanium criticality separately from the main endpoint inventory query. Rationale: Gateway returns errors when a requested sensor is unavailable, and missing Criticality content-set access should not break normal inventory sync.
  • (2026-04-29) Use Tanium Endpoint Criticality with Level, not just Endpoint Criticality, because Alga needs display text in addition to any numeric multiplier.
  • (2026-04-29) If global criticality enrichment fails for a scope, leave existing facts untouched. If an endpoint explicitly returns no result, mark that endpoint fact unavailable and preserve raw metadata.
  • (2026-04-29) Day-one UI should only display an available Tanium Criticality fact; no generic editable custom/facts UI in this phase.

Discoveries / Constraints

  • (2026-04-29) Existing Tanium sync already has a best-effort separate sensor enrichment pattern for Last Reboot in ee/server/src/lib/integrations/tanium/taniumGatewayClient.ts.
  • (2026-04-29) Existing shared RMM ingestion returns assetId for created/updated assets, which is the right point to upsert facts.
  • (2026-04-29) Existing normalized RMM extension fields and system_info are useful for raw provider metadata, but are not a good long-term query surface for workflows/AI/filtering.
  • (2026-04-29) Tanium developer docs browser pane a4169d08-2203-48d1-8845-330185626c87 showed Endpoint Criticality and Endpoint Criticality with Level in Sensor Inventory, not as first-class Endpoint GraphQL fields.
  • (2026-04-29) Tanium Sensor Inventory details found:
    • Endpoint Criticality: Criticality virtual sensor. Returns number of endpoints with each criticality. Multipliers: Low = 1, Medium = 1.33, High = 1.67, Critical = 2.
    • Endpoint Criticality with Level: Criticality virtual sensor. Returns number of endpoints with each endpoint criticality value and text.
  • (2026-04-29) Gateway schema supports arbitrary endpoint sensor reads through Endpoint.sensorReading(sensor: EndpointSensorRef!) and Endpoint.sensorReadings(sensors: [EndpointSensorRef!]!).
  • (2026-04-29) Gateway docs say sensorReading returns raw values and can return floatValues for numeric/integer conversion. For multi-column sensors, sensorReading requires exactly one column; sensorReadings should be used for multiple sensors/columns.
  • (2026-04-29) Gateway docs say unavailable sensors return query errors, reinforcing the separate best-effort enrichment design.

Commands / Runbooks

  • (2026-04-29) Scaffold plan:
    • python3 /Users/roberisaacs/.agents/skills/alga-plan/scripts/scaffold_plan.py --slug tanium-criticality-asset-facts "Tanium Criticality Asset Facts"
  • (2026-04-29) Inspect Tanium docs browser URL/content:
    • alga-dev browser-get-url --paneId=a4169d08-2203-48d1-8845-330185626c87 --pretty
    • alga-dev browser-eval --paneId=a4169d08-2203-48d1-8845-330185626c87 --script='(() => ({title: document.title, url: location.href, text: (document.body.innerText || "").slice(0, 12000)}))()'
  • (2026-04-29) Fetch Gateway schema text from authenticated browser pane:
    • alga-dev browser-eval --paneId=a4169d08-2203-48d1-8845-330185626c87 --script='(async () => (await fetch("/_spec-gql/apis/tanium_gateway_schema.graphql?download")).text())()'
  • (2026-04-29) Fetch Sensor Inventory page data from authenticated browser pane:
    • alga-dev browser-eval --paneId=a4169d08-2203-48d1-8845-330185626c87 --script='(async () => fetch("/page-data/sensor-inventory/sensor_list/data.json").then(r=>r.json()))()'
  • Tanium docs page used: https://developer.tanium.com/apis/api_intro
  • Tanium Gateway schema download path in authenticated browser: /_spec-gql/apis/tanium_gateway_schema.graphql?download
  • Tanium Sensor Inventory page data: /page-data/sensor-inventory/sensor_list/data.json
  • Existing Tanium client: ee/server/src/lib/integrations/tanium/taniumGatewayClient.ts
  • Existing Tanium actions/sync: ee/server/src/lib/actions/integrations/taniumActions.ts
  • Shared RMM contracts: packages/integrations/src/lib/rmm/contracts.ts
  • Shared RMM ingestion: packages/integrations/src/lib/rmm/sharedAssetIngestionService.ts
  • Prior design reference: ee/docs/plans/2026-04-15-tanium-asset-enrichment-design.md
  • Tanium integration plan reference: ee/docs/plans/2026-04-06-tanium-rmm-integration-plan/

Open Questions

  • What exact columns does Endpoint Criticality with Level return in customer tenants? Implementation should preserve raw columns and parse defensively.
  • Should future facts uniqueness include integration_id to support multiple providers/instances publishing same namespace/key for one asset? V1 plan uses one current fact per asset/source_type/namespace/key.
  • Should unavailable facts be exposed in a future admin/debug panel? Day one hides unavailable facts from primary asset detail.

Implementation Updates

  • (2026-04-29) Implemented CE/base migration server/migrations/20260429133000_create_asset_facts_table.cjs for asset_facts with:

    • tenant-aware PK (tenant, asset_fact_id),
    • tenant+asset FK to assets,
    • typed value columns + raw value_json,
    • availability + sync/source timestamps,
    • uniqueness on (tenant, asset_id, source_type, namespace, fact_key). Rationale: provides a neutral, queryable fact primitive while preserving Citus tenant key patterns.
  • (2026-04-29) Added shared asset fact typing and service:

    • AssetFact and AssetFactSourceType in packages/types/src/interfaces/asset.interfaces.ts.
    • server/src/lib/assets/assetFactsService.ts with upsertAssetFact(...) and listAvailableAssetFactsForAsset(...). Rationale: central reusable read/upsert behavior for provider-sourced facts with tenant+asset scoping.
  • (2026-04-29) Extended Tanium Gateway client (ee/server/src/lib/integrations/tanium/taniumGatewayClient.ts):

    • Added metadata lookup for Endpoint Criticality with Level.
    • Added paginated endpoint criticality sensor reading query via sensorReadings.
    • Added defensive parser that preserves raw columns, maps known labels to multipliers, and tolerates unknown columns.
  • (2026-04-29) Integrated best-effort criticality enrichment into triggerTaniumFullSync (ee/server/src/lib/actions/integrations/taniumActions.ts):

    • Criticality query runs separately from endpoint inventory query.
    • Global criticality failure logs warning and does not fail full sync.
    • Existing facts remain untouched on global failure.
    • For successful criticality query, endpoint with explicit no result is upserted unavailable.
    • Criticality fact upsert happens only after ingestion returns assetId.
    • Fact shape stored with source_type=integration, provider=tanium, namespace=tanium, fact_key=criticality, source metadata for sensor.
  • (2026-04-29) Added asset detail facts read path:

    • getAvailableAssetFacts(asset_id) in packages/assets/src/actions/assetActions.ts with tenant-scoped auth checks.
    • useAssetDetail now loads facts.
  • (2026-04-29) Added Tanium criticality UI rendering on asset detail (packages/assets/src/components/panels/RmmVitalsPanel.tsx):

    • Shows Tanium Criticality only when available Tanium criticality fact exists.
    • Known labels map to compact badge variants (Low/Medium/High/Critical).
    • Missing/unavailable facts are hidden.

Test Updates

  • (2026-04-29) Added/updated tests:

    • ee/server/src/__tests__/unit/integrations/taniumGatewayClient.test.ts
      • endpoint criticality parse coverage (known + unknown columns).
    • ee/server/src/__tests__/unit/integrations/taniumActions.test.ts
      • criticality enrichment isolation from sync failure,
      • upsert only when assetId exists,
      • leave existing facts untouched on global criticality failure.
    • packages/assets/src/components/panels/RmmVitalsPanel.test.tsx
      • renders Tanium criticality only when available fact exists.
  • (2026-04-29) Verification commands:

    • npx nx test sebastian-ee -- --run src/__tests__/unit/integrations/taniumGatewayClient.test.ts src/__tests__/unit/integrations/taniumActions.test.ts (pass)
    • npx nx test @alga-psa/assets -- --run src/components/panels/RmmVitalsPanel.test.tsx --reporter=verbose (our panel tests pass; suite still reports pre-existing unrelated failures in QuickAddAsset.quick-add-client.contract.test.ts and CreateTicketFromAssetButton.boardScopedStatuses.test.tsx).

Gotchas

  • (2026-04-29) EE action tests use withAuth wrappers directly; test invocations must pass explicit (user, { tenant }) args.
  • (2026-04-29) Asset package targeted test runs currently include additional files in this workspace, exposing unrelated baseline failures outside this change.
  • (2026-04-29) Added server/src/test/unit/assets/assetFactsService.test.ts to cover T001/T002/T003 service behaviors:
    • tenant-scoped insert/read,
    • uniqueness/upsert semantics for current fact key,
    • explicit unavailable upsert preserving raw metadata.
  • (2026-04-29) Verification command:
    • cd server && npx vitest run src/test/unit/assets/assetFactsService.test.ts (pass)