Azure (Microsoft) logo

Skill

azure-connectornamespace-aca-sandbox

manage Azure Connector Namespace connections

Covers Azure Integrations API Development

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 requestPatternConnectors 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)

RuleDetails
No hallucinationCheck references/ for details. Use az rest --help for syntax.
No generated notebooks/scriptsDo NOT generate a notebook or standalone script for the user. Walk through interactively. (Reference scripts in scripts/ and labs/ exist for learning.)
No MCP configsSandbox apps call runtime URL directly via HTTP. If you reach mcp-config create, STOP.
No guessing dynamic valuesx-ms-dynamic-* → call API, present results, STOP. Never assume a team/channel/folder/site.
Execute, don't askGather inputs → execute immediately → report. Never say "Can I run this?"
No az extensionsGateway = az rest. Sandbox = aca CLI. Do NOT use az connectorgateway/sandbox/sandboxgroup.
Always @$tmpFileFor 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 schemaUses metadata + notificationDetails (callbackUrl/body/auth). operationName+parameters at properties root. callbackTarget does NOT exist. See Step 5B template.
Handler deployWrite to local file → aca sandbox fs write. Never inline Python in PowerShell.
SSL/stderrREQUESTS_CA_BUNDLE preferred. verify=False needs disable_warnings(). stderr = trigger failure. See handler-guide.md.
Parallel executionRun independent ops (connections, ACLs, gatewayConnections wiring, dynamic values) as parallel tool calls.
Sandbox ↔ connection wiringUse the declarative gatewayConnections pattern (SG-level PATCH + per-sandbox PUT body). See gateway-connections.md.
Swagger / operation discoveryAlways 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 idempotencyWhen 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 progressThe 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

  1. Check az account show and aca --version. If missing, see prerequisites.md.
  2. 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.
  3. 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}
      

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 saysConnector nameCommon triggers
Email, Outlookoffice365OnNewEmailV3, OnFlaggedEmail
SharePoint, listsharepointonlineOnNewItem, OnUpdatedItem
OneDrive, filesonedriveforbusinessOnNewFile, OnUpdatedFile
TeamsteamsOnNewChannelMessage
Forms, survey, quizmicrosoftformsOnFormResponse, OnNewResponse
Azure BlobazureblobOnNewBlob, 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:

  1. Get gateway info (principalId, tenantId, location)
  2. List existing connections (names, statuses, runtime URLs)
  3. 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-preview Use 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 principalId and tenantId — 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-Process to open links. Body MUST use parameters array with objectId/tenantId from 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 via gatewayConnections[].
  • 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 AStep 5A
  • If BStep 5B

Step 5A: Direct API calls via dynamicInvoke

Full details: direct-api.md | Swagger discovery: swagger-discovery.md | Dynamic values: dynamic-values.md

  1. Fetch the connector Swagger and pick an operation — see swagger-discovery.md.
  2. Call dynamicInvoke on the connection with the resolved method + path
  3. 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

  1. Discover trigger operations — fetch the Swagger and filter paths whose operation has x-ms-trigger set. See swagger-discovery.md.
  2. If trigger type is batch (polling): inform user it polls every ~3 minutes by default. Ask if they want a different interval.
  3. Collect parameters (resolve x-ms-dynamic-* via Swagger + dynamicInvoke)
  4. Ask user: sandbox (existing/new) + callback type (ShellCommand / ExecuteCommand / InvokePort)
  5. Create trigger + access policy + role assignment (run in parallel) — canonical template in trigger-setup.md Step 8B
  6. Verify trigger state is Enabled

⚠️ Do NOT use callbackTarget — that field does not exist. Correct schema: metadata + notificationDetails. See trigger-setup.md.

TargetCallback URLNotes
ShellCommandhttps://management.{region}.azuredevcompute.io/.../executeShellCommandAuto-resumes sandbox; needs RBAC c24cf47c-... on sandbox group. Regional host required (unregional → 404 GlobalSandboxNotFound).
ExecuteCommandhttps://management.{region}.azuredevcompute.io/.../executeCommandSame as above, no shell interpretation. Regional host required.
InvokePorthttps://{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, connectionRuntimeUrl available
  • ✅ Access policies on connection: gateway-acl (gateway MI) AND sandbox-acl (sandbox-group MI)
  • ✅ Sandbox group has SystemAssigned MI (aca sandboxgroup identity assign --name {sg} --system-assigned if principalId is 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; use az rest data-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-acl exists (gateway MI → connection)
  • ✅ RBAC role on sandbox group (ShellCommand) OR port auth (InvokePort)
  • ✅ If handler calls runtime URL: also needs sandbox-acl + sandbox-group gatewayConnections[] entry + per-sandbox gatewayConnections[{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

© 2026 YourAI.tools. Every skill from an identity-verified publisher.

Independent catalog. Not affiliated with, endorsed by, or sponsored by Anthropic or any listed publisher. All trademarks belong to their respective owners.