$ErrorActionPreference = "Stop" $root = Split-Path $PSScriptRoot -Parent $bootstrap = Join-Path $root "Enroll-MinerOpsAgent.ps1" $tokens = $null $parseErrors = $null [System.Management.Automation.Language.Parser]::ParseFile( $bootstrap, [ref] $tokens, [ref] $parseErrors ) | Out-Null if ($parseErrors.Count -gt 0) { throw "Enroll-MinerOpsAgent.ps1 parser errors: $($parseErrors.Message -join '; ')" } $source = Get-Content -LiteralPath $bootstrap -Raw function Assert-SourceContains { param( [Parameter(Mandatory)][string] $Pattern, [Parameter(Mandatory)][string] $Message ) if ($source -notmatch $Pattern) { throw $Message } } Assert-SourceContains 'enrollment\.json' ` "Bootstrap enrollment file is not explicit." Assert-SourceContains '/api/agent/enroll' ` "Bootstrap does not use the secure enrollment endpoint." Assert-SourceContains 'Read-Host[\s\S]*-AsSecureString' ` "API3 password is not prompted as a SecureString." Assert-SourceContains 'agent-config\.json\.pending' ` "Atomic pending config path is missing." Assert-SourceContains 'agent-config\.recovery\.json' ` "Post-redemption credential recovery path is missing." Assert-SourceContains 'Protect-MinerOpsCredentialFile' ` "Credential file ACL protection is missing." Assert-SourceContains 'S-1-5-18' ` "SYSTEM ACL entry is missing." Assert-SourceContains 'S-1-5-32-544' ` "Administrators ACL entry is missing." Assert-SourceContains 'WindowsIdentity\]::GetCurrent\(\)\.User' ` "Installing user ACL entry is missing." Assert-SourceContains 'Move-Item[\s\S]*\$ConfigPath' ` "Atomic final config move is missing." Assert-SourceContains '& \$Installer' ` "Bootstrap does not hand off to the safe installer." Assert-SourceContains 'Start-ScheduledTask -TaskName "MinerOpsAgent"' ` "Fresh Agent startup is missing." Assert-SourceContains 'Remove-Item -LiteralPath \$EnrollmentPath' ` "Consumed extracted enrollment token is not removed." $existingConfigGuard = $source.IndexOf( 'Test-Path -LiteralPath $ConfigPath' ) $redeemCall = $source.IndexOf( '"$HubUrl/api/agent/enroll"' ) if ( $existingConfigGuard -lt 0 -or $redeemCall -lt 0 -or $existingConfigGuard -gt $redeemCall ) { throw "Existing Agent identity must be rejected before token redemption." } $configMove = $source.IndexOf( '-Destination $ConfigPath' ) $installerCall = $source.IndexOf( '& $Installer' ) if ( $configMove -lt 0 -or $installerCall -lt 0 -or $configMove -gt $installerCall ) { throw "Permanent Agent credentials must be persisted before installation." } foreach ($sensitiveVariable in @( 'EnrollmentToken', 'Api3PasswordPlain' )) { if ( $source -match ( '(?im)Write-(Host|Output|Verbose|Information).*?\$' + $sensitiveVariable ) ) { throw "$sensitiveVariable must not be written to output." } } Write-Host "MinerOps enrollment bootstrap source safety tests passed."