11 KiB
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.ps1installer/runtime-build-attacktracer-org-report.ps1scripts/run-attacktracer-ninja-server.ps1installer/runtime-run-attacktracer-ninja-server.ps1scripts/build-attacktracer-server-installer.ps1installer/server-install-attacktracer-ninja-server.ps1installer/server-uninstall-attacktracer-ninja-server.ps1installer/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.ps1scripts/run-attacktracer-ninja.ps1docs/ninjaone-monitoring-playbook.mdconfig/attacktracer-settings.example.json
Existing components to preserve and refactor
These are still valuable and should become the base for V2:
src/AttackTracerNinjaCli/AttackScanner.cssrc/AttackTracerNinjaCli/VulnerabilityCorrelation.cssrc/AttackTracerNinjaCli/Models.cssrc/AttackTracerNinjaCli/JsonOptions.cssrc/AttackTracerNinjaCli/Program.cssrc/AttackTracerNinjaCli/ScanOptions.cs
Core scanning logic should remain in C#.
New repository structure
Recommended target layout:
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:
AttackTracerNinjaCli.exe scan --output "C:\ProgramData\AttackTracerNinja\reports\latest.json" --ninja-output
upload
Uploads an existing report to n8n.
Example:
AttackTracerNinjaCli.exe upload --report "C:\ProgramData\AttackTracerNinja\reports\latest.json"
scan-and-upload
Performs a scan and directly uploads the result.
Example:
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:
{
"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:
- NinjaOne install task writes a tenant token once and immediately protects it with DPAPI.
- 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/jsonX-ATN-DeviceX-ATN-TimestampX-ATN-NonceX-ATN-VersionX-ATN-Payload-SHA256X-ATN-Signature
Body:
- JSON scan report only
Signature input recommendation:
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
{
"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.zipAttackTracerNinjaClient-win-x64.zip.sha256version.json
ZIP layout
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
{
"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-Setwhen available- Ninja CLI fallback if needed
Fields to preserve:
attacktracerstatusattacktracerreasonattacktracerbasestatusattacktracereventsattacktraceruniqueipsattacktracercvecriticalattacktracercvetotalattacktracermodeattacktracertriggeredattacktracerlastscanutc
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.csTransport/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.csUploadCommand.csScanAndUploadCommand.csVersionCommand.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.ps1build/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
- Mark server/share docs as legacy
- Add new config and payload docs
- Freeze V2 JSON schema
Phase B: client refactor
- Add command split
- Add signed upload path
- Add DPAPI secret handling
- Keep existing scan logic intact
Phase C: packaging
- Build ZIP package
- Build version manifest
- Add install/update scripts
Phase D: central integration
- Build n8n ingest workflow
- Build Postgres schema
- Build NinjaOne org-field update workflow
Phase E: rollout
- Pilot group
- Validate cadence and missing-report detection
- Roll out widely
- 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.