# AttackTracer Ninja V2 Repo Plan ## Purpose This document turns the V2 architecture into a concrete repository refactor plan. It answers: - which existing components should be removed or deprecated - which new components should be created - how the client package should be structured - what the n8n webhook contract should look like - in which order the migration should happen ## Target result The repository should end up centered around one endpoint client package that: - runs on every managed Windows device - writes NinjaOne device fields locally - uploads signed JSON reports to n8n - can be installed and updated from NinjaOne using GitLab-hosted release artifacts The repository should no longer rely on: - share mirroring - a central `AttackTracerNinjaServer` - organization aggregation on a Windows endpoint ## Existing components to remove or deprecate ## Remove from active architecture These should be retired from the primary product path: - `scripts/build-attacktracer-org-report.ps1` - `installer/runtime-build-attacktracer-org-report.ps1` - `scripts/run-attacktracer-ninja-server.ps1` - `installer/runtime-run-attacktracer-ninja-server.ps1` - `scripts/build-attacktracer-server-installer.ps1` - `installer/server-install-attacktracer-ninja-server.ps1` - `installer/server-uninstall-attacktracer-ninja-server.ps1` - `installer/AttackTracerNinjaServerBootstrapper/*` - `docs/attacktracer-ninja-server.md` - share-based org-report playbook content in `docs/ninjaone-org-report-playbook.md` ## Keep only as legacy reference These can remain temporarily during migration but should be clearly marked legacy: - `scripts/run-attacktracer-ninja-monitor.ps1` - `scripts/run-attacktracer-ninja.ps1` - `docs/ninjaone-monitoring-playbook.md` - `config/attacktracer-settings.example.json` ## Existing components to preserve and refactor These are still valuable and should become the base for V2: - `src/AttackTracerNinjaCli/AttackScanner.cs` - `src/AttackTracerNinjaCli/VulnerabilityCorrelation.cs` - `src/AttackTracerNinjaCli/Models.cs` - `src/AttackTracerNinjaCli/JsonOptions.cs` - `src/AttackTracerNinjaCli/Program.cs` - `src/AttackTracerNinjaCli/ScanOptions.cs` Core scanning logic should remain in C#. ## New repository structure Recommended target layout: ```text src/ AttackTracerNinjaCli/ AttackTracerNinjaCli.csproj Commands/ ScanCommand.cs UploadCommand.cs ScanAndUploadCommand.cs VersionCommand.cs Security/ HmacSigner.cs NonceStore.cs ProtectedSecretStore.cs Transport/ N8nUploadClient.cs UploadEnvelopeBuilder.cs Models/ ReportEnvelope.cs ScanReport.cs UploadResult.cs Configuration/ ClientConfiguration.cs ConfigurationLoader.cs scripts/ install-attacktracer-ninja.ps1 uninstall-attacktracer-ninja.ps1 update-attacktracer-ninja.ps1 run-attacktracer-ninja.ps1 publish-ninja-fields.ps1 config/ attacktracer-client.example.json update-channel.example.json docs/ attacktracer-ninja-v2-architecture.md attacktracer-ninja-v2-repo-plan.md attacktracer-ninja-v2-n8n-contract.md attacktracer-ninja-v2-deployment.md build/ build-client-package.ps1 build-release-manifest.ps1 samples/ webhook-payload.example.json version.example.json ``` ## New endpoint client responsibilities ## Binary responsibilities The compiled client should do these jobs: - local attack scanning - vulnerability correlation - JSON report generation - report signing - authenticated upload to n8n - stable exit codes - machine-readable output for NinjaOne wrappers ## Wrapper responsibilities PowerShell wrappers should only do: - install/uninstall - update - local config bootstrap - invoking the binary - publishing NinjaOne device custom fields - logging wrapper-level failures ## New client command model Recommended commands: ### `scan` Performs local scan and writes a report file. Example: ```powershell AttackTracerNinjaCli.exe scan --output "C:\ProgramData\AttackTracerNinja\reports\latest.json" --ninja-output ``` ### `upload` Uploads an existing report to n8n. Example: ```powershell AttackTracerNinjaCli.exe upload --report "C:\ProgramData\AttackTracerNinja\reports\latest.json" ``` ### `scan-and-upload` Performs a scan and directly uploads the result. Example: ```powershell AttackTracerNinjaCli.exe scan-and-upload --output "C:\ProgramData\AttackTracerNinja\reports\latest.json" --ninja-output ``` ### `version` Prints installed version and build metadata. ## Config model Recommended local config file: - `C:\ProgramData\AttackTracerNinja\config\attacktracer-client.json` Recommended fields: ```json { "schemaVersion": "2.0", "environment": "production", "lookbackDays": 7, "topFindings": 10, "n8nWebhookUrl": "https://n8n.example.com/webhook/attacktracer-ingest", "deviceIdentifierMode": "machineName", "uploadTimeoutSeconds": 30, "enableVulnerabilityCorrelation": true, "vulnerabilityCsvPath": "", "secretReference": "device-default" } ``` Secrets should not be stored here in clear text. ## Local secret handling plan ## Secret storage Create a protected local secret file under: - `C:\ProgramData\AttackTracerNinja\secrets\upload-secret.dat` Use DPAPI machine protection to encrypt the secret. ## Secret bootstrap Initial rollout options: 1. NinjaOne install task writes a tenant token once and immediately protects it with DPAPI. 2. Later evolution: unique per-device secret issued centrally. Recommended first cut: - tenant-level ingest secret wrapped with DPAPI - HMAC signature over request metadata + payload hash ## n8n webhook contract ## Endpoint request Method: - `POST` URL: - provided via config, for example: - `https://n8n.example.com/webhook/attacktracer-ingest` Headers: - `Content-Type: application/json` - `X-ATN-Device` - `X-ATN-Timestamp` - `X-ATN-Nonce` - `X-ATN-Version` - `X-ATN-Payload-SHA256` - `X-ATN-Signature` Body: - JSON scan report only Signature input recommendation: ```text device + "\n" + timestamp + "\n" + nonce + "\n" + version + "\n" + payloadSha256 ``` Algorithm: - `HMAC-SHA256` ## n8n validation rules n8n should reject when: - any required header is missing - timestamp is outside tolerance - nonce already exists - payload hash mismatches body - signature mismatches - schema is invalid ## Suggested report payload schema ```json { "schemaVersion": "2.0", "machineName": "WSUS", "generatedAtUtc": "2026-07-16T19:12:00Z", "clientVersion": "2.0.0", "baseStatus": "ok", "alertState": "ok", "totalEvents": 0, "uniqueIpCount": 0, "errorCount": 0, "attackFindings": [], "vulnerabilityCorrelation": { "totalCount": 0, "criticalCount": 0, "highCvssCount": 0 }, "runtime": { "startedAtUtc": "2026-07-16T19:11:57Z", "finishedAtUtc": "2026-07-16T19:12:00Z", "uploadAttempted": true } } ``` ## GitLab release plan ## Release artifacts Each release should publish: - `AttackTracerNinjaClient-win-x64.zip` - `AttackTracerNinjaClient-win-x64.zip.sha256` - `version.json` ## ZIP layout ```text AttackTracerNinjaClient-win-x64.zip app/ AttackTracerNinjaCli.exe AttackTracerNinjaCli.dll scripts/ install-attacktracer-ninja.ps1 uninstall-attacktracer-ninja.ps1 update-attacktracer-ninja.ps1 run-attacktracer-ninja.ps1 publish-ninja-fields.ps1 config/ attacktracer-client.example.json VERSION.txt ``` ## Manifest format ```json { "channel": "stable", "version": "2.0.0", "artifactUrl": "https://gitlab.example.com/group/project/-/releases/v2.0.0/downloads/AttackTracerNinjaClient-win-x64.zip", "sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", "publishedAtUtc": "2026-07-16T19:15:00Z" } ``` ## NinjaOne task model ## Task A: install/update client Runs as SYSTEM. Responsibilities: - fetch `version.json` - compare with local version - download artifact when newer - verify SHA-256 - verify Authenticode signature on executable - install or update package ## Task B: run scan Runs as SYSTEM on each endpoint. Responsibilities: - invoke `run-attacktracer-ninja.ps1` - publish device custom fields - trigger upload to n8n ## Device custom field path Keep the current device-level field strategy. Wrappers should continue using: - `Ninja-Property-Set` when available - Ninja CLI fallback if needed Fields to preserve: - `attacktracerstatus` - `attacktracerreason` - `attacktracerbasestatus` - `attacktracerevents` - `attacktraceruniqueips` - `attacktracercvecritical` - `attacktracercvetotal` - `attacktracermode` - `attacktracertriggered` - `attacktracerlastscanutc` ## Concrete code refactor plan ## Step 1: isolate scan model Refactor current CLI so scan output is represented by one stable report class. Create: - `Models/ScanReport.cs` Move report shape ownership there. ## Step 2: add transport layer Create: - `Transport/N8nUploadClient.cs` - `Transport/UploadEnvelopeBuilder.cs` Responsibilities: - prepare headers - hash payload - sign request - upload with timeout and retry policy ## Step 3: add secret protection Create: - `Security/ProtectedSecretStore.cs` Responsibilities: - store secret using DPAPI - load secret at runtime ## Step 4: add nonce/replay support Create: - `Security/NonceStore.cs` Local nonce history is optional, but useful for diagnostics. ## Step 5: split commands Refactor `Program.cs` into command-oriented classes: - `ScanCommand.cs` - `UploadCommand.cs` - `ScanAndUploadCommand.cs` - `VersionCommand.cs` ## Step 6: simplify wrappers Replace older server/share assumptions in wrappers. `run-attacktracer-ninja.ps1` should become: - invoke binary - capture output - write Ninja device fields - exit with monitoring-friendly code ## Step 7: replace build pipeline Create: - `build/build-client-package.ps1` - `build/build-release-manifest.ps1` Deprecate: - heavy installer-first flow if ZIP distribution is enough ## Step 8: deprecate server package Mark these as legacy and remove from active release build: - `AttackTracerNinjaServer*` - org HTML writer logic - share mirroring flow ## Implementation order ## Phase A: repo cleanup and design freeze 1. Mark server/share docs as legacy 2. Add new config and payload docs 3. Freeze V2 JSON schema ## Phase B: client refactor 1. Add command split 2. Add signed upload path 3. Add DPAPI secret handling 4. Keep existing scan logic intact ## Phase C: packaging 1. Build ZIP package 2. Build version manifest 3. Add install/update scripts ## Phase D: central integration 1. Build n8n ingest workflow 2. Build Postgres schema 3. Build NinjaOne org-field update workflow ## Phase E: rollout 1. Pilot group 2. Validate cadence and missing-report detection 3. Roll out widely 4. Retire server/share path ## Final recommendation Implement V2 as: - compiled endpoint collector - PowerShell operational wrapper - GitLab-hosted signed releases - NinjaOne-based deployment and update - n8n-based central ingestion and org aggregation This gives a cleaner codebase and a safer operational model than extending the old share/server architecture further.