Windows setup runbook¶
Replaces (and supersedes) the three exploratory notes:
docs/architecture/next-windows-dev-environment.md,docs/claude-windows-port.md, anddocs/openai-windows-agent-identity-port.md. The implementation they discussed shipped via PR landing thefeat/windows-portbranch — seedocs/architecture/PLAN-windows-port.md.
Prerequisites¶
- Windows 10 21H2+ or Windows 11. Server SKUs work too but are not the primary target.
- PowerShell 7+ (
pwsh). The shipped scripts use#requires -Version 7.0. Windows PowerShell 5.1 is not enough. - Python 3.12+ on PATH.
- Azure CLI 2.55+ with a logged-in account that has at least
Application Administratorin the target tenant (same RBAC assetup.shon Mac). - git on PATH.
Optional but recommended:
- TPM 2.0 (BitLocker-ready). If the TPM is provisioned and reports
TpmReady, setup uses the Microsoft Platform Crypto Provider (KSP=tpm) so the Blueprint private key is non-exportable and bound to the device. Without a TPM, setup falls back to Microsoft Software Key Storage Provider (KSP=software) — DPAPI binds the key to the user profile.
One-shot setup¶
From a Windows PowerShell terminal (NOT a WSL shell):
cd C:\path\to\entraclaw-identity-research
.\scripts\setup-windows.cmd --new --with-upn-suffix=winagent
The .cmd wrapper elevates to pwsh -ExecutionPolicy Bypass so you
don't need to fight Windows policy gates per-session.
What it does:
- Refuses if invoked from inside WSL. WSL is Linux; use
scripts/setup.shthere instead. - Probes prereqs (
python,az,git,pwsh). - Runs the idempotent legacy data migration —
~/.entraclaw/→%LOCALAPPDATA%\entraclaw\. If both directories already have content, setup halts and asks you to triage manually (don't bypass — see Failure Modes below). - Creates a venv at
.venv\Scripts\python.exe. - Calls
entra_provisioning.pythencreate_entra_agent_ids.py(same Python helpers assetup.sh) to provision the Entra app chain. - Runs
generate_windows_cert.py— auto-probes the TPM and generates the Blueprint cert with hard-locked crypto:RSA-2048,SHA256,DigitalSignature,Signature. Falls back to software KSP if the TPM is missing/disabled. - Writes
.envand locks it withicacls /grant:r {USER}:M(modify, NOT readonly — rotation needs to update it). - Registers the entraclaw MCP server via
mcp_config.pyfor both Claude Code and Copilot CLI.
Final summary lists the chosen KSP and the cert SHA-1 so you can verify both paths were honored.
Smoke test¶
.venv\Scripts\python.exe -c "from entraclaw.tools.teams import acquire_agent_user_token; from entraclaw.config import get_config; print('token len=', len(acquire_agent_user_token(get_config())))"
A green print means the three-hop flow worked end-to-end on this machine.
Cert rotation¶
Run when the cert is approaching expiry, or when the host changes (new TPM, new user profile). Same flow as Mac's deploy script:
Contract:
- Captures the current cert's public DER bytes BEFORE generating the new cert. For non-exportable TPM keys, this is the only chance to grab them — without this, rollback is impossible.
- Generates the new cert.
- PATCHes the new DER to the Blueprint app via Graph.
- Runs a smoke test (acquires a fresh agent-user token).
- On success: deletes the old cert from
Cert:\CurrentUser\My. - On smoke failure: re-PATCHes the old DER, restores
.env, invalidates the MSAL cache (%LOCALAPPDATA%\entraclaw\.msal-cache.bin), raisesRotationRolledBack. - On rollback PATCH also failing: raises
ManualInterventionRequired— triage required before next agent run.
Teardown¶
Removes local cert(s), %LOCALAPPDATA%\entraclaw\, BLUEPRINT_CERT_*
lines from .env, MSAL cache, and the MCP registration. Does NOT
delete the Entra app registrations from the tenant — those are
shared and persistent.
Failure modes¶
| Symptom | Cause | Fix |
|---|---|---|
setup-windows.ps1 invoked from inside WSL |
running setup from a WSL shell | run from native PowerShell, or use setup.sh for the Linux path |
Legacy entraclaw data found at ~\.entraclaw but target ... is empty |
partial migration on an older entraclaw install | run setup again — migration is idempotent — or move the legacy dir manually |
two entraclaw dirs detected: legacy ~\.entraclaw and current %LOCALAPPDATA%\entraclaw both contain data |
parallel installs landed both | pick one: usually the %LOCALAPPDATA% copy is newer; remove ~\.entraclaw |
New-SelfSignedCertificate failed |
provider name typo, KSP missing, or PowerShell-down-version | confirm pwsh -Version ≥ 7; if TPM-disabled host, force software KSP via --ksp software |
thumbprint validation failed — not 40 hex chars |
az warning corrupted stdout (Learning #29 cousin) |
re-run setup; if it persists, file a bug with the captured stdout |
Initial Graph PATCH failed (rotation) |
tenant RBAC, expired Blueprint, or network | check az account show; the old cert is untouched, no rollback needed |
MANUAL INTERVENTION: rollback PATCH failed |
both new + rollback PATCH failed | re-PATCH the old DER (in %TEMP%\entraclaw-old-*.cer) by hand via Graph PATCH |
entraclaw-mcp.exe exits silently mid-run |
likely the same MCP-disconnect bug under investigation on Mac | see docs/runbooks/mcp-disconnect-investigation.md |
What's intentionally not here¶
- Bot Gateway on Windows. The Bot Gateway lives on a Linux host (werner.ac); Windows runs the agent_user mode only.
- WSL2 entraclaw. WSL inherits the Linux setup verbatim — run
scripts/setup.shfrom inside WSL. The two paths don't share state.