
Skill
azure-connectornamespace-aca-sandbox
manage Azure Connector Namespace connections
Description
Azure Connector Namespace — ACA sandbox edition. Manage connector namespaces, connections, and triggers that wire external services (Office 365, Teams, Forms, SharePoint, OneDrive, GitHub, Azure Blob) into ACA sandbox apps via event-driven triggers or direct API calls using connection runtime URLs. Use when: - Managing connector namespaces and connections for ACA sandboxes - Creating trigger configs whose callbacks target sandbox endpoints - Wiring event sources to ACA sandbox callbacks via gatewayConnections - Building sandbox apps that call connector APIs (send email, post Teams message, etc.) - Reacting to events from one service and calling another Triggers: "create trigger", "trigger config", "webhook trigger", "connector namespace", "connector", "connection", "email trigger", "send email", "onedrive", "sharepoint", "teams", "teams message", "microsoft forms", "form response", "aca sandbox", "sandbox group", "container apps sandbox", "notify", "automate", "when", "on new"
SKILL.md
Azure Connector Namespace — ACA sandbox edition
Manage connectors, connections, and triggers — connect external services to sandbox apps via direct API calls or event-driven triggers.
Common scenarios
| User request | Pattern | Connectors involved |
|---|---|---|
| "Send a Teams message when a form is submitted" | Trigger (Forms) + Direct API (Teams) | microsoftforms, teams |
| "Notify a channel when a file is uploaded" | Trigger (OneDrive/Blob) + Direct API (Teams) | onedriveforbusiness/azureblob, teams |
| "Send an email when a SharePoint list item changes" | Trigger (SharePoint) + Direct API (Office 365) | sharepointonline, office365 |
| "Post to Teams when a new email arrives" | Trigger (Office 365) + Direct API (Teams) | office365, teams |
| "Save form responses to SharePoint" | Trigger (Forms) + Direct API (SharePoint) | microsoftforms, sharepointonline |
Rules (MUST follow)
| Rule | Details |
|---|---|
| No hallucination | Check references/ for details. Use az rest --help for syntax. |
| No generated notebooks/scripts | Do NOT generate a notebook or standalone script for the user. Walk through interactively. (Reference scripts in scripts/ and labs/ exist for learning.) |
| No MCP configs | Sandbox apps call runtime URL directly via HTTP. If you reach mcp-config create, STOP. |
| No guessing dynamic values | x-ms-dynamic-* → call API, present results, STOP. Never assume a team/channel/folder/site. |
| Execute, don't ask | Gather inputs → execute immediately → report. Never say "Can I run this?" |
| No az extensions | Gateway = az rest. Sandbox = aca CLI. Do NOT use az connectorgateway/sandbox/sandboxgroup. |
Always @$tmpFile | For az rest --body in PowerShell — inline JSON breaks. Bash examples in references/ use inline for brevity (shell quoting works in bash). See gotchas.md. |
| Trigger body schema | Uses metadata + notificationDetails (callbackUrl/body/auth). operationName+parameters at properties root. callbackTarget does NOT exist. See Step 5B template. |
| Handler deploy | Write to local file → aca sandbox fs write. Never inline Python in PowerShell. |
| SSL/stderr | REQUESTS_CA_BUNDLE preferred. verify=False needs disable_warnings(). stderr = trigger failure. See handler-guide.md. |
| Parallel execution | Run independent ops (connections, ACLs, gatewayConnections wiring, dynamic values) as parallel tool calls. |
| Sandbox ↔ connection wiring | Use the declarative gatewayConnections pattern (SG-level PATCH + per-sandbox PUT body). See gateway-connections.md. |
| Swagger / operation discovery | Always fetch the connector Swagger via the connection's runtime metadata URL — see swagger-discovery.md for the full pattern (auth, ACL idempotency, parsing, picking the right operation). |
| ACL idempotency | When creating a user-ACL on a connection (for swagger discovery from outside a sandbox), ALWAYS GET the policy first and only PUT if it doesn't exist. Never blindly recreate a user-ACL. (This does not apply to gateway-acl / sandbox-acl — those are typically PUT directly during setup.) |
| Narrate progress | The user must know what's happening at each step before you run the shell. Print a short chat message (NOT inside the shell block) with: (a) what you're doing in one line, (b) the exact URL or resource ID being touched, and (c) why. Never run a shell command silently or with only a collapsed shell block. |
When to STOP and ask the user: Any parameter with dynamic values (teams, channels, folders, sites, lists), choosing integration pattern, OAuth consent. You must NEVER skip this — always fetch the list and present it.
When to EXECUTE immediately: creating gateways/connections/triggers/policies, wiring gatewayConnections, deploying handlers, installing deps.
Step 0: Prerequisites & Azure context
- Check
az account showandaca --version. If missing, see prerequisites.md. - Select subscription — list available subscriptions, ask the user to pick:
az account list --query "[].{name:name, id:id, isDefault:isDefault}" -o table
Present the list and ask: "Which subscription do you want to use?" If the user picks a non-default subscription, set it:az account set --subscription "{selected_subscription_id}"
Store the subscription ID for all subsequent commands. - Select resource group — ask: "Do you have an existing resource group, or should I create one?"
- If existing: list and let user pick:
az group list --query "[].{name:name, location:location}" -o table - If new: ask for name + location, then create:
az group create --name {rg} --location {location}
- If existing: list and let user pick:
Stop and wait for the user's answers before continuing.
Step 1: Understand the scenario
Ask the user:
- "What event do you want to trigger on?" (new email, SharePoint list item, file upload, etc.)
- Map the answer to a connector using this table:
| User says | Connector name | Common triggers |
|---|---|---|
| Email, Outlook | office365 | OnNewEmailV3, OnFlaggedEmail |
| SharePoint, list | sharepointonline | OnNewItem, OnUpdatedItem |
| OneDrive, files | onedriveforbusiness | OnNewFile, OnUpdatedFile |
| Teams | teams | OnNewChannelMessage |
| Forms, survey, quiz | microsoftforms | OnFormResponse, OnNewResponse |
| Azure Blob | azureblob | OnNewBlob, OnUpdatedBlob |
- Ask if they already know the trigger operation, or want to discover available ones.
Stop and wait for the user's answer before continuing.
Step 2: Gateway setup
⚡ Parallel batch: Once you know the gateway name, run ALL of these in one parallel call:
- Get gateway info (principalId, tenantId, location)
- List existing connections (names, statuses, runtime URLs)
- Get sandbox group identity (if sandbox already exists)
This avoids sequential round-trips and saves ~2 minutes.
ARM base URL:
https://management.azure.com/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Web/connectorGatewaysAPI version:api-version=2026-05-01-previewUse the subscription and resource group selected in Step 0.
Ask the user:
- "Do you have an existing connector, or should I create a new one?"
- If existing: ask for the gateway name, then retrieve it (using sub/rg from Step 0):
az rest --method GET \ --url "https://management.azure.com/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Web/connectorGateways/{gw}?api-version=2026-05-01-preview" \ --query "{name:name, principalId:identity.principalId, tenantId:identity.tenantId}" - If new: ask for gateway name + location, then create it
immediately with a SystemAssigned managed identity (required for trigger callbacks):
$gwBody = @{ location = "{location}"; identity = @{ type = "SystemAssigned" } } | ConvertTo-Json -Compress $tmp = New-TemporaryFile; Set-Content $tmp $gwBody az rest --method PUT ` --url "https://management.azure.com/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Web/connectorGateways/{gw}?api-version=2026-05-01-preview" ` --body "@$tmp" ` --query "{name:name, principalId:identity.principalId, tenantId:identity.tenantId}" Remove-Item $tmp - Always capture
principalIdandtenantId— they are needed later for access policies and InvokePort auth. - List existing connections:
az rest --method GET \ --url "https://management.azure.com/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Web/connectorGateways/{gw}/connections?api-version=2026-05-01-preview" \ --query "value[].{name:name, status:properties.statuses[0].status, connector:properties.connectorName}"
Once you have the gateway info, proceed immediately to Step 3.
Step 3: Create connection(s) + authenticate
Create ALL needed connections in parallel, then consent all at once:
# Create connections (parallel tool calls if multiple):
$connBody = @{ properties = @{ connectorName = "office365" }; location = "{location}" } | ConvertTo-Json -Compress
$tmp = New-TemporaryFile; Set-Content $tmp $connBody
az rest --method PUT `
--url "https://management.azure.com/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Web/connectorGateways/{gw}/connections/o365-conn?api-version=2026-05-01-preview" `
--body "@$tmp"
Remove-Item $tmp
# Repeat for additional connections (onedriveforbusiness, sharepointonline, etc.)
Generate consent links and open in browser. → Exact format: See consent.md
⚠️ Use
Start-Processto open links. Body MUST useparametersarray withobjectId/tenantIdfrom the connection. Do NOT try other formats or print the URL.
Ask user to authenticate (use ask_user), then verify:
az rest --method GET \
--url ".../{gw}/connections?api-version=2026-05-01-preview" \
--query "value[].{name:name, status:properties.statuses[0].status}"
# All should show: Connected. If not, re-consent.
Step 4: Choose integration pattern
Ask the user:
- A) Direct API calls — call connector operations on demand via
dynamicInvoke(send email, read list, create file). If deploying to sandbox, also wires the connection to the sandbox group + sandbox viagatewayConnections[]. - B) Event-driven triggers — gateway pushes notifications to sandbox when events happen. Handler can then use direct API calls for additional actions.
Stop and wait for the user's answer.
- If A → Step 5A
- If B → Step 5B
Step 5A: Direct API calls via dynamicInvoke
→ Full details: direct-api.md | Swagger discovery: swagger-discovery.md | Dynamic values: dynamic-values.md
- Fetch the connector Swagger and pick an operation — see swagger-discovery.md.
- Call
dynamicInvokeon the connection with the resolvedmethod+path - If parameters have
x-ms-dynamic-*→ resolve via dynamicInvoke, show display names to user, store values
If deploying to sandbox: Wire the connection declaratively (sandbox-group gatewayConnections[] PATCH + per-sandbox PUT body referencing the same connection) → gateway-connections.md. The platform proxy injects Bearer auth on every runtime-URL call automatically; the handler makes plain requests.get(...) calls with no auth header.
→ Skip to Final verification checklist.
Step 5B: Event-driven triggers
→ Full trigger setup (Steps 5B–9B): trigger-setup.md | Swagger discovery: swagger-discovery.md | Dynamic values: dynamic-values.md
- Discover trigger operations — fetch the Swagger and filter paths whose operation has
x-ms-triggerset. See swagger-discovery.md. - If trigger type is
batch(polling): inform user it polls every ~3 minutes by default. Ask if they want a different interval. - Collect parameters (resolve
x-ms-dynamic-*via Swagger + dynamicInvoke) - Ask user: sandbox (existing/new) + callback type (ShellCommand / ExecuteCommand / InvokePort)
- Create trigger + access policy + role assignment (run in parallel) — canonical template in trigger-setup.md Step 8B
- Verify trigger state is
Enabled
⚠️ Do NOT use
callbackTarget— that field does not exist. Correct schema:metadata+notificationDetails. See trigger-setup.md.
| Target | Callback URL | Notes |
|---|---|---|
| ShellCommand | https://management.{region}.azuredevcompute.io/.../executeShellCommand | Auto-resumes sandbox; needs RBAC c24cf47c-... on sandbox group. Regional host required (unregional → 404 GlobalSandboxNotFound). |
| ExecuteCommand | https://management.{region}.azuredevcompute.io/.../executeCommand | Same as above, no shell interpretation. Regional host required. |
| InvokePort | https://{id}--{port}.proxy.azuredevcompute.io/... | Sandbox must be running; needs port auth |
After trigger creation → deploy handler. See handler-guide.md.
Final verification checklist
For Direct API calls (path A):
- ✅ Gateway exists, connection
Connected,connectionRuntimeUrlavailable - ✅ Access policies on connection:
gateway-acl(gateway MI) ANDsandbox-acl(sandbox-group MI) - ✅ Sandbox group has SystemAssigned MI (
aca sandboxgroup identity assign --name {sg} --system-assignedifprincipalIdis null) - ✅ Sandbox-group
properties.gatewayConnections[]includes an entry with this connection's{resourceId, connectionRuntimeUrl, authentication.type=SystemAssignedManagedIdentity}(PATCH; merge-don't-clobber) - ✅ Each sandbox was created with
gatewayConnections: [{resourceId}]in its data-plane PUT body (the aca CLI doesn't expose--gateway-connection; useaz restdata-plane PUT) - ✅ Test call from sandbox works (no auth header needed — platform proxy injects Bearer)
For Event-driven triggers (path B):
- ✅ Gateway has SystemAssigned identity, connection
Connected - ✅ Trigger state is
Enabled,gateway-aclexists (gateway MI → connection) - ✅ RBAC role on sandbox group (ShellCommand) OR port auth (InvokePort)
- ✅ If handler calls runtime URL: also needs
sandbox-acl+ sandbox-groupgatewayConnections[]entry + per-sandboxgatewayConnections[{resourceId}](same as path A)
After setup → deploy the handler app. See handler-guide.md.
Quick reference
# ARM base: https://management.azure.com/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Web/connectorGateways
# API version: api-version=2026-05-01-preview
# Gateway
az rest --method GET --url ".../connectorGateways/{gw}?api-version=2026-05-01-preview"
# Connections
az rest --method GET --url ".../connectorGateways/{gw}/connections?api-version=2026-05-01-preview"
# Connector Swagger (paths, parameters, x-ms-dynamic-* extensions) — use to list operations or pick a specific one.
# See references/swagger-discovery.md for the full fetch pattern (metadata URL + user-ACL + API Hub token):
# az rest --method GET --url "<metadata_url>?export=true" --resource "https://apihub.azure.com"
# Dynamic invoke
az rest --method POST --url ".../connectorGateways/{gw}/connections/{conn}/dynamicInvoke?api-version=2026-05-01-preview" --body '{"request":{"method":"GET","path":"/..."}}'
# Trigger configs
az rest --method GET --url ".../connectorGateways/{gw}/triggerConfigs?api-version=2026-05-01-preview"
az rest --method GET --url ".../connectorGateways/{gw}/triggerConfigs/{name}?api-version=2026-05-01-preview" --query "properties.state"
References
- direct-api.md — Full dynamicInvoke details, parameter resolution, examples
- consent.md — OAuth consent link generation (exact body format)
- trigger-setup.md — Full trigger creation commands (Steps 5B–9B)
- handler-guide.md — Handler development, event delivery, templates
- dynamic-values.md — Dynamic parameter resolution algorithms
- gateway-connections.md — Sandbox ↔ connection wiring (declarative gatewayConnections)
- runtime-url-examples.md — Curl examples for all connectors
- gotchas.md — Common issues and solutions
- trigger-flow.md — Trigger architecture details
- prerequisites.md — Setup requirements
- quickstart.md — Quick start guide
- tutorial-welcome-emailer.md — Pattern A walkthrough: deploy a welcome emailer to a sandbox
More skills from the Connectors repository
View all 2 skillsMore from Azure (Microsoft)
View publisherazure-arg-external-evaluation-policy-author
author and test Azure Resource Graph policies
azure-policy
Jul 12AzureComplianceGovernancePolicyazure-blueprints-migration
migrate Azure Blueprints to Template Specs
azure-blueprints
Jul 12AzureDeploymentInfrastructure as CodeMigrationapiview-feedback-resolution
resolve APIView feedback on Azure SDKs
azure-sdk-tools
Jul 12API DevelopmentAzureCode ReviewDocumentationazsdk-common-live-and-recorded-tests
deploy resources and run Azure SDK tests
azure-sdk-tools
Jul 12AzureDeploymentSDKTestingazsdk-common-prepare-release-plan
manage Azure SDK release plan work items
azure-sdk-tools
Jul 12AzureGitHubProject ManagementSDKazsdk-common-sdk-release
release Azure SDK packages
azure-sdk-tools
Jul 12AzureCI/CDDeploymentSDK