Skip to content

enhancement: sync main to NinjaRMM with custom-field-based script mapping #56

Description

@Gumbees

Problem

The current delivery model couples dtc-inc/msp-script-library and NinjaRMM via raw URL strings. Ninja scripts have URLs pointing at raw.githubusercontent.com/.../main/..., and the mapping of "which Ninja script corresponds to which repo path" lives only in those URLs (and the Ninja UI). Drift between repo state and Ninja state is invisible.

Proposal — C: Sync main → NinjaRMM, link scripts via a Ninja custom field

Move the source-of-truth coupling out of URL strings and into an explicit sync layer.

Mechanics:

  1. Each .ps1 in the repo gets a corresponding script entry in Ninja.
  2. A NinjaRMM custom field on the script entry holds the canonical repo path (e.g. sec-huntress/HuntressAgentInstall.ps1) plus the version / SHA that was last synced.
  3. A GitHub Action (or scheduled job) on every push to main walks the repo, finds the matching Ninja script via the custom field, and updates Ninja's script content via Ninja's API.
  4. Scripts deleted from the repo get flagged in Ninja (don't auto-delete ... operator decides).

What this unblocks:

  • Explicit mapping ... Ninja script -> repo path is queryable, not buried in URL strings.
  • Ninja-side controls work normally ... Ninja's role-based access, scheduling, parameterization, monitoring all apply to the live script.
  • Atomic deployments ... can stop the sync if a regression ships; rollback is git revert + re-sync.
  • Drift detection ... compare custom field SHA to current main HEAD ... mismatches are visible.

Trade-offs / risks

  • NinjaRMM API capability ... need to confirm Ninja's API exposes "update script content" and "read/write custom fields on script entries." Worth checking before scoping further.
  • Sync direction is one-way ... edits made in Ninja's UI get overwritten on next sync. That's the right default (repo is canonical) but operator habits may need to shift.
  • Drift recovery ... if the sync job fails silently for a week, repo and Ninja diverge until someone notices. Need monitoring + alerting on the sync job.
  • Mapping bootstrap ... someone has to stamp every existing Ninja script with the custom field once. One-off but tedious.

Scope

  • Confirm Ninja API supports script-content writes + script-custom-field reads/writes (Ninja docs check, then validate via a curl).
  • Design the custom-field schema (script ID? path? SHA? version?).
  • Decide the sync trigger: push-to-main GHA, or scheduled job, or both.
  • Build the sync job (GHA workflow + script).
  • Bootstrap mapping ... script that stamps existing Ninja scripts with the custom field by matching URL patterns to repo paths.
  • Add monitoring / alerting on sync-job health.
  • Document the new deployment model in README + CLAUDE.md.

Relationship to issues A + B

  • vs A (jsDelivr) ... C bypasses URL-based delivery entirely. They're mutually exclusive directions for the script-delivery model. C is heavier engineering up-front but better long-term observability + control.
  • vs B (vendor-download integrity) ... orthogonal. B can ship inside whatever delivery model is chosen.

Branch / labels

  • Branch prefix: enhancement/ninja-sync
  • Likely largest engineering effort of the three; can be staged across milestones.

Metadata

Metadata

Assignees

No one assigned

    Labels

    category:featureNet-new capability the customer/operator didn't havetype:enhancementNew work that adds or improves capability (Halo: Enhancement)

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions