security(discovery): enforce Zone isolation and retire unsafe legacy writers

Bind Agent observations, review, enrichment and telemetry to current Zone
and inventory authority. Preserve immutable MAC ownership and historical
snapshots with stale-result rejection and transactional security audits.

Retire unbound direct/range/scheduled discovery and one/bulk legacy summary
writes in both modes. Require reconciled exact inventory identity or
explicit Zone-scoped IP selection for CSV metadata imports.

Independent Blocker #1 application-security re-audit: PASS on tree
cf863aadc9. Evidence: 141 focused PostgreSQL/HTTP
tests passed; Chromium and PowerShell checks passed. Two documented baseline
source assertions remain unchanged. Production deployment is not approved.
This commit is contained in:
lussierj committed 2026-10-17 00:45:04 +00:00
1 parent e898f283ab
commit 8b0d32cd6b
26 files changed
+3798 -4092

No files matched your search

+23 -2
View File
@@ -58,6 +58,21 @@ function Invoke-AgentApi {
"X-MinerOps-Agent-ID" = [string]$config.agent_id
}
$batchField = $null
if ($Path -eq "/api/agent/miner-snapshots") { $batchField = "miners" }
elseif ($Path -eq "/api/agent/discoveries") { $batchField = "discoveries" }
if ($batchField -and $Body -ne $null -and @($Body[$batchField]).Count -gt 128) {
$items = @($Body[$batchField])
$results = @()
for ($offset = 0; $offset -lt $items.Count; $offset += 128) {
$batch = @{}
foreach ($key in $Body.Keys) { $batch[$key] = $Body[$key] }
$last = [Math]::Min($offset + 127, $items.Count - 1)
$batch[$batchField] = @($items[$offset..$last])
$results += Invoke-AgentApi -Method $Method -Path $Path -Body $batch
}
return @{ ok = $true; batches = $results; processed = $items.Count }
}
if ($Body -ne $null) {
$json = $Body | ConvertTo-Json -Depth 100 -Compress
return Invoke-RestMethod -Method $Method -Uri $uri -Headers $headers -ContentType "application/json" -Body $json -TimeoutSec 180
@@ -252,6 +267,7 @@ function Poll-KnownMiners {
$result = [ordered]@{
miner_id = [string]$Miner.miner_id
miner_version = [string]$Miner.miner_version
ip_address = [string]$Miner.ip_address
mac_address = [string]$Miner.mac_address
room_name = [string]$Miner.room_name
@@ -592,7 +608,7 @@ public static class MinerOpsFastScanner {
}
function Discover-MinersInRanges {
$config = Read-AgentConfig
$config = Invoke-AgentApi -Method "GET" -Path "/api/agent/config"
$ranges = @($config.ip_ranges | Where-Object { $_.enabled -eq $true })
Ensure-FastScannerLoaded
@@ -1015,7 +1031,12 @@ function Process-PendingCommands {
Write-AgentLog "Running Enrich / Match for discovery IP $ipAddress"
$out = powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\MinerOpsAgent\EnrichOneMiner.ps1 -IpAddress $ipAddress 2>&1 | Out-String
$hubConfig = Invoke-AgentApi -Method "GET" -Path "/api/agent/config"
if (-not [string]::Equals([string]$payloadObj.agent_zone_id, [string]$hubConfig.agent_zone_id, [StringComparison]::Ordinal)) {
throw "discovery_command_stale_authority"
}
if (-not $payloadObj.discovery_id -or -not $payloadObj.version) { throw "discovery_observation_required" }
$out = powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\MinerOpsAgent\EnrichOneMiner.ps1 -IpAddress $ipAddress -DiscoveryId ([string]$payloadObj.discovery_id) -ObservationVersion ([string]$payloadObj.version) -CommandId $commandId 2>&1 | Out-String
if ($LASTEXITCODE -ne 0) {
throw "EnrichOneMiner failed for $ipAddress. Output: $out"