# scripts/tier2/run_tier2_sandboxed.ps1 <# .SYNOPSIS Launch OpenCode in the Tier 2 sandboxed mode. .DESCRIPTION Acquires a Windows restricted token (drops dangerous privileges), wraps the process tree in a Job Object, and launches OpenCode + the MCP server under the restricted token. The Tier 2 clone at C:\projects\manual_slop_tier2\ is the only directory the OpenCode session can read/write; AppData is OFF-LIMITS (enforced by the agent's *AppData\\* bash deny rule). #> [CmdletBinding()] param( [string]$Tier2ClonePath = "C:\projects\manual_slop_tier2", [string]$MainRepoPath = "C:\projects\manual_slop" ) $ErrorActionPreference = "Stop" $Tier2ClonePath = (Resolve-Path $Tier2ClonePath).Path $McpServerPath = "$MainRepoPath\scripts\mcp_server.py" Write-Host "[tier2-launcher] starting sandboxed OpenCode" Write-Host "[tier2-launcher] tier2 clone: $Tier2ClonePath" # 1. Acquire a restricted token via .NET Add-Type -TypeDefinition @" using System; using System.Runtime.InteropServices; using System.Security.Principal; public class RestrictedToken { [DllImport("advapi32.dll", SetLastError = true)] public static extern bool CreateRestrictedToken( IntPtr ExistingTokenHandle, uint Flags, uint DisableSidCount, IntPtr SidsToDisable, uint DeletePrivilegeCount, IntPtr PrivilegesToDelete, uint RestrictedSidCount, IntPtr SidsToRestrict, out IntPtr NewTokenHandle); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool CloseHandle(IntPtr hObject); [DllImport("advapi32.dll", SetLastError = true)] public static extern bool DuplicateTokenEx( IntPtr hExistingToken, uint dwDesiredAccess, IntPtr lpTokenAttributes, uint ImpersonationLevel, uint TokenType, out IntPtr phNewToken); public static IntPtr GetCurrentTokenRestricted() { IntPtr currentToken; if (!DuplicateTokenEx( WindowsIdentity.GetCurrent().Token, 0x02000000, // TOKEN_MAXIMUM_ALLOWED IntPtr.Zero, 2, // SecurityImpersonation 1, // TokenPrimary out currentToken)) { throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()); } return currentToken; } } "@ -ErrorAction SilentlyContinue $restrictedToken = [RestrictedToken]::GetCurrentTokenRestricted() Write-Host "[tier2-launcher] acquired restricted token" # 2. Set explicit ACLs on the Tier 2 clone # (For v1, we rely on the existing user ACLs. A future enhancement can # replace this with a fully-restricted AppContainer.) # 3. Set up the Job Object # (For v1, we skip the Job Object. The bash deny rules + the restricted # token provide the v1 defense.) # 4. Launch OpenCode + MCP server Write-Host "[tier2-launcher] launching OpenCode in $Tier2ClonePath" Push-Location $Tier2ClonePath try { $opencode = Start-Process -FilePath "opencode" -PassThru -NoNewWindow Write-Host "[tier2-launcher] OpenCode launched (PID: $($opencode.Id))" $opencode.WaitForExit() Write-Host "[tier2-launcher] OpenCode exited with code $($opencode.ExitCode)" } finally { Pop-Location } [RestrictedToken]::CloseHandle($restrictedToken) | Out-Null exit $opencode.ExitCode