azure functions
16 TopicsEasy Auth Configuration for Logic App Standard through CI/CD
Problem Statement When Easy Auth (Azure App Service’s built-in authentication and authorization) is enabled on a Logic App Standard, users frequently report that they cannot open the run history. Specifically, the inputs and outputs of the trigger and actions fail to load on the run details page, even though the workflow itself runs and the user has access to the resource. Background — How Easy Auth Interacts with Logic Apps Easy Auth is a feature of Azure App Service. Every request that reaches a Logic App Standard is first routed through the App Service layer, and only then handed off to the Logic App runtime for further processing. When Easy Auth is enabled, App Service authenticates each incoming request and decides whether it should be allowed or blocked — before the Logic App runtime ever sees it. This dual-layer model is what causes the run-history symptom: The Logic App runtime authenticates run-history requests using a SAS token specific to that run, generated from the Logic App access keys. The portal calls that load the inputs and outputs of historical runs do not carry a bearer token — they carry the SAS. Because App Service only knows how to validate Easy Auth tokens (not SAS), it blocks these requests whenever unauthenticatedClientAction is set to disallow unauthenticated traffic. The request never reaches the runtime, so the runtime cannot apply its SAS validation, and the inputs/outputs panel stays empty. Solution There are two ways to fix this, depending on what your security policy allows. Option 1 — Allow unauthenticated requests The simplest fix is to configure Easy Auth to allow unauthenticated requests. This does not mean anyone can invoke the workflow. Instead, all calls (failed and successful) are routed through to the Logic App runtime, and the runtime decides how to handle them: A workflow trigger call with no token → the runtime applies its own auth (SAS, AAD, etc.) and rejects unauthorized invocations. A run-history call carrying a valid SAS → App Service marks it as “failed Easy Auth” but still forwards it; the runtime sees the valid SAS and returns the data. The underlying App Service platform has no knowledge of SAS or any other Logic-App-specific auth scheme, so letting the runtime arbitrate is what makes the run-history experience work. Option 2 — Keep Easy Auth strict, but exclude the runtime paths In many enterprises the security team will not permit “Allow unauthenticated requests.” For those cases, you can leave authentication required but add the runtime endpoints to the excludedPaths list, so App Service skips Easy Auth specifically for those calls. The Logic App runtime continues to authenticate them via SAS. Important: The Azure portal lets you toggle Easy Auth, but it does not expose the excludedPaths setting. You must configure it through ARM, Bicep, the REST API, or CLI — which is exactly why this needs to live in your CI/CD pipeline. There are two ways to apply this through CI/CD. Approach 1 — ARM Template ( Microsoft.Web/sites/config ) Add a Microsoft.Web/sites/config resource of type authsettingsV2 to the same ARM template that deploys the Logic App. Below is the sample template: { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "logicAppName": { "type": "string" }, "location": { "type": "string", "defaultValue": "[resourceGroup().location]" }, "tenantID": { "type": "string" }, "ClientID": { "type": "string" } }, "variables": {}, "resources": [ { "type": "Microsoft.Web/sites", "apiVersion": "2022-03-01", "name": "[parameters('logicAppName')]", "location": "[parameters('location')]", "kind": "functionapp,workflowapp", "identity": { "type": "SystemAssigned" }, "properties": { "serverFarmId": "<App Service Plan ID>", "siteConfig": { "appSettings": [ { "name": "FUNCTIONS_EXTENSION_VERSION", "value": "~4" }, { "name": "FUNCTIONS_WORKER_RUNTIME", "value": "dotnet" }, { "name": "AzureWebJobsStorage", "value": "<Storage Account Connection String>" }, { "name": "APP_KIND", "value": "workflowApp" } ] }, "httpsOnly": true } }, { "type": "Microsoft.Web/sites/config", "apiVersion": "2021-02-01", "name": "[concat(parameters('logicAppName'), '/authsettingsV2')]", "location": "[parameters('location')]", "properties": { "platform": { "enabled": true, "runtimeVersion": "~1" }, "globalValidation": { "requireAuthentication": true, "unauthenticatedClientAction": "Return401", "excludedPaths": ["/runtime/*"] }, "identityProviders": { "azureActiveDirectory": { "enabled": true, "registration": { "openIdIssuer": "[concat('https://sts.windows.net/', parameters('tenantID'), '/v2.0')]", "clientId": "parameters('ClientID')", "clientSecretSettingName": "OVERRIDE_USE_MI_FIC_ASSERTION_CLIENTID" }, "login": { "disableWWWAuthenticate": false }, "validation": { "jwtClaimChecks": {}, "allowedAudiences": [], "defaultAuthorizationPolicy": { "allowedPrincipals": {}, "allowedApplications": ["<LIST OF ALLOWED APPLICATIONS ID>"] } } } } }, "dependsOn": [ "[resourceId('Microsoft.Web/sites', parameters('logicAppName'))]" ] } ], "outputs": {} } Key things to notice in the template: requireAuthentication: true and unauthenticatedClientAction: Return401 keep Easy Auth strict for the public surface. excludedPaths: ["/runtime/*"] carves out the runtime endpoints so the SAS-authenticated run-history calls aren’t blocked. allowedApplications lets you whitelist specific AAD app IDs that are allowed to call the workflow. Reference: Microsoft.Web/sites/config — authsettingsV2 (ARM template) · Bicep variant This is the easiest way to add or update Easy Auth on a new or existing Logic App. Approach 2 — REST API call as a post-deployment pipeline step If you’d rather keep your infra template lean (or you’re updating Easy Auth on a Logic App that already exists), add a step to your CI/CD pipeline that calls the App Service authsettingsV2 REST API after the Logic App infra deployment completes. The payload mirrors the properties block from the ARM example above — including excludedPaths: ["/runtime/*"] . This approach is useful when: The Logic App is provisioned by a different pipeline or team than the one owning auth configuration. You need to update Easy Auth settings without redeploying the site. You want to apply environment-specific values (tenant ID, client ID, allowed application list) at release time rather than template-compile time. Reference: Web Apps - Update Auth Settings V2 - REST API (Azure App Service) | Microsoft Learn · GlobalValidation Summary The “inputs/outputs don’t load on run history” symptom after enabling Easy Auth is caused by App Service blocking SAS-authenticated runtime calls before the Logic App runtime can see them. Either allow unauthenticated requests (and let the runtime do all the auth), or keep Easy Auth strict and exclude /runtime/* . Because the portal doesn’t expose excludedPaths , the production-grade fix is to deploy it through CI/CD — either by adding an authsettingsV2 config resource to your ARM template or by calling the App Service auth REST API as a pipeline step after deployment.From Form to Action: A Governed, Event-Driven AI Intake Pipeline with Azure Integration Services
A production-minded reference architecture using Azure Integration Services and Microsoft Foundry to turn document-heavy intake into governed, traceable work. TL;DR: Calling a model is one step in AI-powered intake. Production readiness depends on everything around the model: authenticated entry, controlled model consumption, durable asynchronous processing, explicit failure handling, and one correlation ID carried from the gateway to the final event. This post walks through a permit-intake reference architecture on Azure Integration Services and a companion repository you can run offline, without an Azure subscription. The Problem: Intake is where AI Prototypes Stall Many teams have built an AI prototype that reads a scanned form, extracts the key fields, and returns clean, structured data. That prototype proves the model can do the job. Taking it to production raises a different set of questions: Who is allowed to call this, and how many times per minute? What happens when the model returns a 429 or the CRM is down for maintenance? Which team consumed those tokens? Can you show me everything that happened to application #00417? Who is notified when a record is created, and what breaks when we add another subscriber? None of those questions is about the model, yet each one can decide whether the solution ships. The underlying customer problem is broader than “How do we read a form?” It’s “How do we accept responsibility for a submission, process it reliably across slow or unavailable dependencies, and give applicants and operators a trustworthy status?” That framing moves the design from a single AI call to a governed system of connected services. In this post, I use a fictional county’s building-permit intake as the running example. A resident submits a permit packet, and the county needs to validate it, extract the key fields, score it against intake policy, record it in a case system, and notify the right people, with a complete audit trail. The same shape appears in insurance first notice of loss, benefits enrollment, supplier onboarding, and claims intake. The repository keeps the domain in schemas and configuration: replace the schemas and labels, and keep the boundaries. My thesis is simple: the hard part of production AI intake is connecting the services around the model reliably and under governance, not calling the model. The model is one component of the system. It isn’t the system. Scope note: This is a production-minded reference architecture, not a production-ready template. The people, permit data, identifiers, and URLs in this post are synthetic, and the screenshots and trace rows show only that synthetic data. The repository favors demonstration clarity: public endpoints, simple SKUs, and simulated fallbacks. Architecture at a Glance Figure 1. The governed, event-driven permit-intake flow. One correlation ID follows the permit from the gateway to the published event. The design separates the acceptance path from the processing path. API Management owns the caller-facing contract and hands the work to a queue. Slow or failure-prone work happens after that hand-off. The flow reads left to right: Portal → API Management → Logic App → Service Bus → Function → Case system → Event Grid → Subscribers │ Document Intelligence + Foundry model (through the AI gateway) Responsibility Service Why this service Governed front door and AI gateway Azure API Management One policy boundary for business APIs and model APIs Low-code validation, enrichment, and routing Azure Logic Apps Business-visible run history; easy to change routing rules Durable hand-off and back-pressure Azure Service Bus Retries, duplicate detection, and dead-lettering Processing worker Azure Functions Scales with queue depth; runs the shared orchestrator Field extraction Azure Document Intelligence Layout and key-value extraction from the packet Policy-oriented scoring Azure OpenAI in Microsoft Foundry Models Rubric-based completeness and consistency review Fan-out to downstream consumers Azure Event Grid Decoupled subscribers via CloudEvents One correlation ID across the flow Application Insights End-to-end transactions plus one KQL join Discovery and reuse Azure API Center A catalog of the Permits and model APIs The case-system box is deliberately not a CRM product. The repository’s crm.py is an adapter: an in-memory stub by default, or an HTTP call to whatever CRM_BASE points at. Swap in Dynamics 365 or your records system without changing the orchestration contract. Let’s walk through the design decisions that matter most. API Management is more than a Proxy API Management is often introduced as a proxy. In this architecture, it’s the governance boundary, and it governs two surfaces. Figure 2. One gateway governs both the business API and the model API. Surface 1: The Permits API The Entra-protected variant of the inbound policy (permits-api.policy.xml, abridged) authenticates, throttles, and stamps a correlation ID before any backend code runs: <inbound> <base /> <validate-azure-ad-token tenant-id="{{tenant-id}}" failed-validation-httpcode="401"> <audiences><audience>api://ais-demo-permits</audience></audiences> </validate-azure-ad-token> <rate-limit-by-key calls="60" renewal-period="60" counter-key="@(context.Subscription?.Key ?? context.Request.IpAddress)" /> <set-variable name="correlationId" value="@(context.Request.Headers.GetValueOrDefault("X-Correlation-Id", Guid.NewGuid().ToString()))" /> <set-header name="X-Correlation-Id" exists-action="override"> <value>@((string)context.Variables["correlationId"])</value> </set-header> <set-backend-service backend-id="permit-intake-logicapp" /> </inbound> Three lines of intent are worth calling out: validate-azure-ad-token rejects missing, invalid, or expired Microsoft Entra tokens with a 401 at the edge, so unauthenticated requests are rejected before they reach the backend. It knows the Entra issuers and signing keys for your tenant, so there’s no OpenID configuration URL to maintain. rate-limit-by-key gives each consumer its own budget and returns 429 with Retry-After when it’s exceeded. The correlation ID is created here (or accepted from a trusted caller) and echoed back on the 202 Accepted response. That single value is how you’ll find this permit later. The deployed demo authenticates callers with API Management subscription keys and applies the same rate limit and correlation ID. To adopt the Entra variant, register an app for the api://ais-demo-permits audience, register a backend for the Logic App trigger, and then swap the policy. Surface 2: The Model API (The AI Gateway) The Function doesn’t call the model endpoint directly. It calls the Azure OpenAI v1 API through API Management, where a second policy applies (abridged): <inbound> <base /> <llm-content-safety backend-id="content-safety-backend" shield-prompt="true"> <categories output-type="EightSeverityLevels"> <category name="Hate" threshold="4" /> <category name="SelfHarm" threshold="4" /> <category name="Sexual" threshold="4" /> <category name="Violence" threshold="4" /> </categories> </llm-content-safety> <llm-token-limit counter-key="@(context.Subscription?.Id ?? "anonymous")" tokens-per-minute="20000" token-quota="2000000" token-quota-period="Monthly" estimate-prompt-tokens="false" /> <llm-emit-token-metric namespace="ais-demo-ai-gateway"> <dimension name="Subscription" value="@(context.Subscription?.Name ?? "unknown")" /> <dimension name="Department" value="@(context.Request.Headers.GetValueOrDefault("x-dept", "unknown"))" /> </llm-emit-token-metric> <set-header name="api-key" exists-action="delete" /> <authentication-managed-identity resource="https://cognitiveservices.azure.com" /> <set-backend-service backend-id="foundry-models-backend" /> </inbound> In order, that policy: llm-content-safety sends the prompt to Azure AI Content Safety, with Prompt Shields for injection attempts, and returns 403 for prompts that exceed the configured thresholds, before they reach the model. llm-token-limit gives each consumer a tokens-per-minute budget (429) and a monthly token quota (403). llm-emit-token-metric publishes token usage to Application Insights with a department dimension for showback or chargeback. Managed identity authenticates the gateway to the model. The caller’s API Management subscription key is stripped, and local (key) auth is disabled on the Foundry resource, so the Function doesn’t hold a model key, which helps reduce the risk of key leakage. The backend also has a circuit breaker that trips after three 429 or 5xx responses within a minute, pauses calls for a minute (or for the Retry-After period the model returns), and then resumes. The repository includes sample KQL for token monitoring and chargeback views. The key point: conventional APIs and AI endpoints share one governed boundary. Your security team reviews one set of policies, and your platform team gets one place to see who is calling what. Discovery: Azure API Center API Management governs runtime traffic; Azure API Center is where people find the APIs. The repository links API Center to API Management, so the Permits APIs and the model API are cataloged with their definitions, lifecycle stage, and environment. Before a team builds another intake API or model proxy, they search the catalog and still call API Management at runtime. API Center isn’t on the request path. Why the Flow is Asynchronous The Permits API returns 202 Accepted with a correlation ID. It doesn’t wait for extraction, scoring, or the case system. That’s deliberate: document analysis, model calls, record writes, and notifications all have different latency and failure behavior, and holding the caller’s request open couples the caller to each of them. Governance boundary: 202 means the platform durably accepted responsibility for the permit. It doesn’t mean extraction succeeded, a model approved anything, or a record was committed. The repository enforces that literally. On the direct route (POST /permits), API Management writes to Service Bus and checks the answer before it says yes: <send-request mode="new" response-variable-name="sbresponse" timeout="20" ignore-error="true"> <!-- POST to https://{namespace}.servicebus.windows.net/permits-in/messages with managed identity --> </send-request> <choose> <when condition="@(context.Variables.GetValueOrDefault<IResponse>("sbresponse") == null || context.Variables.GetValueOrDefault<IResponse>("sbresponse").StatusCode != 201)"> <return-response> <set-status code="503" reason="Service Unavailable" /> <!-- plus Retry-After --> </return-response> </when> </choose> <!-- only now: return 202 Accepted with X-Correlation-Id --> If Service Bus doesn’t confirm the write (an error status, a timeout, or no connection), the caller gets 503 with Retry-After, not a 202 for work that wasn’t queued. Logic Apps: Validate, Enrich, Route The Logic App workflow checks the payload, attaches the correlation ID, and hands the message to Service Bus with its own managed identity. If required fields are missing, it returns 400 immediately. Here’s the send step: "Send_to_Service_Bus": { "type": "Http", "inputs": { "method": "POST", "uri": "https://@{parameters('serviceBusNamespace')}.servicebus.windows.net/@{parameters('permitsQueue')}/messages", "headers": { "BrokerProperties": "@{string(outputs('Broker_properties'))}" }, "body": "@outputs('Enrich_message')", "authentication": { "type": "ManagedServiceIdentity", "audience": "https://servicebus.azure.net" } } } A preceding Broker_properties step sets MessageId to the parcel number and CorrelationId to the request’s correlation ID. Bicep loads this same workflow JSON when it deploys the Logic App, so each deployment applies the workflow definition from the repository. Business analysts can read the run history in the Azure portal. If the county adds a new permit type or a routing rule, that change happens in the workflow, not in Python. Design choice: The template deploys both routes. POST /permits-orchestrated goes through this Logic App. POST /permits uses a direct-enqueue policy that writes straight to Service Bus with the API Management managed identity; it’s the portal’s default and the route the trace below uses. Use the direct route when you don’t need low-code enrichment. Keep the Logic App when business users own the routing rules. Service Bus: The Durable Hand-off The permits-in queue is configured in Bicep with: maxDeliveryCount: 5, a message is delivered up to five times (the first attempt plus four retries) before it’s moved to the dead-letter subqueue. requiresDuplicateDetection: true with a 10-minute window, resubmitting the same messageId (the parcel number) doesn’t create a second message. See duplicate detection. deadLetteringOnMessageExpiration: true, expired messages are kept for inspection instead of being dropped. Functions: One Orchestrator, Many Hosts A Service Bus–triggered Function (Python 3.14 on Flex Consumption) reads the correlation ID from the message properties and runs a framework-agnostic orchestrator. A message without a permit type raises an error, so Service Bus retries it and then moves it to the dead-letter queue. The orchestrator does four things in order: extract → score → record → publish. def process_permit(permit: dict, correlation_id: str) -> ProcessResult: extracted = document_intelligence.extract_fields(permit) # Document Intelligence compliance = ai_gateway.score_compliance(extracted) # model via the API Management AI gateway status = "IntakeReview" if compliance.score >= settings.compliance_threshold else "NeedsAttention" permit_id = crm.create_permit_record(extracted, compliance, correlation_id, status) event_grid.publish_permit_created(PermitEvent(permitId=permit_id, complianceScore=compliance.score, correlationId=correlation_id)) ... Notice what the model doesn’t do: it doesn’t approve or deny anything. The score (0–100, against a rubric for completeness, consistency, and policy fit) only decides which human review state the permit lands in, IntakeReview or NeedsAttention, and that state is written to the case record. The call uses the Responses API on gpt-5.4-mini with structured output: the response must match a JSON schema (score, missing, flags), so downstream code receives a consistent, schema-validated shape. There’s no dated api-version to maintain: client = OpenAI( base_url=f"{apim_base}/openai/v1/", api_key=subscription_key, default_headers={"api-key": subscription_key, "x-dept": "permitting"}, ) review = client.responses.parse( model="gpt-5.4-mini", instructions=RUBRIC, input=fields_json, text_format=Review, reasoning={"effort": "low"}, store=False, ).output_parsed The caller authenticates to API Management, not to the model: the api-key header carries the caller’s API Management subscription key (the template renames this API’s subscription-key header to api-key). The OpenAI client requires api_key and also sends it as a bearer token, but the gateway replaces that header with its own managed-identity token before calling the model. For production, swap the subscription key for a Microsoft Entra token (api_key=token_provider) and validate it at the gateway. The same process_permit function is hosted by the Function, by a FastAPI service for the portal, and by the Python SDK walkthrough. That keeps the demo, the tests, and the deployed worker running the same code. Event Grid: Fan-out without Coupling After the CRM write, the Function publishes a PermitCreated CloudEvent. Two subscribers react independently: an analytics/audit queue and, when you supply a webhook URL, a resident notification webhook. Each subscription makes up to 30 delivery attempts over 24 hours. Adding a third subscriber, such as a GIS update or an inspector scheduling system, is a new subscription. It’s not a change to the permit flow. Commands and Events are Different Things Service Bus carries a command: “process this permit.” Event Grid carries a fact: “this permit was created,” published only after the record write succeeds. Keeping them separate makes retries, ownership, and subscriber behavior easier to reason about, a poison message can be retried and dead-lettered without a PermitCreated event going out for work that didn’t finish. Four rules follow: Message identity: a stable message ID (the parcel number) and the correlation ID as a message property. In the repository. Idempotency: a redelivered message must confirm earlier work, not create a duplicate record. Production work. Dead-letter ownership: someone watches the queue, reads the reason codes, and is authorized to replay. Operational. Status: callers need a status resource (accepted, processing, needs review, completed, failed) that doesn’t expose document contents. Production works the repository returns only the correlation ID. How Failures are Handled and What Still Needs Work A production-minded design makes failure behavior explicit before the happy path is trusted. The table separates what the repository does today from what still belongs on the production path: Failure What happens in the repository Still needed for production Caller has no valid token 401 at API Management (Entra policy variant); no backend call Entra validation on every public API Caller exceeds its rate limit 429 with Retry-After Per-consumer products and quotas Payload missing required fields Orchestrated route: 400 from the Logic App, passed back by API Management. Direct route: accepted, then dead-lettered by the Function if type is missing The same validation on the direct route Queue unavailable Direct route: 503 with Retry-After. Orchestrated route: the Logic App run fails and returns an error. Neither returns 202 An alert on enqueue failures Malformed message on the queue Delivered up to five times, then dead-lettered (MaxDeliveryCountExceeded) A named owner and a replay procedure Prompt blocked by content safety, or monthly token quota spent 403 from the gateway; Service Bus redelivers the message, then dead-letters it Route to NeedsAttention with a reason instead of dead-lettering Model unavailable (429 or 5xx from the gateway or model) The OpenAI client retries twice, then Service Bus redelivers the message and finally dead-letters it. The backend circuit breaker pauses calls to the model while it’s tripped Route to NeedsAttention with the reason model_unavailable, keeping the deterministic validation results Case system unavailable The Function fails before publishing; the message is redelivered An idempotency key on the record write Event Grid unavailable after the record write The Function fails; a retry can repeat the record write A transactional outbox for the event A notification subscriber is down Event Grid retries that subscriber only (30 attempts over 24 hours) — Two rows deserve a closer look. Model unavailable: today, a model failure retries and then dead-letters the permit. A better design keeps the deterministic validation results, routes the permit to NeedsAttention with a reason such as model_unavailable, and never treats a missing score as approval. Case system unavailable: the record write is the commit point for PermitCreated, so the event must never go out before it. Idempotency keys plus an outbox let a committed record and its event be reconciled. A prototype doesn’t need these safeguards; a production service does. AI is Optional and Bounded The non-AI capabilities like durable acceptance, extraction, deterministic validation, the case record, and events are useful with generative AI turned off. The model’s score is advisory: it prioritizes review and surfaces gaps. It must never quietly become the approval decision. Extraction output is evidence to validate, not ground truth. Deterministic rules own required fields, allowed values, and hard policy constraints. In the repository, the Logic App rejects a packet without name or type, and the Function dead-letters a message without type. The model doesn’t enforce either rule. The model’s output is schema-constrained (score, missing, flags) and labeled advisory. Low scores, conflicting evidence, and model failures route to people. Logs carry identifiers and stage outcomes, not document bodies. Before any real workload, evaluate the scorer in Microsoft Foundry with synthetic or properly governed labeled data. The scorer is a direct model call through API Management, not a Foundry agent, so use dataset-based evaluators and graders, and keep an authorized person in the loop for consequential decisions. Trace One Permit End to End Governance is only useful if you can prove what happened. Here’s one synthetic permit created through the demo environment. Submit. The client posts the permit to API Management: { "name": "[Applicant Name]", "type": "Building", "parcel": "AIS-TT-102242", "applicantEmail": "[Applicant Email]" } Govern and accept durably. On the direct /permits route, API Management applies its policies, stamps a correlation ID, writes the message to permits-in, and only after Service Bus answers 201, returns 202 Accepted with X-Correlation-Id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx. Process. The Function picks up the message and extracts the fields. This run had no document attached, so it used the repository’s synthetic extraction fallback; attach a document URL to exercise Document Intelligence. Score, behind content safety. The Function calls the model through the AI gateway. Content Safety and Prompt Shields screen the prompt first; then gpt-5.4-mini returns a score of 22 and lists missing applicant contact details and a project description. Status: NeedsAttention, which is the expected result for a packet missing those details. (Simulated mode scores the same packet 100.) Record and publish. The case-system adapter creates P-E6980B0C, and the Function publishes PermitCreated; Event Grid delivers it to the analytics queue. Reconstruct. One query returns the whole journey. The portal shows the same journey to a business audience: Figure 3. The portal’s processing result and hop-by-hop trace. This screenshot is from simulated mode, so all values are synthetic and the applicant is shown as a placeholder. In Application Insights the journey is two operations. The intake operation is the API Management request and its Service Bus write. The processing operation is one end-to-end transaction: the Function, its call back through the AI gateway, the Content Safety checks, the model call, and the Event Grid publish. The Service Bus hop doesn’t carry W3C trace context, so the correlation ID is the join key, API Management logs it as a header, and the Function’s log lines name it. This query finds the operations that mention it: let cid = '<correlation-id>'; let hits = union AppRequests, AppDependencies, AppTraces, AppExceptions | where OperationId == cid or Message has cid or tostring(Properties) has cid; let ops = hits | where isnotempty(OperationId) and OperationId != '00000000000000000000000000000000' | distinct OperationId; union (union AppRequests, AppDependencies, AppExceptions | where OperationId in (ops)), (hits | where Type == 'AppTraces') | project TimeGenerated, Type, Name = coalesce(Name, Message, OuterMessage), ResultCode, DurationMs, AppRoleName | order by TimeGenerated asc For the permit above, it returned: Operation Hop Component Result Duration (ms) Intake POST /permits API Management 202 1,471 Intake POST /permits-in/messages Service Bus enqueue 201 177 Processing ServiceBusProcessor.ProcessMessage Azure Functions — 5,875 Processing POST /openai/v1/responses AI gateway (called by the Function) 200 4,542 Processing POST /contentsafety/text:analyze Content Safety 200 777 Processing POST /contentsafety/text:shieldPrompt Prompt Shields 200 235 Processing POST /openai/v1/responses Foundry model (gpt-5.4-mini) 200 2,705 Processing POST /api/events Event Grid publish 200 83 Durations come from one run in a demo environment, including cold starts. They aren’t performance figures. Figure 4. The processing operation for the same permit in Application Insights. The durations match the table above. Resource names and tenant identifiers are redacted. When a caseworker asks, “What happened to application #00417?”, the answer can come from one query instead of separate log searches across teams. Run it Locally, then Deploy it The repository is designed so you can understand the architecture before you spend anything on Azure. 1. Offline Simulation (no Azure Subscription) uv sync --extra dev # Python 3.14 cp .env.example .env # SIMULATED_MODE=true by default uv run ais-demo # runs steps B1–B8 end to end In simulated mode, each adapter (Service Bus, Document Intelligence, the model, CRM, Event Grid, Azure Monitor) is replaced by an in-memory stand-in with the same interface. The walkthrough submits a permit, enqueues it, extracts and scores it, writes the record, publishes the event, dead-letters a deliberately malformed message, and prints the correlated trace. The test suite (uv run pytest) covers the same paths. To see the business view, start the API and portal together: ./scripts/setup.sh ./scripts/app.sh start # API on :8000, portal on :5173 (Node.js 24 LTS) 2. Same Interface, Azure-backed Adapters Each adapter module checks one setting: if settings.simulated_mode or not settings.servicebus_fqdn: return _consume_simulated(handler) return _consume_live(handler, settings) # azure-servicebus + DefaultAzureCredential Set SIMULATED_MODE=false, provide the endpoints, and the same orchestrator talks to real services. Live adapters authenticate with DefaultAzureCredential, so the deployed Function uses its managed identity for Service Bus, Document Intelligence, Event Grid, and Azure Monitor. Both Python hosts export OpenTelemetry to Application Insights, and the Function’s log lines name the correlation ID. 3. Deploy with Bicep and Clean up az group create -n rg-ais-demo -l eastus2 az deployment group what-if -g rg-ais-demo \ --template-file infra/main.bicep --parameters infra/main.bicepparam az deployment group create -g rg-ais-demo \ --template-file infra/main.bicep --parameters infra/main.bicepparam # or: azd provision --preview && azd provision One deployment creates and wires the whole stack: Service Bus and Event Grid (with the analytics subscription, plus the notification webhook subscription when you pass notificationWebhookUrl), Document Intelligence, a Microsoft Foundry resource with the gpt-5.4-mini deployment, the Logic App workflow, a Flex Consumption Function App on Python 3.14, API Management with all three APIs (/permits, /permits-orchestrated, and /openai) and their policies, API Center, and the managed-identity role assignments it needs. Local (key) auth is disabled on Service Bus, Event Grid, Document Intelligence, and the Foundry resource. The template defaults to the BasicV2 tier of API Management; the sample main.bicepparam sets the classic Developer tier to match the existing demo environment, so change apimSku for a new environment. For a faster inner loop, pass deployApim=false. After provisioning, publish the Function code; the deployment guide has the details, and a GitHub Actions workflow runs the same what-if and provision steps with OpenID Connect. When you’re done: az group delete -n rg-ais-demo --yes --no-wait The repository also includes a demo track that tells the same story two ways: an Azure portal click-through for business stakeholders (steps A1–A15) and a Python SDK walkthrough for engineers (steps B1–B8). Production Boundaries: What this Reference doesn’t Do This repository is a production-minded reference architecture: it anticipates production concerns while staying candid about what it doesn’t prove. A production path starts from your organization’s requirements and platform standards. Here’s the gap: Area In the repository Before production Networking Public endpoints Private endpoints, virtual network integration, and a WAF in front of internal API Management (reference architecture) Identity Managed identity to Service Bus, Event Grid, Document Intelligence, and the Foundry resource, with local auth disabled; API Management subscription keys for callers (an Entra token policy is provided) Microsoft Entra token validation on every public API; the Function’s API Management subscription key in Key Vault or replaced by Entra auth AI safety Content Safety and Prompt Shields at the gateway; structured output; advisory-only scoring Tuned thresholds and blocklists, response-side checks, and offline and continuous evaluation gated in CI Data retention In-memory or simulated CRM A real system of record with retention, residency, and deletion policies agreed with records owners Consistency Retries, duplicate detection, and dead-lettering Idempotency keys and an outbox for the record write and event publish Caller status The correlation ID A status resource (accepted, processing, needs review, completed, failed) Access control One demo subscription Per-consumer products, least-privilege RBAC, and separated duties for operators and reviewers Operational ownership Demo scripts Dashboards, alerts on dead-letter depth and token budgets, runbooks, and named owners for every queue Human review Score routes to a review state Documented reviewer workflow, override capture, and periodic sampling of AI-assisted decisions Figure 5. The same services in a network-isolated API Management landing zone. The repository’s production path maps each of these items to the Azure Well-Architected Framework pillars. It also sketches how the AI gateway grows into a multi-region front door with backend pools, circuit breakers, and semantic caching, without changing the governance policies you already have. Map the Article to the Repository Article Repository location Shared pipeline src/ais_demo/orchestrator.py Governed intake (direct, orchestrated, Entra variant) apim/policies/permits-api*.xml AI gateway apim/policies/aoai-api.policy.xml Logic App workflow integration/logicapp/permit-intake-workflow.json Durable command and dead-lettering src/ais_demo/integrations/service_bus.py Extraction src/ais_demo/integrations/document_intelligence.py Advisory scoring src/ais_demo/integrations/ai_gateway.py Case-system adapter src/ais_demo/integrations/crm.py Events src/ais_demo/integrations/event_grid.py Trace join src/ais_demo/integrations/monitor.py Infrastructure infra/main.bicep and infra/modules/ Runbooks docs/deployment-guide.md and docs/demo-track.md Production path docs/production-path.md Key Takeaways Put the model behind the same gateway as your APIs. Content safety, token limits, usage metrics, and managed identity help turn model access into something you can govern and attribute. Accept fast, process durably and mean it. Return 202 only after the queue confirms the message. That helps shield residents from downstream outages and gives operators a dead-letter queue to inspect instead of a lost request. Keep AI advisory. Let the model route work to people. Don’t let it make the decision. Create one correlation ID at the edge and carry it through each hop. It’s one of the simplest audit trails you can build. Decouple what happens next. Event Grid lets new consumers subscribe without touching the intake flow. What to do Next Agree on the acceptance contract: exactly when 202 is returned and how callers check status. Run the simulated portal and Python walkthroughs with one synthetic correlation ID. Test the failure paths: queue unavailable, poison message, model unavailable, case system unavailable, and a trace gap. Add idempotent record writes and an outbox for event publication. Evaluate the advisory model separately from deterministic rules and human approval. Complete an architecture, privacy, security, and Well-Architected review for your subscription before using real data. Try It Repository: github.com/honestypugh2/ais-demo. Start with uv run ais-demo, no Azure subscription required. Adapt it: Change the schemas in src/ais_demo/schemas/permit.py, update USE_CASE_PROFILE and the samples in data/, and keep the topology. Go deeper: AI gateway capabilities in API Management · Service Bus dead-letter queues · Event-driven architecture style · Investigate transactions in Application Insights Related reading: Grounding Copilot Studio Agents with Azure AI Search and Foundry IQ Models will change. The work around them is what moves intake from form to action: a governed front door, durable hand-offs, advisory scoring, and one correlation ID from submission to the final event. Clone the repository, run it offline, and adapt the schemas to your own intake process. Comments and questions are welcome below. The sample code in this post and the companion repository is provided "as is" under the MIT license for demonstration purposes. It uses synthetic data only and isn't intended for production use without additional security, reliability, and compliance review. Nothing in this post is legal, compliance, security, or deployment assurance, and it doesn't represent a customer implementation. The county and applicant in this example are fictional. Check product availability, quotas, model access, and regional capabilities for your own subscription.579Views0likes0CommentsBring Azure Logic Apps connectors into your .NET applications with the Azure Connectors SDK
Modern business applications rarely work in isolation. An order exception might need an email, a support case might need a Teams notification, and a completed document might need to be stored in SharePoint. Developers can build each integration directly against a service API, but that also means owning different authentication models, request and response shapes, pagination rules, and error handling for every service. The Azure Connectors SDK brings the typed experience of a .NET client library to Connector Namespace, which makes the Logic Apps and Power Platform connector runtime available to developers as a programmable integration layer. Your application can call connector operations through generated clients and models while Azure manages the connection to the external service. In this post, we will build a small Azure function app that reacts to a new email through a Connector trigger and sends a formatted review email through the Office 365 Outlook connector. The same pattern can then be extended to many other business systems. Preview: Azure Connectors SDK is currently in preview. Preview features are provided without a service-level agreement and are not recommended for production workloads. APIs and setup steps can change before general availability. Why this matters Integration code often starts with one HTTP call and grows into a collection of service-specific concerns. The Azure Connectors SDK gives .NET developers: Typed clients, request models, and response models generated from connector contracts Async operations with cancellation-token support Azure credential integration for authenticating the calling application Consistent connector exceptions and diagnostics Built-in retry support for transient failures Pagination, binary payload, and dynamic-schema support where connectors expose them OpenTelemetry integration for tracing connector calls Access to a broad connector ecosystem that includes Microsoft 365, Azure services, data platforms, storage, messaging, and SaaS applications The SDK does not put external-service credentials in your application. Instead, your code authenticates to a Connector Namespace connection. That connection holds the authorization for Office 365 Outlook or another target service. Scenario: notify operations about an order exception Imagine an order service that flags transactions for manual review by sending an email to an Office 365 mailbox. The subject identifies the order and the body briefly explains the exception: To: orders@contoso.com Subject: Order exception: SO-10482 Body: Customer requested a delivery-address change after payment. Connector Namespace polls the mailbox for new messages matching the subject filter and calls an Azure function app's Connector trigger. The function reads the typed email payload and sends a formatted review email to a separate operations inbox. Unlike an HTTP-triggered function, there is no application endpoint or 202 Accepted response to invoke. Prerequisites You need: An Azure subscription in which Connector Namespace is available Permission to create Connector Namespace resources and connections .NET 10 SDK Azure Functions Core Tools v4 Azure CLI Azure Developer CLI ( azd ) for deployment, or an existing .NET 10 isolated-worker function app An Office 365 account that can authorize the connection and send email At the time of writing, Connector Namespace is available in a limited set of preview regions. Confirm current region availability before creating the resource. 1. Create an Office 365 connection First sign in and select the subscription that will own the Connector Namespace: az login az account set --subscription "<subscription-id>" $subscriptionId = "<subscription-id>" $resourceGroup = "<resource-group>" $namespaceName = "<connector-namespace-name>" $connectionName = "office365-orders" $location = "<supported-azure-region>" $apiVersion = "2026-05-01-preview" $nsId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.Web/connectorGateways/$namespaceName" Create a Connector Namespace with a system-assigned managed identity: $namespace = @{ location = $location identity = @{ type = "SystemAssigned" } properties = @{} } | ConvertTo-Json -Depth 5 -Compress $tempFile = Join-Path $env:TEMP "connector-namespace.json" [System.IO.File]::WriteAllText($tempFile, $namespace) az rest --method PUT ` --uri "https://management.azure.com${nsId}?api-version=$apiVersion" ` --body "@$tempFile" ` --headers "Content-Type=application/json" ` --output none Remove-Item $tempFile Create the Office 365 connection: $connection = @{ properties = @{ connectorName = "office365" } } | ConvertTo-Json -Depth 5 -Compress $tempFile = Join-Path $env:TEMP "connector-connection.json" [System.IO.File]::WriteAllText($tempFile, $connection) az rest --method PUT ` --uri "https://management.azure.com${nsId}/connections/${connectionName}?api-version=$apiVersion" ` --body "@$tempFile" ` --headers "Content-Type=application/json" ` --output none Remove-Item $tempFile The new connection is not authorized yet. Request an OAuth consent link and open it in your browser: $consentRequest = @{ parameters = @( @{ redirectUrl = "https://portal.azure.com" parameterName = "token" } ) } | ConvertTo-Json -Depth 5 -Compress $tempFile = Join-Path $env:TEMP "connector-consent.json" [System.IO.File]::WriteAllText($tempFile, $consentRequest) $consent = az rest --method POST ` --uri "https://management.azure.com${nsId}/connections/${connectionName}/listConsentLinks?api-version=$apiVersion" ` --body "@$tempFile" ` --headers "Content-Type=application/json" ` --output json | ConvertFrom-Json Remove-Item $tempFile Start-Process $consent.value[0].link Complete the sign-in and consent flow. Then verify that the connection reports Connected : az rest --method GET ` --uri "https://management.azure.com${nsId}/connections/${connectionName}?api-version=$apiVersion" ` --output json | ConvertFrom-Json | Select-Object -ExpandProperty properties | Select-Object -ExpandProperty statuses 2. Allow your local identity to call the connection OAuth consent authorizes the connection to call Office 365. A separate access policy authorizes your application to call the connection. This distinction is important: without the policy, the runtime call fails with HTTP 403 and a missing connection ACL message. Add an access policy for the identity currently signed in to Azure CLI: $userObjectId = az ad signed-in-user show --query id --output tsv $tenantId = az account show --query tenantId --output tsv $policy = @{ properties = @{ principal = @{ type = "ActiveDirectory" identity = @{ objectId = $userObjectId tenantId = $tenantId } } } } | ConvertTo-Json -Depth 6 -Compress $tempFile = Join-Path $env:TEMP "connector-policy.json" [System.IO.File]::WriteAllText($tempFile, $policy) az rest --method PUT ` --uri "https://management.azure.com${nsId}/connections/${connectionName}/accessPolicies/local-dev?api-version=$apiVersion" ` --body "@$tempFile" ` --headers "Content-Type=application/json" ` --output none Remove-Item $tempFile Access-policy changes can take a few minutes to reach the connector runtime. Finally, retrieve the connection runtime URL. Treat this value as application configuration rather than source code: $connection = az rest --method GET ` --uri "https://management.azure.com${nsId}/connections/${connectionName}?api-version=$apiVersion" ` --output json | ConvertFrom-Json $connectionRuntimeUrl = $connection.properties.connectionRuntimeUrl 3. Create the Azure function app Create an isolated-worker function app with the current Core Tools template. Some Core Tools v4 versions do not offer net10.0 as a func init --target-framework option; use the .NET 9 template, then change the generated project's TargetFramework to net10.0 before building: func init ConnectorsSdkOrderAlerts --worker-runtime dotnet-isolated --target-framework net9.0 Set-Location ConnectorsSdkOrderAlerts In ConnectorsSdkOrderAlerts.csproj , set: <TargetFramework>net10.0</TargetFramework> Add the connector packages: dotnet add package Azure.Connectors.Sdk --version 0.13.0-preview.1 dotnet add package Azure.Identity dotnet add package Microsoft.Azure.Functions.Worker.Extensions.Connector --version 0.2.0-alpha Register an Azure credential and only the connector client this function needs. DefaultAzureCredential can use your Azure CLI identity locally and the function app's managed identity in Azure: using Azure.Connectors.Sdk; using Azure.Core; using Azure.Identity; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; var host = new HostBuilder() .ConfigureFunctionsWorkerDefaults() .ConfigureServices((hostContext, services) => { services.AddSingleton<TokenCredential>(new DefaultAzureCredential()); services.AddOffice365Client( hostContext.Configuration.GetSection("Connectors:Office365")); }) .Build(); host.Run(); Add the function. The Connector trigger binds the OnNewEmailV3 callback to a typed payload. Filter the subject again in code, HTML-encode untrusted email fields, and send the review message through the generated SendEmailInput model: using System.Text.Encodings.Web; using Azure.Connectors.Sdk.Office365; using Azure.Connectors.Sdk.Office365.Models; using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Extensions.Connector; public sealed class OperationalAlertFunctions { private const string SubjectPrefix = "Order exception:"; private readonly Office365Client _office365Client; public OperationalAlertFunctions(Office365Client office365Client) { this._office365Client = office365Client; } [Function("OnOrderExceptionEmail")] public async Task OnOrderExceptionEmailAsync( [ConnectorTrigger] Office365OnNewEmailTriggerPayload payload, CancellationToken cancellationToken) { foreach (var message in payload.Body?.Value ?? []) { if (message?.Subject?.StartsWith( OperationalAlertFunctions.SubjectPrefix, StringComparison.OrdinalIgnoreCase) != true) { continue; } var orderId = message.Subject[OperationalAlertFunctions.SubjectPrefix.Length..].Trim(); if (string.IsNullOrWhiteSpace(orderId)) { continue; } var email = new SendEmailInput { To = "operations@contoso.com", Subject = $"Order {orderId} requires review", Body = "<h2>Order review required</h2>" + $"<p><strong>Order:</strong> {HtmlEncoder.Default.Encode(orderId)}</p>" + $"<p><strong>From:</strong> {HtmlEncoder.Default.Encode(message.From ?? string.Empty)}</p>" + $"<p><strong>Reason:</strong> {HtmlEncoder.Default.Encode(message.BodyPreview ?? string.Empty)}</p>" }; await this._office365Client.SendEmailAsync(email, cancellationToken); } } } Use a monitored mailbox or folder separate from the operations inbox. Keep the outgoing subject different from the trigger's subject filter so the notification cannot trigger itself. For production workloads, account for repeated callbacks and partial failures within a batch before performing non-idempotent actions such as sending mail. 4. Deploy and register the Connector trigger Keep the runtime URL out of source control. Set it for local development, then deploy the function app with a system-assigned managed identity and the same setting in its application configuration: $env:Connectors__Office365__ConnectionRuntimeUrl = $connectionRuntimeUrl The public Office 365 connector-trigger sample is a downloadable .NET 10 function app with deployment infrastructure, an OnNewEmail binding, and post-deploy trigger registration. Use its azd up workflow or deploy this function app through your existing pipeline. A locally running Functions host is not reachable by the Connector Namespace polling callback unless you provide a secure public callback endpoint. Once the function app is deployed, add its managed identity to the connection's access policies, just as you added your CLI identity for local development. For a system-assigned identity, get its principal ID and use it in the access policy from step 2 instead of $userObjectId : $functionAppName = "<function-app-name>" $functionObjectId = az functionapp identity show ` --resource-group $resourceGroup --name $functionAppName ` --query principalId --output tsv $policy = @{ properties = @{ principal = @{ type = "ActiveDirectory" identity = @{ objectId = $functionObjectId tenantId = $tenantId } } } } | ConvertTo-Json -Depth 6 -Compress $tempFile = [System.IO.Path]::GetTempFileName() try { [System.IO.File]::WriteAllText($tempFile, $policy) az rest --method PUT ` --uri "https://management.azure.com${nsId}/connections/${connectionName}/accessPolicies/order-alert-function?api-version=$apiVersion" ` --body "@$tempFile" ` --headers "Content-Type=application/json" ` --output none } finally { Remove-Item $tempFile } Obtain the Connector extension's system key and the function app's actual default hostname, then construct the callback URL for the deployed function. Do not assume that the hostname is <function-app-name>.azurewebsites.net ; the default hostname format can vary: $connectorExtensionKey = az functionapp keys list ` --resource-group $resourceGroup --name $functionAppName ` --query "systemKeys.connector_extension" --output tsv $functionAppHostname = az functionapp show ` --resource-group $resourceGroup --name $functionAppName ` --query "defaultHostName" --output tsv $callbackUrl = "https://$functionAppHostname/runtime/webhooks/connector?functionName=OnOrderExceptionEmail&code=$connectorExtensionKey" The system key is a secret. Do not log, publish, or commit the callback URL. Create the Office 365 polling trigger config using the same connection and a subject filter matching the incoming order messages: $triggerConfig = @{ properties = @{ operationName = "OnNewEmailV3" connectionDetails = @{ connectorName = "office365" connectionName = $connectionName } notificationDetails = @{ callbackUrl = $callbackUrl httpMethod = "Post" } parameters = @( @{ name = "folderPath"; value = "Inbox" } @{ name = "subjectFilter"; value = "Order exception:" } ) metadata = @{ destinationType = "functionApp" functionAppName = $functionAppName functionAppResourceGroup = $resourceGroup functionAppSubscriptionId = $subscriptionId functionName = "OnOrderExceptionEmail" recurrenceFrequency = "Minute" recurrenceInterval = "5" } } } | ConvertTo-Json -Depth 6 -Compress $tempFile = [System.IO.Path]::GetTempFileName() try { [System.IO.File]::WriteAllText($tempFile, $triggerConfig) az rest --method PUT ` --uri "https://management.azure.com${nsId}/triggerConfigs/order-exception-email?api-version=$apiVersion" ` --body "@$tempFile" ` --headers "Content-Type=application/json" ` --output none } finally { Remove-Item $tempFile } Confirm that the trigger config reports Enabled . Send a test email to the monitored mailbox, and allow for the polling interval before checking the function logs and the operations inbox: az rest --method GET ` --uri "https://management.azure.com${nsId}/triggerConfigs/order-exception-email?api-version=$apiVersion" ` --query "properties.{operation:operationName,state:state}" ` --output table Confirm all three outcomes before considering the test complete: The trigger config is Enabled and the function logs show the invocation. The operations inbox receives a review email with the expected order ID and reason. Unrelated messages do not produce review emails. From local development to Azure For a deployed function app, use its managed identity instead of a developer identity: Enable a system-assigned or user-assigned managed identity on the function app. Add that identity as an access policy on the Connector Namespace connection. Register DefaultAzureCredential or ManagedIdentityCredential as the TokenCredential . Store the connection runtime URL in function app configuration. Protect the Connector trigger callback with the Connector extension system key; use a stronger authorization model for production as appropriate. The external-service credential remains in the connector connection. The function app presents its Azure identity when it calls the runtime URL. The Connector Namespace uses the callback URL and its system key to invoke the function. Go beyond email The order-alert example is intentionally small, but the programming model supports much broader integration scenarios: Microsoft 365: work with Outlook, SharePoint, Teams, OneDrive, Excel, Planner, Forms, and Microsoft Entra ID-backed operations. Azure services: connect to Blob Storage, queues, tables, Event Grid, Event Hubs, Service Bus, Key Vault, Azure Monitor Logs, and Azure Data Factory. Business applications: integrate with Salesforce, Dynamics 365, Jira, ServiceNow-style workflows, DocuSign, Zendesk, and other SaaS systems represented in the connector catalog. Event-driven applications: register polling triggers that call back to an Azure function app when connector events occur. Data-rich APIs: consume paginated operations, binary content, and operations whose input or output schema is resolved dynamically. Observable integrations: capture connector activity in distributed traces with OpenTelemetry. Because connector clients are typed, developers can discover operations through IntelliSense and keep connector calls alongside the rest of their application code. The connection layer handles authorization to the external system, while Azure identity and access policies govern which application may use that connection. Troubleshooting The call returns 403 with “missing connection ACL.” The external OAuth connection may be healthy, but the calling Azure identity is not authorized. Add an access policy for the Azure CLI user during local development or the workload managed identity after deployment. Allow time for the policy to propagate. The connection remains in an error state. Complete the OAuth consent flow and query the connection again. Make sure the account used for consent has access to the target service. The client fails during startup because the runtime URL is missing. Make sure Connectors__Office365__ConnectionRuntimeUrl is present in the process environment. In a larger application, register only the connector clients whose configuration is available. Authentication works locally but fails in Azure. The local Azure CLI user and the function app managed identity are different principals. Add a separate connection access policy for the function app identity and use a managed-identity-capable credential in the deployed host. The email trigger does not fire. Verify the trigger config is Enabled , its operation is OnNewEmailV3 , its folderPath and subjectFilter match the test email, and its callback uses the deployed function's OnOrderExceptionEmail name and Connector extension system key. Polling is not instantaneous. Get started Explore the Azure Connectors SDK repository, try the samples, and tell us which connectors and application patterns would be most useful for your team. Azure Connectors SDK for .NET Azure Connectors SDK samples Downloadable Office 365 connector-trigger function app Azure Logic Apps connectors overview Azure Identity client library for .NET581Views0likes0CommentsLogic Apps Aviators Newsletter - June 2026
In this issue: Ace Aviator of the Month News from our product group News from our community Ace Aviator of the Month June 2026's Ace Aviator: Florian De Langhe LinkedIn: https://www.linkedin.com/in/floriandelanghe/ What's your role and title? What are your responsibilities? Lead Expert/Team Lead for the Microsoft Integration team at delaware. I have a wide range of responsibilities: - People management - Resource planning - Design and operate our integration solutions at our customers, what we brand as "SmartLink". Next to this, as many of us, I follow the latest AI news closely to keep up to date and try to stay ahead of the curve. Can you give us some insights into your day-to-day activities? I wear many hats so no two days look the same. That is also what keeps it interesting. A typical day starts with reviewing resource planning across our active projects, followed by a technical design review for a new integration. Sprinkle some one-on-one coaching conversations and research into new technologies/features and you have my day. The balance between People leadership and hands-on technical work is what I enjoy most. What motivates and inspires you to be an active member of the Aviators/Microsoft community? I started out being an active member on the Microsoft Logic App forum 10 years ago. I remember going back and forth with Wagner through the forum posts trying to solve questions. Good times. Integration is one of those disciplines where you're constantly connecting systems, teams, and ideas. What motivates me is seeing how members of our community across different companies and countries solve similar problems in completely different ways. The Aviators community has that right mix of deep technical knowledge and willingness to help each other out. Since discovering Integration and the Microsoft community, I basically never left. Looking back, what advice do you wish you had been given earlier? Document everything and treat documentation as a deliverable, not an afterthought. Early in my career I saw documentation as the boring part that you do after the development work. Now I see it as the leverage point. A well-written design document doesn't just help the next person understand what you built, it compounds. It feeds code generation, easier onboarding of new members and validation with your customers on what and how to build it. What has helped you grow professionally? Two things: 1) Always challenge yourself and your implementations; everything can be better, so I am always pushing myself to keep learning, stay up to date, and think about every idea/solution posted in this community—how it could improve my way of thinking or solutions that I am building/have built. 2) Focus on understanding the integration concepts and patterns. At the end of the day everything is a pattern; it is how you implement where we make the difference. So knowing the base layer itself helps a lot when building integration solutions. If you had a magic wand that could create a feature in Logic Apps, what would it be? To be able to control scaling of the workflow service plans more fine grained. Being able to control this would unlock a lot of use cases, especially for the combination of Logic Apps and Service Bus concurrency and throughput. News from our product group Write Logic Apps in C#: introducing the Logic Apps Standard SDK This article introduces the Logic Apps Standard SDK (Microsoft.Azure.Workflows.Sdk), a code-first way to define Logic Apps Standard workflows in C#. Developers compose workflows using a fluent builder with strongly typed triggers and actions, including both built-in and managed connector operations. The SDK preserves the existing runtime, connectors, monitoring, and run history while changing only the authoring experience. It supports control flow constructs, custom C# code steps, and run-after conditions for fault handling. Guidance covers getting started in VS Code, project layout, local F5 execution, and preview limitations such as no service provider connectors and work-in-progress managed identity support. New AI gateway capabilities in Azure API Management Azure API Management expands its AI gateway with a Unified Model API (preview) that lets clients use a single OpenAI-style format across providers, plus model aliases and discovery. GA updates include support for Anthropic and Google Vertex AI and content safety for MCP and Agent-to-Agent (A2A) traffic. Token observability now tracks cached, reasoning, and thinking tokens in Application Insights. Foundry import adds Anthropic API operations. A2A APIs reach GA with richer diagnostics and availability in classic tiers. Together, these features standardize governance, security, and observability for multi-model, multi-protocol AI applications. 🎉 Automation just became a team sport. Meet Azure Logic Apps Automation. Azure Logic Apps Automation (public preview) is a new SKU that delivers a managed, SaaS-like experience for building and running workflow automations. It keeps the enterprise-grade Logic Apps engine while simplifying onboarding, collaboration, and governance with projects and applications, flexible permissions, and policy inheritance. The experience is AI-native with natural language authoring, first-class agents, tools via MCP, and managed sandboxes. It introduces a modern designer, draft mode, live run history, JavaScript expressions, elastic scale to zero, and knowledge-as-a-service integration—aimed at helping teams prototype quickly and operate securely at scale. 📢 Announcing Knowledge as a Service for Azure Logic Apps Knowledge as a Service (public preview) provides a managed knowledge layer for Logic Apps that turns documents into a ready-to-use knowledge base without building a custom RAG pipeline. The service handles ingestion (parsing, chunking, embeddings) and retrieval (query rewriting, semantic search, ranking) and integrates with agentic workflows in Logic Apps Standard and the Automation SKU. On Standard, teams bring their own vector store and models; on Automation, the platform hosts them on behalf of the user. It supports Entra authentication and focuses on secure, grounded responses for agents and workflows. Better Together: Build Agents in Microsoft Foundry, Automate them with Azure Logic Apps This post outlines a combined stack for agentic applications: Microsoft Foundry for building and hosting agents, and Azure Logic Apps for invoking and orchestrating them. New capabilities let teams create or select Foundry agents directly from the Logic Apps designer, pair any trigger with an agent for autonomous execution, and expose 1,400+ Logic Apps connectors and entire workflows as agent tools. The approach enables agents to act across systems, handle long-running processes, and integrate with enterprise events, making deterministic workflows and AI-driven reasoning work together in production. What's new in Azure API Management at Microsoft Build 2026 This roundup covers Build 2026 updates for API Management and API Center: GA for agent registration, assessment, and Git sync in API Center, plus a data plane MCP server for enterprise discovery. API Management adds GA support for JSON‑RPC agent‑to‑agent (A2A) APIs and extends content safety controls to MCP and A2A flows. Unified Model API enters preview to standardize client integration across model providers, and AI Gateway expands to Anthropic and Vertex AI with broader token metrics. Platform enhancements include multi‑domain and wildcard custom hostnames in v2 tiers and workspace support on the built‑in gateway. Azure Connector Namespaces: managed integration for any Azure compute Azure Connector Namespace (preview) offers a fully managed integration layer that brings the Logic Apps connector ecosystem to any Azure or self‑hosted compute without requiring a workflow engine. Apps call strongly typed SDKs for C#, Node.js, or Python to invoke actions and subscribe to triggers, while the namespace handles auth, token rotation, retries, throttling, and webhook delivery. It also projects connectors as MCP servers for agents, and supports hosted MCP servers like Playwright and Azure SQL. The post details building blocks, scenarios, security, governance, and preview limitations. What's new in Azure Logic Apps at Microsoft Build 2026 This Build 2026 overview highlights Logic Apps Automation (public preview), GA for the Logic Apps MCP Server to expose workflows as MCP tools, direct invocation of Microsoft Foundry agents from Logic Apps, Knowledge as a Service, and code‑first development with the Logic Apps Standard SDK (Codeful Workflows). It also introduces a Migration Agent to help modernize from legacy platforms. The theme is making enterprise‑grade automation more accessible while preserving governance, reliability, and operational controls for production use. Hosted MCP Servers in Connector Namespace (Preview) Hosted MCP servers in Connector Namespace let teams deploy managed, enterprise‑ready MCP servers from a curated catalog in minutes. The platform handles deployment, scaling, authentication (inbound with Entra ID, outbound with managed identity or on‑behalf‑of), availability, and observability via Application Insights. Preview servers include Playwright for browser automation and Azure SQL via Data API Builder, enabling agents to use reliable tools without the overhead of self‑hosting. The post explains setup, benefits over self‑hosted servers, and areas of ongoing investment like catalog expansion and VNet support. MCP Test Console and Git Repository synch in Azure API Center Azure API Center adds a built‑in MCP Test Console in the developer portal and Git repository synchronization for MCP servers and other assets. Developers can validate MCP tools interactively on the Documentation tab and browse server tiles with endpoints and schemas. Git sync keeps the API Center inventory aligned with source‑controlled definitions, with secure access via Key Vault and managed identity. Together, these additions streamline discovery, testing, and governance of MCP assets across the enterprise. Bringing all your Integration workloads to Logic Apps Standard This post outlines Microsoft’s guided path for moving enterprise integration workloads—especially BizTalk—to Azure Logic Apps Standard. It introduces the open-source Logic Apps Migration Agent, which delivers an AI‑assisted, stage‑gated process across discovery, planning, baseline conversion, and continuous validation with human‑in‑the‑loop checkpoints. The workflow integrates with VS Code and GitHub Copilot, supports incremental “flow‑group” migration, and accommodates existing black‑box tests. The article also previews mission‑critical capabilities arriving for Standard and Hybrid (HL7, MLLP, Rules Engine, MSMQ, Oracle DB, flat‑file generation, Integration Accounts, and more), giving teams a repeatable, auditable modernization path with reduced risk. Announcing Microsoft Host Integration Server 2028: Modern connectivity for IBM Mainframes Midranges Host Integration Server 2028 (HIS 2028) is the next HIS release, delivered as a standalone SKU decoupled from BizTalk. It modernizes platform foundations (.NET 10) and, for non‑SNA features, introduces Linux support. New investments include Foundry integration for agent scenarios, REST APIs for DB2 and Transaction Integrator workloads, Entra ID and Azure Arc for hybrid management, a move to Visual Studio Code for designers, and alignment with newer IBM middleware. The post also lists product cleanup and deprecations (e.g., 32‑bit, WMI/WCF, BizTalk adapters), helping enterprises secure, govern, and operate host connectivity for years ahead. Easy Auth Configuration for Logic App Standard through CI/CD Enabling App Service Easy Auth on Logic Apps Standard can break run‑history views because SAS‑based runtime calls are blocked before the Logic Apps engine can validate them. This article explains two remedies: allow unauthenticated requests (so the runtime enforces its own auth), or keep Easy Auth strict and exclude runtime endpoints (e.g., /runtime/*) using authsettingsV2. It provides CI/CD‑ready approaches via ARM/Bicep templates or a post‑deployment REST API call, and highlights key settings such as requireAuthentication, unauthenticatedClientAction, excludedPaths, and allowedApplications. The guidance restores run‑history usability while maintaining enterprise authentication policies. Run Javascript code on Agent Loop Azure Logic Apps Agent Loop now supports a JavaScript code interpreter, extending earlier code‑execution support and enabling reliable computations, validations, and transformations alongside LLMs. The runtime executes generated or pre‑written code inside a V8 isolate using the isolated‑vm library, providing memory limits, timeouts, and failure isolation (not a full sandbox) to reduce blast radius. A worked example shows expense‑validation with agent tools orchestrated in a workflow. For Consumption, attaching an Integration Account provides isolated compute for the interpreter. The capability helps teams combine deterministic steps with agentic reasoning to deliver robust, auditable outcomes. Bulk-configure diagnostic settings on Azure Logic Apps Consumptions LA‑BulkDiag is a single‑file PowerShell script that bulk‑applies diagnostic settings across Logic Apps Consumption in a resource group. It inventories workflows, supports quick scopes (bare/all/pick), verifies destinations, auto‑renames on name collisions, and ships with 129 Pester tests. Presets cover logs, metrics, and workflow‑runtime categories; selection grammar enables non‑interactive runs suitable for CI. The post includes quick‑start commands and clarifies scope: it targets Consumption only (not Standard) and doesn’t configure Event Hub sinks. The result is faster, consistent observability at scale without repetitive portal clicks or accidental overwrites. Clean up idle and always-failing Azure Logic App Consumption LA‑CleanUp is a PowerShell utility that scans a subscription for Logic Apps Consumption workflows, classifying them as Idle (no runs in N days) or AlwaysFailing (runs in the window with zero successes). It can export candidates to CSV, then guide per‑item deletion with y/N/q prompts, reporting final counts. Under the hood, it uses OData filters and $top=1 queries for fast server‑side checks, caches an ARM token once, and intentionally avoids cross‑subscription operations. Scope notes: it doesn’t touch Standard workflows or API connections. The tool reduces noise, costs, and operational drag from abandoned or broken apps. News from our community Spec2Integration Post by Balbir Singh Spec2Integration proposes a spec-driven approach to building Azure Integration Services solutions. The open-source toolkit guides teams from a product brief through specification, modeling, contracts, mapping, and architecture to a deployable implementation targeting Azure Logic Apps, Functions, and related services. It includes governance gates for idempotency, observability, retries, and PII handling, plus a VS Code extension that visualizes pipeline status and the integration representation. Templates and tooling support greenfield projects and BizTalk migrations. The result aims to standardize repeatable steps, reduce failure modes, and accelerate delivery while keeping architectural control outside individual workflows. Stateful Orchestration in Azure: When Logic Apps Break, and What to Do Instead Post by Al Ghoniem, MBA This article examines where stateful orchestration with Azure Logic Apps can fall short and how to design around those gaps. It differentiates execution state from business state and highlights common failure modes: long-running instances, retry-induced duplicates, partial completion across SAP/Oracle/APIs, lost correlation, and unowned DLQs. It then contrasts orchestration choices—stateful Logic Apps, Durable Functions, Service Bus–backed orchestration, and choreography—emphasizing idempotency, correlation, reconciliation, and compensation. The guidance steers architects toward a control and observability layer so production incidents can be traced, replayed, and recovered without relying on workflow run history alone. Logic Apps Announcements at Microsoft Build Video by Sebastian Meyer This video recaps Logic Apps announcements from Microsoft Build with insights from a member of the product team. It highlights newly introduced capabilities and shares resources for deeper dives. Viewers get a concise overview of what’s new, why it matters for integration practitioners, and where to learn more. The discussion points architects toward practical use cases and next steps, making it a useful primer for anyone assessing roadmap impacts on existing or upcoming Azure Integration Services projects. Logic Apps Standard vs. Consumption: Which Plan Should You Choose? Post by Chiranjib Ghatak The article compares Logic Apps Standard and Consumption, explaining differences in hosting models, pricing, networking, and development experience. It outlines when to pick each plan, noting Standard’s single-tenant model, VNet/private endpoints, built-in connectors, and local DevOps workflow, versus Consumption’s pay-per-execution model and simplicity for sporadic or low-volume workloads. It also covers performance trade-offs, stateful vs. stateless options available in Standard, and typical enterprise scenarios where Standard provides predictable costs and better throughput. Azure Connector Namespaces: Managed Connectors Beyond Logic Apps Post by Şahin Özdemir This post introduces Azure Connector Namespaces and previews managed connectors for Azure Functions, extending the Logic Apps connector ecosystem to more compute services. It explains the motivation, how namespaces decouple connectors from workflows, and the benefits: reduced custom code, consistent authentication via managed identity, and reuse of Microsoft-managed integrations. A step-by-step walkthrough shows creating a namespace, adding a managed connector, and using the Azure Connectors .NET SDK in Functions, illustrating how teams can standardize connectivity while keeping business logic in code. Stop working harder and start flowing smarter, with Logic Apps Automation Post by Sonny Gillissen Sonny Gillissen explores Logic Apps Automation, a new, governed experience for building enterprise automations. He explains the Project → Application → Workflow model, dedicated portal (auto.azure.com), and reusable Sandboxes for agent code. The post shows how the AI assistant can scaffold workflows from intent, with Knowledge sources to ground agents, while monitoring and analytics provide visibility. Benefits include familiar Logic Apps design, reduced operational overhead, and scale-to-zero. Current gaps are noted—OBO auth shift, occasional assistant syntax issues, managed vs. built‑in connector choices, no migration tooling yet, and pending VNet/private endpoint support. Stop Using Static Filters! Automate DIXF Exports with Logic App Post by Anitha Eswaran Anitha Eswaran demonstrates how to make DIXF exports in D365FO dynamic using Azure Logic Apps and a small X++ customization. A custom OData action updates the DIXF Definition Group filter at runtime based on a parameter such as Customer Group. A Logic App triggered by a business event parses the input, stores the value, calls the OData action, invokes the standard ExportToPackage API, and then retrieves the download URL via GetExportedPackageUrl to fetch the ZIP with a time‑limited SAS token. Screenshots and code samples illustrate the end‑to‑end flow and implementation details. Logic Apps Agent Loops: Master Class Video by Stephen W Thomas Stephen W Thomas compiles his full Logic Apps Agent Loop series into one master‑class video. It covers getting started with Agent Loop on Logic Apps Standard, a human‑in‑the‑loop pattern used to resolve failed code translations, interactive chat agents with secure website embedding via Easy Auth, and when to choose the Consumption tier for simpler, pay‑as‑you‑go deployments. The chaptered format lets viewers jump to relevant topics. The emphasis is on the orchestration pattern—agents that select and compose tools to achieve goals—offering a practical foundation for teams moving from deterministic workflows toward agentic automation. Forget Sampling — This One host.json Setting Cuts Logic Apps Telemetry Costs by 80% Post by Daniel Jonathan This article tackles high Application Insights ingestion costs in Logic Apps Standard and shows a data‑driven path to reduce spend. Through a controlled experiment, it demonstrates that switching Runtime.ApplicationInsightTelemetryVersion to v2 in host.json delivers ~80% reduction without sacrificing troubleshooting. Further options include disabling dependency tracking (eliminates AppDependencies with the trade‑off of losing per‑call HTTP detail) and using adaptive sampling for marginal additional savings, while excluding exceptions. It also explains why some run‑level telemetry bypasses sampling and how to toggle sampling via an environment variable for short‑term diagnostics. Production Is the Only Truth in Integration Post by Marcelo Gomes This piece reframes integration success through a production‑first lens. It argues that reliability emerges when systems are designed for failure as the norm, not the exception. The article urges separating orchestration from business logic—using tools like Azure Logic Apps for coordination and Azure Functions for rules and transformations—to keep retries safe and evolution predictable. It positions production‑readiness as a design concern, emphasizing idempotency, replay, observability, runbooks, and ownership. The practical outcome is reduced operational risk and cost, more predictable behavior, and greater business trust in automated processes. DevUP Talks #05 – Logic Apps Tips & Tricks with Sandro Pereira Video by Mattias Lögdberg In this session, Sandro Pereira distills practical guidance from real projects to help teams build more resilient Logic Apps. Topics include applying environment‑specific timer conditions, deploying Logic Apps in a disabled state to control activation during releases, and using User‑Managed Identity with Azure Service Bus in Logic Apps Standard. The video focuses on patterns that improve reliability, security, and operational control across environments, offering actionable advice for developers and architects working in Azure Integration Services who want fewer surprises in production and a smoother deployment lifecycle. Logic Apps: Service Bus with User‑Assigned Managed Identity Post by Sandro Pereira This best‑practices guide shows how to configure the Azure Service Bus connector in Logic Apps Standard to use a user‑assigned managed identity. Sandro Pereira explains why system‑assigned identities complicate CI/CD—RBAC can’t be fully declared until the identity exists—then demonstrates a pattern that keeps deployments reproducible. The approach uses app settings for the Service Bus namespace and identity resource ID, a custom serviceProviderConnections entry referencing those settings, and workflow actions bound to that connection. The result is secretless, declarative authentication that avoids RBAC timing issues across environments. Logic App Consumption Bulk Failed Runs Resubmit Tool Post by Sandro Pereira Sandro Pereira introduces a small .NET Windows utility that lists and bulk resubmits failed Logic Apps Consumption runs. After authenticating to Azure, users supply the Logic App name, resource group and subscription. The tool can optionally filter by a date range, otherwise it returns up to 250 failed runs for fast triage. It targets a common pain point the portal features don’t fully streamline and includes a link to the GitHub source so teams can adapt or integrate it into operational workflows. A concise “one‑minute brief” outlines the problem and practical benefits. Control the Initial State of Logic Apps Standard Workflows Post by Sandro Pereira This tip explains how to prevent Logic Apps Standard workflows from starting immediately after deployment—a common production risk. Instead of a state property in ARM/Bicep, the initial state is controlled via App Settings on the underlying App Service. By setting Workflows..FlowState to Disabled (in local.settings.json and/or app settings), teams ensure workflows deploy in a safe, non‑running state. The article outlines the rationale, differences from Consumption, and provides concrete examples and screenshots to adopt the practice across environments.Network Connectivity Check APIs for Logic App Standard
Introduction When your Logic App Standard is integrated with a Virtual Network (VNET), you can use these APIs to troubleshoot connectivity issues to downstream resources like SQL databases, Storage Accounts, Service Bus, Key Vault, and more. The checks run directly from the worker hosting your Logic App, so the results reflect the actual network path your workflows use. API Overview API HTTP Method Route Suffix Purpose ConnectivityCheck POST /connectivityCheck Validates end-to-end connectivity to an Azure resource (SQL, Key Vault, Storage, Service Bus, etc.) DnsCheck POST /dnsCheck Performs DNS resolution for a hostname TcpPingCheck POST /tcpPingCheck Performs a TCP ping to a host and port How to Call Using Azure API Playground Sign in with your Azure account. https://portal.azure.com/#view/Microsoft_Azure_Resources/ArmPlayground.ReactView Use POST method with the URLs below. Instead of API playground you can also use PowerShell or Az Rest URL Pattern Production slot: POST https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{logicAppName}/connectivityCheck?api-version=2026-03-01-preview Deployment slot: POST https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{logicAppName}/slots/{slotName}/connectivityCheck?api-version=2026-03-01-preview Replace connectivityCheck with dnsCheck or tcpPingCheck as needed. all the requests should be Json 1. ConnectivityCheck Tests end-to-end connectivity from your Logic App to an Azure resource. This validates DNS, TCP, and authentication in a single call. Supported Provider Types ProviderType Use For KeyVault Azure Key Vault SQL Azure SQL Database / SQL Server ServiceBus Azure Service Bus EventHubs Azure Event Hubs BlobStorage Azure Blob Storage FileShare Azure File Share (see Port 445 limitation) only tese 443 QueueStorage Azure Queue Storage TableStorage Azure Table Storage Web Any HTTP/HTTPS endpoint Credential Types CredentialType When to Use ConnectionString You have a connection string to provide directly Authentication You have an endpoint URL with username and password CredentialReference You want to reference an existing connection string or app setting by name AppSetting You want to reference an app setting configured on the Logic App ManagedIdentity Your Logic App uses Managed Identity to authenticate Sample Request — Connection String (SQL Database) POST https://management.azure.com/subscriptions/{subId}/resourceGroups/{rg}/providers/Microsoft.Web/sites/{logicAppName}/connectivityCheck?api-version=2026-03-01-preview Content-Type: application/json { "properties": { "providerType": "SQL", "credentials": { "credentialType": "ConnectionString", "connectionString": "Server=tcp:myserver.database.windows.net,1433;Database=mydb;User ID=myuser;Password=mypassword;Encrypt=True;TrustServerCertificate=False;" }, "resourceMetadata": { "entityName": "" } } } Sample Request — App Setting Reference (Service Bus) Use this when your connection string is stored in an app setting on the Logic App (e.g., ServiceBusConnection). { "properties": { "providerType": "ServiceBus", "credentials": { "credentialType": "AppSetting", "appSetting": "ServiceBusConnection" }, "resourceMetadata": { "entityName": "myqueue" } } } Sample Request — Managed Identity (Blob Storage) Use this when your Logic App authenticates using Managed Identity. { "properties": { "providerType": "BlobStorage", "credentials": { "credentialType": "ManagedIdentity", "managedIdentity": { "targetResourceUrl": "https://mystorageaccount.blob.core.windows.net", "clientId": "" } }, "resourceMetadata": { "entityName": "" } } } Tip: Leave clientId empty to use the system-assigned managed identity. Provide a client ID to use a specific user-assigned managed identity. 2. DnsCheck Tests whether a hostname can be resolved from your Logic App's worker. This is useful for verifying private DNS zones and private endpoints are configured correctly. Sample Request POST https://management.azure.com/subscriptions/{subId}/resourceGroups/{rg}/providers/Microsoft.Web/sites/{logicAppName}/dnsCheck?api-version=2026-03-01-preview Content-Type: application/json { "properties": { "dnsName": "myserver.database.windows.net" } } 3. TcpPingCheck Tests whether a TCP connection can be established from your Logic App to a specific host and port. This is useful for checking if a port is open and reachable through your VNET. Sample Request POST https://management.azure.com/subscriptions/{subId}/resourceGroups/{rg}/providers/Microsoft.Web/sites/{logicAppName}/tcpPingCheck?api-version=2026-03-01-preview Content-Type: application/json { "properties": { "host": "myserver.database.windows.net", "port": "1433" } } Port 445 (SMB / Azure File Share) — Known Limitation Port 445 cannot be reliably tested using TcpPingCheck or ConnectivityCheck with the FileShare provider type. Restricted Outgoing Ports Regardless of address, applications cannot connect to anywhere using ports 445, 137, 138, and 139. In other words, even if connecting to a non-private IP address or the address of a virtual network, connections to ports 445, 137, 138, and 139 are not permitted.Announcing General Availability: Azure Logic Apps Standard Custom Code with .NET 8
We’re excited to announce the General Availability (GA) of Custom Code support in Azure Logic Apps Standard with .NET 8. This release marks a significant step forward in enabling developers to build more powerful, flexible, and maintainable integration workflows using familiar .NET tools and practices. With this capability, developers can now embed custom .NET 8 code directly within their Logic Apps Standard workflows. This unlocks advanced logic scenarios, promotes code reuse, and allows seamless integration with existing .NET libraries and services—making it easier than ever to build enterprise-grade solutions on Azure. What’s New in GA This GA release introduces several key enhancements that improve the development experience and expand the capabilities of custom code in Logic Apps: Bring Your Own Packages Developers can now include and manage their own NuGet packages within custom code projects without having to resolve conflicts with the dependencies used by the language worker host. The update includes the ability to load the assembly dependencies of the custom code project into a separate Assembly context allowing you to bring any NET8 compatible dependent assembly versions that your project need. There are only three exceptions to this rule: Microsoft.Extensions.Logging.Abstractions Microsoft.Extensions.DependencyInjection.Abstractions Microsoft.Azure.Functions.Extensions.Workflows.Abstractions Dependency Injection Native Support Custom code now supports native Dependency Injection (DI), enabling better separation of concerns and more testable, maintainable code. This aligns with modern .NET development patterns and simplifies service management within your custom logic. To enable Dependency Injection, developers will need to provide a StartupConfiguration class, defining the list of dependencies: using Microsoft.Azure.Functions.Extensions.Workflows; using Microsoft.Extensions.DependencyInjection; public class StartupConfiguration : IConfigureStartup { /// <summary> /// Configures services for the Azure Functions application. /// </summary> /// <param name="services">The service collection to configure.</param> public void Configure(IServiceCollection services) { // Register the routing service with dependency injection services.AddSingleton<IRoutingService, OrderRoutingService>(); services.AddSingleton<IDiscountService, DiscountService>(); } } You will also need to initialize those register those services during your custom code class constructor: public class MySampleFunction { private readonly ILogger<MySampleFunction> logger; private readonly IRoutingService routingService; private readonly IDiscountService discountService; public MySampleFunction(ILoggerFactory loggerFactory, IRoutingService routingService, IDiscountService discountService) { this.logger = loggerFactory.CreateLogger<MySampleFunction>(); this.routingService = routingService; this.discountService = discountService; } // your function logic here } Improved Authoring Experience The development experience has been significantly enhanced with improved tooling and templates. Whether you're using Visual Studio or Visual Studio Code, you’ll benefit from streamlined scaffolding, local debugging, and deployment workflows that make building and managing custom code faster and more intuitive. The following user experience improvements were added: Local functions metadata are kept between VS Code sessions, so you don't receive validation errors when editing workflows that depend on the local functions. Projects are also built when designer starts, so you don't have to manually update references. New context menu gestures, allowing you to create new local functions or build your functions project directly from the explorer area Unified debugging experience, making it easer for you to debug. We have now a single task for debugging custom code and logic apps, which makes starting a new debug session as easy as pressing F5. Learn More To get started with custom code in Azure Logic Apps Standard, visit the official Microsoft Learn documentation: Create and run custom code in Azure Logic Apps Standard You can also find example code for Dependency injection wsilveiranz/CustomCode-Dependency-Injection1.1KViews1like0CommentsIntroducing Skills in Azure API Center
The problem Modern applications depend on more than APIs. A single AI workflow might call an LLM, invoke an MCP tool, integrate a third-party service, and reference a business capability spanning dozens of endpoints. Without a central inventory, these assets become impossible to discover, easy to duplicate, and painful to govern. Azure API Center — part of the Azure API Management platform — already catalogs models, agents, and MCP servers alongside traditional APIs. Skills extend that foundation to cover reusable AI capabilities. What is a Skill? As AI agents become more capable, organizations need a way to define and govern what those agents can actually do. Skills are the answer. A Skill in Azure API Center is a reusable, registered capability that AI agents can discover and consume to extend their functionality. Each skill is backed by source code — typically hosted in a Git repository — and describes what it does, what APIs or MCP servers it can access, and who owns it. Think of skills as the building blocks of AI agent behavior, promoted into a governed inventory alongside your APIs, MCP servers, models, and agents. Example: A "Code Review Skill" performs automated code reviews using static analysis. It is registered in API Center with a Source URL pointing to its GitHub repo, allowed to access your code analysis API, and discoverable by any AI agent in your organization. How Skills work in API Center Skills can be added to your inventory in two ways: registered manually through the Azure portal, or synchronized automatically from a connected Git repository. Both approaches end up in the same governed catalog, discoverable through the API Center portal. Option 1: Register a Skill manually Use the Azure portal to register a skill directly. Navigate to Inventory > Assets in your API center, select + Register an asset > Skill, and fill in the registration form. Figure 2: Register a skill form in the Azure portal. The form captures everything needed to make a skill discoverable and governable: Field Description Title Display name for the skill (e.g. Code Review Skill). Identification Auto-generated URL slug based on the title. Editable. Summary One-line description of what the skill does. Description Full detail on capabilities, use cases, and expected behavior. Lifecycle stage Current state: Design, Preview, Production, or Deprecated. Source URL Git repository URL for the skill source code. Allowed tools The APIs or MCP servers from your inventory this skill is permitted to access. Enforces governance at the capability level. License Licensing terms: MIT, Apache 2.0, Proprietary, etc. Contact information Owner or support contact for the skill. Governance note: The Allowed tools field is key for AI governance. It explicitly defines which APIs and MCP servers a skill can invoke — preventing uncontrolled access and making security review straightforward. Option 2: Sync Skills from a Git repository For teams managing skills in source control, API Center can integrate directly with a Git repository and synchronize skill information automatically. This is the recommended approach for teams practicing GitOps or managing many skills at scale. Figure 3: Integrating a Git repository to sync skills automatically into API Center. When you configure a Git integration, API Center: Creates an Environment representing the repository as a source of skills Scans for files matching the configured pattern (default: **/skill.md) Syncs matching skills into your inventory and keeps them current as the repo changes For private repositories, a Personal Access Token (PAT) stored in Azure Key Vault is used for authentication. API Center's managed identity retrieves the PAT securely — no credentials are stored in the service itself. Tip: Use the Automatically configure managed identity and assign permissions option when setting up the integration if you haven't pre-configured a managed identity. API Center handles the Key Vault permissions automatically. Discovering Skills in your catalog Once registered — manually or via Git — skills appear in the Inventory > Assets page alongside all other asset types. Linked skills (synced from Git) are visually identified with a link icon, so teams can see at a glance which skills are source-controlled. From the API Center portal, developers and other stakeholders can browse the full skill catalog, filter by lifecycle stage or type, and view detailed information about each skill — including its source URL, allowed tools, and contact information. Figure 4: Skills catalog in API Center portal, showing registered skills and the details related to the skill. Developer experience: The API Center portal gives teams a self-service way to discover approved skills without needing to ask around or search GitHub. The catalog becomes the authoritative source of what's available and what's allowed. Why this matters for AI development teams Skills close a critical gap in AI governance. As organizations deploy AI agents, they need to know — and control — what those agents can do. Without a governed skill registry, capability discovery is ad hoc, reuse is low, and security review is difficult. By bringing skills into Azure API Center alongside APIs, MCP servers, models, and agents, teams get: A single inventory for all the assets AI agents depend on Explicit governance over which resources each skill can access via Allowed tools Automated, source-controlled skill registration via Git integration Discoverability for developers and AI systems through the API Center portal Consistent lifecycle management — Design through Production to Deprecated API Center, as part of the Azure API Management platform and the broader AI Gateway vision, is evolving into the system of record for AI-ready development. Skills are the latest step in that direction. Available now Skills are available today in Azure API Center (preview). To register your first skill: Sign in to the Azure portal and navigate to your API Center instance In the sidebar, select Inventory > Assets Select + Register an asset > Skill Fill in the registration form and select Create → Register and discover skills in Azure API Center (docs) → Set up your API Center portal → Explore the Azure API Management platform2.8KViews0likes2CommentsAzure API Management Your Auth Gateway For MCP Servers
The Model Context Protocol (MCP) is quickly becoming the standard for integrating Tools 🛠️ with Agents 🤖 and Azure API Management is at the fore-front, ready to support this open-source protocol 🚀. You may have already encountered discussions about MCP, so let's clarify some key concepts: Model Context Protocol (MCP) is a standardized way, (a protocol), for AI models to interact with external tools, (and either read data or perform actions) and to enrich context for ANY language models. AI Agents/Assistants are autonomous LLM-powered applications with the ability to use tools to connect to external services required to accomplish tasks on behalf of users. Tools are components made available to Agents allowing them to interact with external systems, perform computation, and take actions to achieve specific goals. Azure API Management: As a platform-as-a-service, API Management supports the complete API lifecycle, enabling organizations to create, publish, secure, and analyze APIs with built-in governance, security, analytics, and scalability. New Cool Kid in Town - MCP AI Agents are becoming widely adopted due to enhanced Large Language Model (LLM) capabilities. However, even the most advanced models face limitations due to their isolation from external data. Each new data source requires custom implementations to extract, prepare, and make data accessible for any model(s). - A lot of heavy lifting. Anthropic developed an open-source standard - the Model Context Protocol (MCP), to connect your agents to external data sources such as local data sources (databases or computer files) or remote services (systems available over the internet through e.g. APIs). MCP Hosts: LLM applications such as chat apps or AI assistant in your IDEs (like GitHub Copilot in VS Code) that need to access external capabilities MCP Clients: Protocol clients that maintain 1:1 connections with servers, inside the host application MCP Servers: Lightweight programs that each expose specific capabilities and provide context, tools, and prompts to clients MCP Protocol: Transport layer in the middle At its core, MCP follows a client-server architecture where a host application can connect to multiple servers. Whenever your MCP host or client needs a tool, it is going to connect to the MCP server. The MCP server will then connect to for example a database or an API. MCP hosts and servers will connect with each other through the MCP protocol. You can create your own custom MCP Servers that connect to your or organizational data sources. For a quick start, please visit our GitHub repository to learn how to build a remote MCP server using Azure Functions without authentication: https://aka.ms/mcp-remote Remote vs. Local MCP Servers The MCP standard supports two modes of operation: Remote MCP servers: MCP clients connect to MCP servers over the Internet, establishing a connection using HTTP and Server-Sent Events (SSE), and authorizing the MCP client access to resources on the user's account using OAuth. Local MCP servers: MCP clients connect to MCP servers on the same machine, using stdio as a local transport method. Azure API Management as the AI Auth Gateway Now that we have learned that MCP servers can connect to remote services through an API. The question now rises, how can we expose our remote MCP servers in a secure and scalable way? This is where Azure API Management comes in. A way that we can securely and safely expose tools as MCP servers. Azure API Management provides: Security: AI agents often need to access sensitive data. API Management as a remote MCP proxy safeguards organizational data through authentication and authorization. Scalability: As the number of LLM interactions and external tool integrations grows, API Management ensures the system can handle the load. Security remains to be a critical piece of building MCP servers, as agents will need to securely connect to protected endpoints (tools) to perform certain actions or read protected data. When building remote MCP servers, you need a way to allow users to login (Authenticate) and allow them to grant the MCP client access to resources on their account (Authorization). MCP - Current Authorization Challenges State: 4/10/2025 Recent changes in MCP authorization have sparked significant debate within the community. 🔍 𝗞𝗲𝘆 𝗖𝗵𝗮𝗹𝗹𝗲𝗻𝗴𝗲𝘀 with the Authorization Changes: The MCP server is now treated as both a resource server AND an authorization server. This dual role has fundamental implications for MCP server developers and runtime operations. 💡 𝗢𝘂𝗿 𝗦𝗼𝗹𝘂𝘁𝗶𝗼𝗻: To address these challenges, we recommend using 𝗔𝘇𝘂𝗿𝗲 𝗔𝗣𝗜 𝗠𝗮𝗻𝗮𝗴𝗲𝗺𝗲𝗻𝘁 as your authorization gateway for remote MCP servers. 🔗For an enterprise-ready solution, please check out our azd up sample repo to learn how to build a remote MCP server using Azure API Management as your authentication gateway: https://aka.ms/mcp-remote-apim-auth The Authorization Flow The workflow involves three core components: the MCP client, the APIM Gateway, and the MCP server, with Microsoft Entra managing authentication (AuthN) and authorization (AuthZ). Using the OAuth protocol, the client starts by calling the APIM Gateway, which redirects the user to Entra for login and consent. Once authenticated, Entra provides an access token to the Gateway, which then exchanges a code with the client to generate an MCP server token. This token allows the client to communicate securely with the server via the Gateway, ensuring user validation and scope verification. Finally, the MCP server establishes a session key for ongoing communication through a dedicated message endpoint. Diagram source: https://aka.ms/mcp-remote-apim-auth-diagram Conclusion Azure API Management (APIM) is an essential tool for enterprise customers looking to integrate AI models with external tools using the Model Context Protocol (MCP). In this blog, we've emphasized the simplicity of connecting AI agents to various data sources through MCP, streamlining previously complex implementations. Given the critical role of secure access to platforms and services for AI agents, APIM offers robust solutions for managing OAuth tokens and ensuring secure access to protected endpoints, making it an invaluable asset for enterprises, despite the challenges of authentication. API Management: An Enterprise Solution for Securing MCP Servers Azure API Management is an essential tool for enterprise customers looking to integrate AI models with external tools using the Model Context Protocol (MCP). It is designed to help you to securely expose your remote MCP servers. MCP servers are still very new, and as the technology evolves, API Management provides an enterprise-ready solution that will evolve with the latest technology. Stay tuned for further feature announcements soon! Acknowledgments This post and work was made possible thanks to the hard work and dedication of our incredible team. Special thanks to Pranami Jhawar, Julia Kasper, Julia Muiruri, Annaji Sharma Ganti Jack Pa, Chaoyi Yuan and Alex Vieira for their invaluable contributions. Additional Resources MCP Client Server integration with APIM as AI gateway Blog Post: https://aka.ms/remote-mcp-apim-auth-blog Sequence Diagram: https://aka.ms/mcp-remote-apim-auth-diagram APIM lab: https://aka.ms/ai-gateway-lab-mcp-client-auth Python: https://aka.ms/mcp-remote-apim-auth .NET: https://aka.ms/mcp-remote-apim-auth-dotnet On-Behalf-Of Authorization: https://aka.ms/mcp-obo-sample 3rd Party APIs – Backend Auth via Credential Manager: Blog Post: https://aka.ms/remote-mcp-apim-lab-blog APIM lab: https://aka.ms/ai-gateway-lab-mcp YouTube Video: https://aka.ms/ai-gateway-lab-demo25KViews12likes4CommentsLogic Apps Aviators Newsletter - November 2025
In this issue: Ace Aviator of the Month News from our product group News from our community Ace Aviator of the Month Novembers’s Ace Aviator: Al Ghoniem What's your role and title? What are your responsibilities? As a Senior Integration Consultant, I design and deliver enterprise-grade integration on Microsoft Azure, primarily using Logic Apps Standard, API Management, Service Bus, Event Grid and Azure Functions. My remit covers reference architectures, “golden” templates, governance and FinOps guardrails, CI/CD automation (Bicep and YAML), and production-ready patterns for reliability, observability and cost efficiency. Alongside my technical work, I lead teams of consultants and engineers, helping them adopt standardised delivery models, mentor through code reviews and architectural walkthroughs, and ensure we deliver consistent, high-quality outcomes across projects. I also help teams apply decisioning patterns (embedded versus external rules) and integrate AI responsibly within enterprise workflows. Can you give us some insights into your day-to-day activities and what a typical day in your role looks like? Architecture and patterns: refining solution designs, sequence diagrams and rules models for new and existing integrations. Build and automation: evolving reusable Logic App Standard templates, Bicep modules and pipelines, embedding monitoring, alerts and identity-first security. Problem-solving: addressing performance tuning, transient fault handling, poison/DLQ flows and “design for reprocessing.” Leadership and enablement: mentoring consultants, facilitating technical discussions, and ensuring knowledge is shared across teams. Community and writing: publishing articles and examples to demystify real-world integration trade-offs. What motivates and inspires you to be an active member of the Aviators/Microsoft community? The community continuously turns hard-won lessons into reusable practices. Sharing patterns (and anti-patterns) saves others time and incidents, while learning from peers strengthens my own work. Microsoft’s product teams also listen closely, and seeing customer feedback directly shape the platform is genuinely rewarding. Looking back, what advice do you wish you had been given earlier that you'd now share with those looking to get into STEM/technology? Optimise for learning speed, not titles. Choose problems that stretch you and deliver in small, measurable increments. Master the fundamentals. Naming, idempotency, retries and observability are not glamorous but make systems dependable. Document everything. Diagrams, runbooks and ADRs multiply your impact. Understand trade-offs. Every decision buys something and costs something; acknowledge both sides clearly. Value collaboration over heroics. Ask questions, share knowledge and give credit freely. What has helped you grow professionally? Reusable scaffolding: creating golden templates and reference repositories that capture best practice once and reuse it everywhere. Feedback loops: leveraging telemetry, post-incident reviews and peer critique to improve. Teaching and mentoring: explaining concepts to others brings clarity and strengthens leadership. Cross-disciplinary curiosity: combining architecture, DevOps, FinOps and AI to address problems holistically. If you had a magic wand that could create a feature in Logic Apps, what would it be and why? "Stateful Sessions and Decisions” as a first-class capability: Built-in session state across multiple workflows, durable correlation and resumable orchestrations without external storage. A native decisioning activity with versioned decision tables and rule auditing (“why this rule fired”). A local-first developer experience with fast testing and contract validation for confident iteration. This would simplify complex, human-in-the-loop and event-driven scenarios, reduce custom plumbing, and make advanced orchestration patterns accessible to a wider audience. News from our product group Logic Apps Community Day 2025 Did you miss or want to catch up again on your favorite Logic Apps Community Day videos – jump back into action on this four hours long learning session, with 10 sessions from our Community Experts. And stay tuned for individual sessions being shared throughout the week. Announcing Parse & Chunk with Metadata in Logic Apps: Build Context-Aware RAG Agents New Parse & Chunk actions add metadata like page numbers and sentence completeness—perfect for context-aware document Q&A using Azure AI Search and Agent Loop. Introducing the RabbitMQ Connector (Public Preview) The new connector (Public Preview) lets you send and receive messages with RabbitMQ in Logic Apps Standard and Hybrid—ideal for scalable, reliable messaging across industries. News from our community EventGrid And Entra Auth In Logic Apps Standard Post by Riccardo Viglianisi Learn how to use Entra Auth for webhook authentication, ditch SAS tokens, and configure private endpoints with public access rules—perfect for secure, scalable integrations. Debugging XSLT Made Easy in VS Code: .NET-Based Debugging for Logic Apps Post by Daniel Jonathan A new .NET-based extension brings real debugging to XSLT for Logic Apps. Set breakpoints, step through transformations, and inspect variables—making XSLT development clear and productive. This is the 3 rd post in a 5 part series, so worth checking out the other posts too. Modifying the Logic App Azure Workbook: Custom Views for Multi Workflow Monitoring Post by Jeff Wessling Learn how to tailor dashboards with KQL, multi-workflow views, and context panes—boosting visibility, troubleshooting speed, and operational efficiency across your integrations. Azure AI Agents in Logic Apps: A Guide to Automate Decisions Post by Imashi Kinigama Discover how GPT-powered agents, created using Logic Apps Agent Loop, automate decisions, extract data, and adapt in real time. Build intelligent workflows with minimal effort—no hardcoding, just instructions and tools. How to Turn Logic App Connectors into MCP Servers (Step-by-Step Guide) Post by Stephen W. Thomas Learn how to expose connectors like Google Drive or Salesforce as MCP endpoints using Azure API Center—giving AI agents secure, real-time access to 1,400+ services directly from VS Code. Custom SAP MCP Server with Logic Apps Post by Sebastian Meyer Learn how to turn Logic Apps into AI-accessible tools using MCP. From workflow descriptions to Easy Auth setup and VS Code integration—this guide unlocks SAP automation with Copilot. How Azure Logic Apps as MCP Servers Accelerate AI Agent Development Post by Monisha S Turn 1,400+ connectors into AI tools with Logic Apps Standard. Build agents fast, integrate with legacy systems, and scale intelligent workflows across your organization. Designing Business Rules in Azure Logic Apps: When to Go Embedded vs External Post by Al Ghoniem Learn when to use Logic Apps' native Rules Engine or offload to Azure Functions with NRules or JSON RulesEngine. Discover hybrid patterns for scalable, testable decision automation. Syncing SharePoint with Azure Blob Storage using Logic Apps & Azure Functions for Azure AI Search Post by Daniel Jonathan Solve folder delete issues by tagging blobs with SharePoint metadata. Use Logic Apps and a custom Azure Function to clean up orphaned files and keep Azure AI Search in sync. Step-by-Step Guide: Building a Conversational Agent in Azure Logic Apps Post by Stephen W. Thomas Use Azure AI Foundry and Logic Apps Standard to create chatbots that shuffle cards, answer questions, and embed into websites—no code required, just smart workflows and EasyAuth. You can hide sensitive data from the Logic App run history Post by Francisco Leal Learn how to protect sensitive data like authentication tokens, credentials, and personal information in Logic App, so this data don’t appear in the run history, which could pose security and privacy risks.2.2KViews0likes0Comments🚀 New in Azure API Management: MCP in v2 SKUs + external MCP-compliant server support
Your APIs are becoming tools. Your users are becoming agents. Your platform needs to adapt. Azure API Management is becoming the secure, scalable control plane for connecting agents, tools, and APIs — with governance built in. -------------------------------------------------------------------------------------------------------------------------------------------------------------------- Today, we’re announcing two major updates to bring the power of the Model Context Protocol (MCP) in Azure API Management to more environments and scenarios: MCP support in v2 SKUs — now in public preview Expose existing MCP-compliant servers through API Management These features make it easier than ever to connect APIs and agents with enterprise-grade control—without rewriting your backends. Why MCP? MCP is an open protocol that enables AI agents—like GitHub Copilot, ChatGPT, and Azure OpenAI—to discover and invoke APIs as tools. It turns traditional REST APIs into structured, secure tools that agents can call during execution — powering real-time, context-aware workflows. Why API Management for MCP? Azure API Management is the single, secure control plane for exposing and governing MCP capabilities — whether from your REST APIs, Azure-hosted services, or external MCP-compliant runtimes. With built-in support for: Security using OAuth 2.1, Microsoft Entra ID, API keys, IP filtering, and rate limiting. Outbound token injection via Credential Manager with policy-based routing. Monitoring and diagnostics using Azure Monitor, Logs, and Application Insights. Discovery and reuse with Azure API Center integration. Comprehensive policy engine for request/response transformation, caching, validation, header manipulation, throttling, and more. …you get end-to-end governance for both inbound and outbound agent interactions — with no new infrastructure or code rewrites. ✅ What’s New? 1. MCP support in v2 SKUs Previously available only in classic tiers (Basic, Standard, Premium), MCP support is now in public preview for v2 SKUs — Basic v2, Standard v2, and Premium v2 — with no pre-requisites or manual enablement required. You can now: Expose any REST API as an MCP server in v2 SKUs Protect it with Microsoft Entra ID, keys or tokens Register tools in Azure API Center 2. Expose existing MCP-compliant servers (pass-through scenario) Already using tools hosted in Logic Apps, Azure Functions, LangChain or custom runtimes? Now you can govern those external tool servers by exposing them through API Management. Use API Management to: Secure external MCP servers with OAuth, rate limits, and Credential Manager Monitor and log usage with Azure Monitor and Application Insights Unify discovery with internal tools via Azure API Center 🔗 You bring the tools. API Management brings the governance. 🧭 What’s Next We’re actively expanding MCP capabilities in API Management: Tool-level access policies for granular governance Support for MCP resources and prompts to expand beyond tools 📚 Get Started 📘 Expose APIs as MCP servers 🌐 Connect external MCP servers 🔐 Secure access to MCP servers 🔎 Discover tools in API Center Summary Azure API Management is your single control plane for agents, tools and APIs — whether you're building internal copilots or connecting external toolchains. This preview unlocks more flexibility, less friction, and a secure foundation for the next wave of agent-powered applications. No new infrastructure. Secure by default. Built for the future.4.2KViews2likes3Comments