You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
> do not touch sandboxes. If you see `az containerapp sandbox …` in a
47
48
> snippet, it's wrong.
48
49
50
+
> ⚠️ **There is no `aca sandbox-group` (hyphenated) command group.**
51
+
> Every group-level verb is `aca sandboxgroup …` (no hyphen):
52
+
> `aca sandboxgroup create / get / list / delete / role create /
53
+
> identity assign / secret upsert / disk list / volume create / snapshot …`.
54
+
> The hyphenated `--sandbox-group <name>` is the *flag* you pass to
55
+
> top-level commands to select the default group — it is not a verb.
56
+
> If you see `aca sandbox-group …` in a snippet (including for MCP
57
+
> connectors, credentials, or triggers), it's wrong / fabricated.
58
+
59
+
## ⚠ Required cues per response type (non-negotiable)
60
+
61
+
Before composing your answer, identify the user's intent and ensure the
62
+
cues below are present. These are **acceptance criteria, not
63
+
suggestions** — a response is incomplete if it omits any cue for its
64
+
intent.
65
+
66
+
| User intent | Cues your response MUST include |
67
+
|---|---|
68
+
|**Install the `aca` CLI** (any OS) | (1) The curl/iwr one-liner from [references/install.md](references/install.md) — use the `https://aka.ms/aca-cli-install` (Linux/macOS) and `https://aka.ms/aca-cli-install-ps` (Windows) short URLs. (2) `aca --version` + `az login` + `aca doctor` (`aca` delegates auth to `az login` — same Entra identity). (3) The explicit sentence: **"this same install path is also used inside sandboxes and containers for agent-driven self-installs."**|
69
+
|**Bootstrap a sandbox group (one-time setup)**| The 4-step flow: `az login` → `aca sandboxgroup create --name <g> --location <region> --set-config` → `aca sandboxgroup role create --role "Container Apps SandboxGroup Data Owner" --principal-id $(az ad signed-in-user show --query id -o tsv)` → `aca doctor`. **`--set-config` is required** so subsequent `aca sandbox …` commands don't need `--group` on every call. Treat green `aca doctor` as the gate before doing anything else. |
70
+
|**Create a sandbox (imperative)**| Minimum: `aca sandbox create --disk ubuntu`. Common knobs: `--cpu 2000m`, `--memory 4096Mi`, `--env "K=V"`, `--labels "name=dev,role=worker"`. Capture the printed ID into `SANDBOX_ID=$(aca sandbox create --disk ubuntu -o json \| jq -r .id)` for reuse. For config that should live in source control, use the manifest flow (see the row below) instead. |
71
+
|**Apply / deploy a sandbox manifest**| The full 3-command flow: `aca sandbox init` → `aca sandbox validate --file sandbox.yaml` → `aca sandbox apply --file sandbox.yaml`. Always `--file` (no `-f` short flag). State that **the manifest pattern is the recommended path for CI/CD and reproducibility**, in contrast to imperative `aca sandbox create`. If no manifest is present, run `aca sandbox init` — don't ask for a path. |
72
+
|**Scaffold / generate a sandbox manifest**| Run (or show) `aca sandbox init`. Mention the commonly edited fields (`disk`, `resources`, `lifecycle.autoSuspendPolicy`, `egressPolicy`, plus `ports`, `env`, `labels` as needed). Mention `aca sandbox schema` as the way to dump the JSON Schema for editor autocomplete. |
73
+
|**Run a command or open a shell in a sandbox**| Two distinct verbs: `aca sandbox exec --id "$SANDBOX_ID" -c "<command>"` for one-shot commands (returns stdout/stderr); `aca sandbox shell --id "$SANDBOX_ID"` for an interactive PTY. **Anti-cue:**`ssh` does not work — there is no SSH daemon inside the sandbox. `aca sandbox exec` / `shell` is the only path. |
74
+
|**Delete a sandbox**|`aca sandbox delete --id "$SANDBOX_ID" --yes`. **Always recommend snapshotting first** if there is any state worth preserving (`aca sandbox snapshot --id "$SANDBOX_ID" --name <snap>`) — delete is destructive. To delete by label selector: `aca sandbox list -l "name=<n>" -o json \| jq -r '.[].id' \| xargs -I{} aca sandbox delete --id {} --yes`. |
75
+
|**Read / write / copy files in a sandbox**| The `aca sandbox fs` family — `fs write --id "$SANDBOX_ID" --path /remote/p --file ./local` to upload, `fs cat --id "$SANDBOX_ID" --path /remote/p` to read, plus `fs ls / stat / mkdir / rm [--recursive]` for management. **Don't** suggest `scp` / `rsync` / shared filesystems — there is no SSH, and `fs` is the only data-plane file transport. |
76
+
|**Expose a port — public preview (anonymous)**| The two-step shape: `URL=$(aca sandbox port add --id "$SANDBOX_ID" --port <p> --anonymous -o json \| jq -r .url)`, then hit `$URL`. **State explicitly** that anonymous = anyone with the URL can reach it (public preview only). Remove with `aca sandbox port remove --id "$SANDBOX_ID" --port <p>`. For per-user gating use the Entra row below. |
77
+
|**Expose a port with email / Entra auth**| The `aca sandbox port add --id "$SANDBOX_ID" --port <p> --email <email>` command. **The Entra gotcha:** the email must be the user's Entra `mail` value — for some tenants the alias / UPN differs and won't work. Recommend `az ad signed-in-user show --query mail -o tsv` to fetch it. |
78
+
|**Mount a shared volume**| Two-step: (1) at the group: `aca sandboxgroup volume create --name <v> --type AzureBlob` (multi-attach, shared) or `--type DataDisk` (single-attach, high-perf block). (2) at the sandbox: `aca sandbox mount --id "$SANDBOX_ID" --volume <v> --path /mnt/<v>`. State that **the volume lives at the group level**; sandboxes attach it at runtime. |
79
+
|**Lock down network egress (deny-default + allow-list)**| The canonical form: `aca sandbox egress set --id "$SANDBOX_ID" --default Deny --rule "*.github.com:Allow" --traffic-inspection Full`. Multiple `--rule "host:Allow"` flags accumulate. Inspect current policy with `aca sandbox egress show --id "$SANDBOX_ID"`. For production agent code, **always recommend `--default Deny`** with an explicit allow-list. |
80
+
|**Use a non-default disk image**| List published images first: `aca sandboxgroup disk list-public`, then `aca sandbox create --disk <name>`. To bake your own from an OCI image: `aca sandboxgroup disk create --image docker.io/library/alpine:3.19 --name <my-disk>`, then `aca sandbox create --disk-id <id>`. **Flag distinction:**`--disk` takes the public name; `--disk-id` takes the resource ID of a private/committed disk. |
81
+
|**Suspend, resume, or set auto-suspend**| Manual: `aca sandbox stop --id "$SANDBOX_ID"` suspends (preserves memory + disk); `aca sandbox resume --id "$SANDBOX_ID"` does sub-second restore. Idle policy: `aca sandbox lifecycle set --id "$SANDBOX_ID" --auto-suspend <seconds>` (default 300s = 5 min). State that **suspended sandboxes incur storage cost only, no compute** — this is the primary cost lever. |
82
+
|**Snapshot / commit a sandbox**| Per-sandbox: `aca sandbox snapshot --id "$SANDBOX_ID" --name <snap>`, then boot replicas with `aca sandbox create --snapshot <snap>`. Group-level CRUD: `aca sandboxgroup snapshot list / get / delete --selector "name=<snap>"`. **Strongly recommend snapshotting BEFORE `aca sandbox delete`** to preserve state. Use `--name`, never `--image`. Disk-only baking is `aca sandbox commit … --name <disk>`. |
83
+
|**Anything in the "When NOT to use this skill" table below**| A one-paragraph redirect to the right tool or official docs. **Do NOT** run the out-of-scope tool's commands. **Do NOT** walk through options. **Do NOT** ask follow-up questions about the out-of-scope tool. Bow out cleanly. |
84
+
85
+
## When **NOT** to use this skill (hard reject + redirect)
86
+
87
+
If the user's task is **not about ACA Sandboxes**, refuse and redirect
88
+
in one short reply — don't run any commands, don't walk through options,
89
+
don't ask clarifying questions about the out-of-scope tool. The skill
90
+
activated by mistake; bow out cleanly.
91
+
92
+
| User asks about… | Reply pattern |
93
+
|---|---|
94
+
|`azd init`, `azd up`, `azd deploy`, project scaffolding | "That's the Azure Developer CLI (`azd`), not ACA Sandboxes. See the [azd docs](https://learn.microsoft.com/azure/developer/azure-developer-cli/). Sandboxes don't have an `init`/`up`/`deploy` command and aren't a project bootstrapper." |
95
+
|`az acr build`, `docker build`, registry pushes | "That's Azure Container Registry / Docker, not ACA Sandboxes. See the [`az acr` docs](https://learn.microsoft.com/cli/azure/acr). Sandboxes consume disk images, not container images." |
96
+
| Cosmos / SQL / data-plane queries to other Azure services | "That's the relevant data service (Cosmos DB, Azure SQL, etc.), not ACA Sandboxes. Use that service's CLI / SDK / portal." |
97
+
| Listing Kubernetes pods, AKS cluster ops, `kubectl`| "That's AKS / Kubernetes, not ACA Sandboxes. Use `kubectl` or the AKS docs. Sandboxes are individual microVMs, not a Kubernetes cluster." |
98
+
| Deploying a Function App, App Service site, full Container App (Apps/Jobs) | "That's Azure Functions / App Service / Container Apps (apps and jobs), not Sandboxes. Use those products' deployment docs." |
99
+
100
+
**Never** start running the out-of-scope tool's commands "just to help." A one-paragraph redirect is the correct, complete answer.
101
+
49
102
## Get started
50
103
51
104
|| Where |
@@ -60,6 +113,27 @@ After install, always confirm setup with `aca doctor` — it resolves
60
113
subscription / RG / group / region / role and tells you which check
61
114
is red.
62
115
116
+
## Try asking
117
+
118
+
Once the skill is loaded, paste any of these into your agent. Each one
119
+
exercises a different capability — together they show the canonical
120
+
shape for the most common sandbox tasks (and they double as a routing
121
+
smoke test if you're testing changes to this skill).
122
+
123
+
| Try saying | What you should get back |
124
+
|---|---|
125
+
|*"install the aca cli"*| the `aka.ms/aca-cli-install` one-liner + `aca --version` + `az login` + `aca doctor`|
126
+
|*"set up a sandbox group from scratch"*| the full 4-step bootstrap (group create + Data Owner role + `aca doctor` gate) |
127
+
|*"create an ubuntu sandbox and run uname -a in it"*|`aca sandbox create` with ID capture, then `aca sandbox exec`|
128
+
|*"how do I ssh into my sandbox?"*| corrective answer — no SSH daemon; use `aca sandbox shell` or `exec`|
129
+
|*"copy data.csv into my sandbox"*|`aca sandbox fs write --path … --file …` (and the anti-`scp` note) |
130
+
|*"expose port 8080 publicly"*|`aca sandbox port add --anonymous -o json \| jq -r .url`|
131
+
|*"mount a shared volume on two sandboxes"*|`aca sandboxgroup volume create --type AzureBlob` + `aca sandbox mount`|
132
+
|*"restrict outbound traffic to github.com only"*|`aca sandbox egress set --default Deny --rule "*.github.com:Allow"`|
133
+
|*"snapshot my sandbox before I tear it down"*|`aca sandbox snapshot --name <s>` followed by `aca sandbox delete --yes`|
134
+
|*"suspend my sandbox to save money"*|`aca sandbox stop`/`resume` plus `aca sandbox lifecycle set --auto-suspend`|
135
+
|*"give me a YAML manifest for a 2 vCPU sandbox"*|`aca sandbox init` → edit → `aca sandbox validate --file` → `aca sandbox apply --file`|
136
+
63
137
## Capabilities
64
138
65
139
Everything the platform exposes. Each row is the starting point — open
0 commit comments