Deploy a Microsoft Foundry agent that lives in Azure and responds in Slack whenever it is mentioned.
This project is a cloud-only deployment accelerator for connecting Slack channels to a Microsoft Foundry-hosted agent experience. No local tunnel, local server, or workstation process is used in production.
Slack sends app_mention events to an Azure Functions HTTPS endpoint. The function optionally verifies the Slack signature when a signing secret is available, acknowledges Slack immediately, queues the event, runs the Foundry-backed agent from Azure, and posts the answer back into the same Slack thread.
flowchart LR
U["Slack user @mentions bot"] --> S["Slack Events API"]
S --> H["Azure Functions HTTP trigger"]
H --> Q["Azure Storage Queue"]
Q --> W["Azure Functions queue worker"]
W --> A["Microsoft Foundry Agent Service"]
W --> T["Azure Table Storage"]
W --> R["Slack threaded reply"]
- Resource group.
- Storage account, queue, and table-backed conversation state.
- Application Insights.
- Linux Azure Functions app on Python 3.11.
- Microsoft Foundry account.
- Microsoft Foundry project.
- Foundry model deployment.
- Managed identity role assignment for the Function App to call Foundry.
- Function App settings for Slack and Foundry runtime configuration.
This implementation follows Slack's current guidance:
- Uses the Events API with the
app_mentionbot event. - Handles Slack URL verification challenges.
- Verifies
X-Slack-Signaturewith the Slack signing secret when provided. - Rejects replayed requests outside the timestamp tolerance window when signature verification is enabled.
- Returns
200 OKquickly before long-running agent work. - Processes work asynchronously from Azure Storage Queue.
- Deduplicates Slack event IDs so Slack retries do not produce duplicate replies.
- Replies in-thread to keep channels readable.
- Uses least-privilege bot scopes for mention handling and responses.
Slack bot token note: after the Slack app exists and has its Events API request URL configured, SLACK_BOT_TOKEN is the only required Slack value for the Azure runtime. A bot token can post replies and validate bot identity. It cannot create or update Slack app configuration, and it cannot retrieve the Slack signing secret. For stricter production security, also provide SLACK_SIGNING_SECRET; without it, the endpoint accepts Events API requests without signature verification.
Slack supports app manifests in YAML or JSON. This repo treats the manifest as deployment configuration, so the Slack app can be created or updated automatically after Terraform publishes the Azure Functions request URL.
export SLACK_APP_CONFIG_TOKEN="xapp-..."
export SLACK_APP_ID="A0123456789"
export SLACK_BOT_TOKEN="xoxb-..."
export SLACK_CHANNEL_ID="C0123456789"
python scripts/configure_slack_app.py --from-terraformThe script:
- Resolves the deployed request URL:
https://<function-app>.azurewebsites.net/api/slack/events. - Writes
outputs/slack-manifest.yamlandoutputs/slack-manifest.json. - Validates the manifest with Slack.
- Creates a new Slack app if
SLACK_APP_CONFIG_TOKENis set andSLACK_APP_IDis omitted. - Updates the existing Slack app if both
SLACK_APP_CONFIG_TOKENandSLACK_APP_IDare set. - Verifies the bot token and joins
SLACK_CHANNEL_IDwhen those values are present.
The manifest configures:
- Event subscription request URL.
- Bot event:
app_mention. - Bot user display name.
- Bot scopes:
app_mentions:read,chat:write,channels:join,channels:read,groups:read,im:history,im:read, andim:write.
Slack boundary: SLACK_BOT_TOKEN is enough for the deployed Azure runtime after the Slack app is configured. Slack does not allow a bot token to create/update the app manifest, set the Events API URL, or read the signing secret. App creation and Events API configuration require a Slack app configuration token, or a one-time manual manifest import in Slack. If scopes or app capabilities change, Slack may require reinstalling the app so a workspace admin can approve the new permissions.
Run this once from a workstation signed in to Azure and GitHub:
./scripts/bootstrap_github_oidc.sh \
--repo msftse/foundry-slack-agent \
--subscription-id "<subscription-id>" \
--resource-group "rg-foundry-slack-agent-prod" \
--location "eastus" \
--slack-bot-token "xoxb-..." \
--slack-channel-id "C0123456789"The script:
- Creates or confirms the Azure resource group.
- Creates an Azure AD app registration for GitHub OIDC.
- Adds a federated credential for
main. - Stores GitHub Actions secrets.
- Starts the
Deployworkflow.
The Deploy workflow runs Terraform, publishes the Function App, writes the Slack request URL to the GitHub Actions summary, and applies the Slack manifest when SLACK_APP_CONFIG_TOKEN is available.
export TF_VAR_subscription_id="<subscription-id>"
export TF_VAR_resource_group_name="rg-foundry-slack-agent-prod"
export TF_VAR_location="eastus"
export TF_VAR_slack_bot_token="xoxb-..."
export TF_VAR_slack_channel_id="C0123456789"
export TF_VAR_model_name="gpt-5.4-mini"
export TF_VAR_model_deployment_name="gpt-5.4-mini"
export TF_VAR_model_version="2026-03-17"
./scripts/deploy_from_workstation.shOptional production hardening:
export TF_VAR_slack_signing_secret="..."When this value is set, the Function App verifies every Slack request using Slack's signing headers. When it is omitted, bot-token-only deployments still work, but request signature verification is disabled.
Invite the bot to the target channel, then mention it:
@Foundry Agent give me a quick summary of what you can do
The bot posts a Working on it... message and updates that message with the Foundry response.
python -m venv .venv
source .venv/bin/activate
pip install -r requirements-dev.txt
ruff check .
pytest
terraform -chdir=infra/terraform fmt -check
terraform -chdir=infra/terraform validate