Triggers
Invoke your sandbox when an external event fires.
A trigger watches a connector event and wakes up or invokes a sandbox when it fires. An event could be a new email, a SharePoint upload, or any other connector event. The action is to run a script or a command inside a sandbox. The connector namespace's managed identity handles authentication, so there are no shared secrets to manage.
- The Connectors CLI (
az connector-namespace) is installed (install instructions).
Run a command in a sandbox when an event fires
Create a trigger and configure a sandbox action when a specific event fires.
Wire the connector event → sandbox command in one snippet:
- Bash
- PowerShell
# One time setup
AZURE_SUBSCRIPTION_ID=$(az account show --query id -o tsv)
AZURE_RESOURCE_GROUP=my-rg
AZURE_SANDBOX_GROUP=my-sandbox-group
AZURE_REGION=eastus2
NS=my-connector-namespace
SANDBOX_ID=$(aca sandbox get -l name=my-first-sandbox -o json \
| python -c 'import sys,json; print(json.load(sys.stdin)["id"])')
SG_MGMT=$(az resource show \
--resource-group $AZURE_RESOURCE_GROUP \
--name $AZURE_SANDBOX_GROUP \
--resource-type "Microsoft.App/sandboxGroups" \
--query properties.managementEndpoint -o tsv)
az connector-namespace trigger create -g $AZURE_RESOURCE_GROUP --namespace $NS -n on-new-invoice-run \
--connection-details '{"connectionName":"sharepointConn","connectorName":"sharepointonline"}' \
--operation-name GetOnNewFileItems \
--notification-details "{
\"callbackUrl\": \"$SG_MGMT/subscriptions/$AZURE_SUBSCRIPTION_ID/resourceGroups/$AZURE_RESOURCE_GROUP/sandboxGroups/$AZURE_SANDBOX_GROUP/sandboxes/$SANDBOX_ID/executeShellCommand?api-version=2026-02-01-preview\",
\"httpMethod\": \"Post\",
\"body\": {
\"command\": \"python /work/process_invoice.py\",
\"shell\": \"bash\",
\"workingDirectory\": \"/work\",
\"activationMode\": \"OnDemand\"
},
\"authentication\": {
\"type\": \"ManagedServiceIdentity\",
\"audience\": \"https://management.azuredevcompute.io/\"
}
}"
# Verify subsequent fires show up here
az connector-namespace trigger run list -g $AZURE_RESOURCE_GROUP --namespace $NS --trigger-config-name on-new-invoice-run
# One time setup
$AZURE_SUBSCRIPTION_ID = az account show --query id -o tsv
$AZURE_RESOURCE_GROUP = "my-rg"
$AZURE_SANDBOX_GROUP = "my-sandbox-group"
$AZURE_REGION = "eastus2"
$NS = "my-connector-namespace"
$SANDBOX_ID = (aca sandbox get -l name=my-first-sandbox -o json | ConvertFrom-Json).id
$SG_MGMT = az resource show `
--resource-group $AZURE_RESOURCE_GROUP `
--name $AZURE_SANDBOX_GROUP `
--resource-type "Microsoft.App/sandboxGroups" `
--query properties.managementEndpoint -o tsv
$notificationDetails = @"
{
"callbackUrl": "$SG_MGMT/subscriptions/$AZURE_SUBSCRIPTION_ID/resourceGroups/$AZURE_RESOURCE_GROUP/sandboxGroups/$AZURE_SANDBOX_GROUP/sandboxes/$SANDBOX_ID/executeShellCommand?api-version=2026-02-01-preview",
"httpMethod": "Post",
"body": {
"command": "python /work/process_invoice.py",
"shell": "bash",
"workingDirectory": "/work",
"activationMode": "OnDemand"
},
"authentication": {
"type": "ManagedServiceIdentity",
"audience": "https://management.azuredevcompute.io/"
}
}
"@
az connector-namespace trigger create -g $AZURE_RESOURCE_GROUP --namespace $NS -n on-new-invoice-run `
--connection-details '{"connectionName":"sharepointConn","connectorName":"sharepointonline"}' `
--operation-name GetOnNewFileItems `
--notification-details $notificationDetails
# Verify subsequent fires show up here
az connector-namespace trigger run list -g $AZURE_RESOURCE_GROUP --namespace $NS --trigger-config-name on-new-invoice-run
type: ManagedServiceIdentity tells the callback to fetch an Entra token for audience using a managed identity on the connector namespace. The identity field selects which one:
-
System-assigned (default) - omit
identity, as both examples here do. The token is issued for the namespace's own system-assigned identity. -
User-assigned - set
identityto the full ARM resource ID of a user-assigned identity (a string). The namespace must already have that identity attached. Use this when you want a purpose-built identity that you can grant exactly the RBAC needed to invoke the sandbox:"authentication": {
"type": "ManagedServiceIdentity",
"audience": "https://management.azuredevcompute.io/",
"identity": "/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<uami-name>"
}
Control how often a polling trigger polls
Connector triggers come in three flavors, and only one of them takes a recurrence schedule:
- Polling (e.g., SharePoint
GetOnNewFileItems, OutlookOnNewEmail) — the namespace runner queries the source on a cadence you set. Recurrence applies here. - Webhook (e.g., Teams
WebhookChatMessageTrigger) — the source pushes events to the runner as they happen. No cadence to set. - Notification — a polling op that ships with a paired webhook variant the runner uses for delivery. No cadence to set.
For a polling trigger, set recurrenceFrequency (Second, Minute, Hour, Day, Week, Month) and recurrenceInterval (a number) inside --metadata. Lower the interval for near-real-time reactions; raise it for low-volume sources like a daily report library.
# Poll the SharePoint "new file" trigger every 5 minutes
az connector-namespace trigger create -g $AZURE_RESOURCE_GROUP --namespace $NS -n on-new-invoice-5min \
--connection-details '{"connectionName":"sharepointConn","connectorName":"sharepointonline"}' \
--operation-name GetOnNewFileItems \
--metadata "{\"recurrenceFrequency\":\"Minute\",\"recurrenceInterval\":\"5\",\"sandboxGroupName\":\"$AZURE_SANDBOX_GROUP\",\"sandboxId\":\"$SANDBOX_ID\"}" \
--notification-details "..."
The connector show command doesn't return per-operation classification, so check the connector swagger directly. The snippet below prints true when the operation is a polling trigger (recurrence applies), false when it's a webhook or notification trigger (recurrence does not), or operation not found.
az rest --method GET \
--url "https://management.azure.com/subscriptions/$AZURE_SUBSCRIPTION_ID/providers/Microsoft.Web/locations/$AZURE_REGION/managedApis/sharepointonline?api-version=2022-09-01-preview&export=true" \
| jq -r --arg op "GetOnNewFileItems" '
([ .paths[] | to_entries[] | .value | select(.operationId == $op) ] | first) as $o
| if $o == null then "operation not found"
elif ($o["x-ms-notification-content"]
// ([$o.responses[]? | .["x-ms-notification-content"]] | map(select(. != null)) | first)) != null
then "false" # Webhook
elif ($o["x-ms-notification"]?.operationId
// ([$o.responses[]? | .["x-ms-notification"]?.operationId] | map(select(. != null)) | first)) != null
then "false" # Notification
else "true" # Polling -> recurrence applies
end'
Requires jq. The rule mirrors the portal wizard's classifier: an op with x-ms-notification-content is a webhook, an op with x-ms-notification.operationId is a notification, anything else is polling.
Observe trigger runs
Every trigger fire is recorded as a run. The portal's Triggers tab shows recent runs inline; from the CLI:
# Recent runs (most recent first)
az connector-namespace trigger run list -g $AZURE_RESOURCE_GROUP --namespace $NS \
--trigger-config-name on-new-invoice-run
# Drill into a specific run - request, response, captured stdout/stderr/exitCode
az connector-namespace trigger run show -g $AZURE_RESOURCE_GROUP --namespace $NS \
--trigger-config-name on-new-invoice-run -n <run-id>
# Trigger-level status (rolling health; defaults to the latest status)
az connector-namespace trigger status show -g $AZURE_RESOURCE_GROUP --namespace $NS \
--trigger-config-name on-new-invoice-run
Disable, re-enable, and delete a trigger
# Pause without losing the config
az connector-namespace trigger update -g $AZURE_RESOURCE_GROUP --namespace $NS -n on-new-invoice-run \
--state Disabled
# Resume
az connector-namespace trigger update -g $AZURE_RESOURCE_GROUP --namespace $NS -n on-new-invoice-run \
--state Enabled
# Delete permanently
az connector-namespace trigger delete -g $AZURE_RESOURCE_GROUP --namespace $NS -n on-new-invoice-run
Scenarios
- Per-event email triage. Each incoming Outlook email spawns an ephemeral sandbox that classifies and routes via Teams MCP. Uses the run-a-command flow. See Sample 10.
- Per-event SharePoint document automation. Each new SharePoint upload hits a long-lived sandbox FastAPI on
:8080; the agent OCRs the file and uploads JSON back. Uses the invoke-a-port flow. See Sample 11. - PR review bot. A GitHub PR-opened trigger spawns a fresh sandbox that runs your tests on the PR branch and posts results via the GitHub MCP.
- Hourly compliance audit. A SharePoint connector trigger polling once an hour wakes a sandbox that uses SharePoint MCP to scan a document library and Teams MCP to notify on violations.
- Daily email digest. An Outlook connector trigger polling once a day wakes a sandbox at 7 AM that reads the last 24 hours of email and drafts a digest.
- High-priority-only email escalation. Same as the email triage, with the connector's native
importance=Highparameter as a server-side filter.
The full runnable example at examples/connectors-end-to-end.sh wires connector + sandbox group + sandbox + trigger end-to-end in one runnable file.