# ============================================================================ # Agent Audit - install bootstrap (Windows PowerShell) # # Usage: # iwr -useb https://www.agentaudit.co.uk/install.ps1 | iex # # What it does (in order): # 1. Verify Python 3.10+ and pip are present # 2. Create or reuse %USERPROFILE%\.agentaudit\venv # 3. pip install --upgrade agentaudit (inside the venv) # 4. Prompt for your API key (or read $env:AGENTAUDIT_API_KEY) # 5. Write %USERPROFILE%\.agentaudit\env with the key (ACL'd to current user) # 6. Send a test receipt and report whether the chain accepted it # # Re-running is safe. It only updates the SDK and re-verifies the chain. # Source: https://www.agentaudit.co.uk/download/ # ============================================================================ $ErrorActionPreference = 'Stop' function Say ($m) { Write-Host "==> $m" -ForegroundColor Blue } function Ok ($m) { Write-Host "[OK] $m" -ForegroundColor Green } function Warn ($m) { Write-Host "[!] $m" -ForegroundColor Yellow } function Err ($m) { Write-Host "[X] $m" -ForegroundColor Red } $AAHome = if ($env:AGENTAUDIT_HOME) { $env:AGENTAUDIT_HOME } else { Join-Path $env:USERPROFILE '.agentaudit' } $AAVenv = Join-Path $AAHome 'venv' $AAEnv = Join-Path $AAHome 'env' $AAIngest = 'https://www.agentaudit.co.uk' # --- 1. Python check -------------------------------------------------------- Say 'Checking Python' $python = $null foreach ($candidate in @('python', 'py', 'python3')) { if (Get-Command $candidate -ErrorAction SilentlyContinue) { $python = $candidate; break } } if (-not $python) { Err 'python is not on PATH. Install Python 3.10+ from https://python.org and re-run.' exit 1 } $pyv = & $python -c 'import sys; print("%d.%d" % sys.version_info[:2])' $parts = $pyv.Split('.') if ([int]$parts[0] -lt 3 -or ([int]$parts[0] -eq 3 -and [int]$parts[1] -lt 10)) { Err "Python 3.10+ required (found $pyv)." exit 1 } Ok "Python $pyv" # --- 2. Virtualenv --------------------------------------------------------- Say "Preparing virtualenv at $AAVenv" if (-not (Test-Path $AAHome)) { New-Item -ItemType Directory -Path $AAHome | Out-Null } # Restrict folder ACL to current user only $acl = Get-Acl $AAHome $acl.SetAccessRuleProtection($true, $false) $me = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name $rule = New-Object System.Security.AccessControl.FileSystemAccessRule( $me, 'FullControl', 'ContainerInherit, ObjectInherit', 'None', 'Allow' ) $acl.AddAccessRule($rule) Set-Acl -Path $AAHome -AclObject $acl if (-not (Test-Path $AAVenv)) { & $python -m venv $AAVenv Ok "Created $AAVenv" } else { Ok "Reusing $AAVenv" } $venvPython = Join-Path $AAVenv 'Scripts\python.exe' # --- 3. Install the SDK ---------------------------------------------------- Say 'Installing agentaudit' & $venvPython -m pip install --quiet --upgrade pip & $venvPython -m pip install --quiet --upgrade agentaudit $sdkVer = (& $venvPython -c 'import agentaudit; print(getattr(agentaudit, "__version__", "unknown"))' 2>$null) if (-not $sdkVer) { $sdkVer = 'unknown' } Ok "agentaudit $sdkVer installed" # --- 4. API key ------------------------------------------------------------ $key = $env:AGENTAUDIT_API_KEY if (-not $key -and (Test-Path $AAEnv)) { Get-Content $AAEnv | ForEach-Object { if ($_ -match '^\s*AGENTAUDIT_API_KEY\s*=\s*"?([^"]+)"?\s*$') { $key = $matches[1] } } } if (-not $key) { Say "Paste your API key (or get one at $AAIngest/dashboard/settings/keys/):" $secure = Read-Host ' API key' -AsSecureString $bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secure) $key = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr) [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr) | Out-Null } if ($key -notmatch '^aa_(live|test)_[A-Za-z0-9]{16,}$') { Err "That doesn't look like an Agent Audit key (expected aa_live_... or aa_test_...)." exit 1 } # --- 5. Write env file ----------------------------------------------------- Say "Writing $AAEnv" @" # Agent Audit configuration - keep this file private. AGENTAUDIT_API_KEY="$key" AGENTAUDIT_INGEST_URL="$AAIngest" AGENTAUDIT_HOME="$AAHome" "@ | Set-Content -Path $AAEnv -Encoding UTF8 # Lock the env file ACL to the current user only $envAcl = Get-Acl $AAEnv $envAcl.SetAccessRuleProtection($true, $false) $envRule = New-Object System.Security.AccessControl.FileSystemAccessRule( $me, 'FullControl', 'Allow' ) $envAcl.AddAccessRule($envRule) Set-Acl -Path $AAEnv -AclObject $envAcl Ok 'Wrote env (current-user ACL)' # --- 6. Test receipt ------------------------------------------------------- Say 'Sending a test receipt to verify the chain' $env:AGENTAUDIT_API_KEY = $key $env:AGENTAUDIT_INGEST_URL = $AAIngest $pyScript = @' import os, sys, json, urllib.request, time, uuid key = os.environ.get("AGENTAUDIT_API_KEY", "") base = os.environ.get("AGENTAUDIT_INGEST_URL", "https://www.agentaudit.co.uk") body = { "agent_id": "agentaudit-bootstrap", "session_id": f"bootstrap-{int(time.time())}", "event_id": str(uuid.uuid4()), "action_type":"system", "action_name":"install_verify", "ts": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), } data = json.dumps({"receipts": [body]}).encode("utf-8") req = urllib.request.Request( f"{base}/api/v1/receipts", data=data, headers={ "Authorization": f"Bearer {key}", "Content-Type": "application/json", "User-Agent": "agentaudit-bootstrap/1.0", }, method="POST", ) try: with urllib.request.urlopen(req, timeout=8) as r: print(f"HTTP {r.status}") except Exception as e: print(f"ERROR {e}") '@ $testOutput = & $venvPython -c $pyScript 2>&1 if ($testOutput -match 'HTTP 20[01]') { Ok 'Test receipt accepted - check the dashboard.' } else { Warn "Test receipt did not confirm (got: $testOutput). Dashboard will still flip to connected once you send a real one." } Write-Host '' Write-Host '[OK] Agent Audit installed.' -ForegroundColor Green Write-Host " env: $AAEnv" Write-Host " sdk: $sdkVer (venv)" Write-Host " docs: $AAIngest/docs/" Write-Host " dashboard: $AAIngest/dashboard/" Write-Host '' Write-Host 'Next: import agentaudit in your agent code, or run:' Write-Host " & '$AAVenv\Scripts\Activate.ps1'; agentaudit doctor" Write-Host ''