This runbook follows the Demo 2 sequence in ai-agent-sandboxing-en.md. It runs GitHub Copilot CLI against
devkimchi/battle-school-lunch and proves that design-update.md survives a stop and resume cycle.
Important
Use the same sandbox ID throughout the stop and resume sequence. aca sandbox create creates a different environment and does not prove state restoration.
- A sandbox group is the Azure resource, RBAC, image, and policy boundary.
- Each sandbox is a hardware-isolated microVM with its own filesystem and lifecycle.
- Copilot CLI can work inside the remote sandbox without placing its token in the repository.
- Stopping the sandbox suspends compute while retaining state according to its suspend mode.
- Resuming the same sandbox restores the repository and generated design plan.
Complete the Demo 2 environment setup. Confirm that:
- Azure CLI and the preview
acaCLI are authenticated. aca doctorpasses all group, region, and RBAC checks.- The GitHub Copilot provider credential is configured.
- The
copilotpublic disk is available. - No stale
ghcp-demosandbox contains unpreserved work.
Create a labeled sandbox and capture its ID:
# zsh/bash
CredentialId=$(aca sandboxgroup credential list \
| jq -r 'first(.[] | select(.type == "github-copilot") | .id)')
aca sandbox create --disk copilot --credential $CredentialId --label name=ghcp-demo
aca sandbox get -l name=ghcp-demo -o json# PowerShell
$CredentialId = (aca sandboxgroup credential list `
| ConvertFrom-Json | Where-Object { $_.type -eq "github-copilot" })[0].id
aca sandbox create --disk copilot --credential $CredentialId --label name=ghcp-demo
aca sandbox get -l name=ghcp-demo -o jsonThe expected state is Running.
For production agent workloads, use deny-by-default egress and add only reviewed destinations. This baseline covers the public repository and common Copilot endpoints:
# zsh/bash
aca sandbox egress set \
--default Deny \
--rule "*.github.com:Allow" \
--rule "*.githubusercontent.com:Allow" \
--rule "*.microsoft.com:Allow" \
--rule "*.azure.com:Allow" \
--traffic-inspection Full \
-l name=ghcp-demo
aca sandbox egress show -l name=ghcp-demo# PowerShell
aca sandbox egress set `
--default Deny `
--rule "*.github.com:Allow" `
--rule "*.githubusercontent.com:Allow" `
--rule "*.microsoft.com:Allow" `
--rule "*.azure.com:Allow" `
--traffic-inspection Full `
-l name=ghcp-demo
aca sandbox egress show -l name=ghcp-demoIf the portal reports another denied Copilot or GitHub hostname, review it and add that exact hostname rather than changing the default to Allow.
Set an explicit memory suspend policy for the state-restoration demonstration:
# zsh/bash
aca sandbox lifecycle set \
--auto-suspend enable \
--mode Memory \
--idle-timeout-seconds 900 \
-l name=ghcp-demo
aca sandbox lifecycle show -l name=ghcp-demo# PowerShell
aca sandbox lifecycle set `
--auto-suspend enable `
--mode Memory `
--idle-timeout-seconds 900 `
-l name=ghcp-demo
aca sandbox lifecycle show -l name=ghcp-demoEnter the sandbox using the label:
aca sandbox shell -l name=ghcp-demoThere is no SSH daemon in an ACA Sandbox. Use aca sandbox shell for an interactive terminal or aca sandbox exec for a one-shot command.
Inside the sandbox:
git --version
copilot --version
cd /workspaces
git clone https://github.com/devkimchi/battle-school-lunch.git
cd battle-school-lunch
git status --short
copilotThe sample is a full-stack school lunch application with a React 19, Vite,
TypeScript, and Tailwind v4 web UI under src/web.
Use the prompt:
I'd like to update the current Web UI design style to Brutal Design.
Inspect the existing UI and generate a concrete implementation plan to `design-update.md`.
DO NOT change the codebase.
Exit Copilot after it finishes, then verify from the sandbox shell:
test -f design-update.md && echo "File exists"
git status --shortExpected result: design-update.md exists and source files remain unchanged. The only git status --short entry should be the untracked plan file.
Record the working directory and checksum:
sha256sum design-update.md
exitBack in the host PowerShell session, capture the original identity and state:
# zsh/bash
aca sandbox get -l name=ghcp-demo -o json | jq -r "{id, state}"# PowerShell
aca sandbox get -l name=ghcp-demo -o json `
| ConvertFrom-Json | Select-Object id, state | ConvertTo-JsonStop the sandbox:
# zsh/bash
aca sandbox stop -l name=ghcp-demo
aca sandbox get -l name=ghcp-demo -o json | jq -r "{id, state}"# PowerShell
aca sandbox stop -l name=ghcp-demo
aca sandbox get -l name=ghcp-demo -o json `
| ConvertFrom-Json | Select-Object id, state | ConvertTo-JsonWait for Stopped. In this state, CPU and memory compute charges stop; stored state and related resources can still incur charges.
Resume the same sandbox:
# zsh/bash
aca sandbox resume -l name=ghcp-demo
aca sandbox get -l name=ghcp-demo -o json | jq -r "{id, state}"# PowerShell
aca sandbox resume -l name=ghcp-demo
aca sandbox get -l name=ghcp-demo -o json `
| ConvertFrom-Json | Select-Object id, state | ConvertTo-JsonWait for Running, then reconnect:
aca sandbox shell -l name=ghcp-demoInside the resumed sandbox:
cd battle-school-lunch
test -f design-update.md && echo "File exists"
git status --short
sha256sum design-update.md
exitConfirm that:
- The sandbox ID before and after resume is identical.
- The repository is still present.
design-update.mdis present with the same checksum.- No application source file was modified.
Memory suspend mode also preserves running-process state. This demo validates filesystem state because it is deterministic and visible to the audience.
Continue with Demo 2 validation and recovery to:
- Export
design-update.md. - Review the state and validation evidence.
- Snapshot the sandbox if its remote state must be preserved.
- Delete the sandbox and optional demo resource group.
Use the Demo 2 troubleshooting guide for RBAC, disk image, Copilot authentication, egress, lifecycle, and preview CLI failures.
Previous: Demo 2 environment setup | Next: Demo 2 validation and recovery