daisami guides developers through securing Azure Bot Service endpoints for Microsoft Teams, focusing on application-level protections, token validation, and tenant restrictions to safeguard accessible endpoints in ASP.NET Core bots.

Securing Azure Bot Service Endpoints for Teams Channel Integration

By daisami

Prerequisite

Before proceeding, review the foundational article on Developing a Custom Engine Agent for Microsoft 365 Copilot Chat Using Pro-Code, which details how to publish a Custom Engine Agent using C# or pro-code platforms.

Overview

This article shifts the focus from development to security, addressing the critical question of how to secure your bot endpoints when integrating Azure Bot Service with the Microsoft Teams channel. Due to the architectural characteristics of Teams and Azure Bot Service, there are unique security considerations and limitations that teams must account for in production environments.

Endpoints in Scope

You must consider THREE primary endpoints:

  1. Teams Endpoint - Where users access the bot through the Teams app. Access is managed via Teams Admin Center, with restrictions set for users/groups. There is no endpoint-level isolation possible, and app packages can be copied by external organizations.

  2. Azure Bot Service Endpoint - Publicly accessible bridge between Teams and your backend. Limited configuration—mainly the Service Principal. No granular access controls on this relay.

  3. ASP.NET Core Endpoint - The actual backend, often exposed publicly (via devtunnel for development or Azure App Service in production).

    • Network isolation is NOT available for Teams channel bots (unlike Direct Line channel). Therefore, you must implement application-level security controls like token validation, IP filtering, and mutual TLS.
    • See Azure Bot Service networking documentation for limitations.

Current Security Approaches and Limitations

  • Teams app management can restrict user/group access inside your tenant but cannot stop external sharing or copying of app packages.
  • Azure Bot Service enforces identity via Service Principal, but the endpoint itself is public and acts as a pass-through.
  • Backend endpoint (ASP.NET Core) must be exposed publicly for Teams to reach it. Network-level isolation (Private Endpoints, VNET) is not supported for the Teams channel, so all security must be enforced at the application code level.
  1. JWT Token Validation
    • Validate issuer, audience, and signature of incoming tokens.
    • Only accept tokens for your Azure Bot Service’s Service Principal.
    • Validate that the required claims (audience/client and tenant IDs) match your configuration.
  2. Reject Requests without Tokens
    • Modify authentication logic to fail requests missing authorization headers. (This is a security improvement over default behavior where missing tokens may be ignored.)
    • Example code (simplified):

      if (string.IsNullOrEmpty(authorizationHeader)) {
         context.Fail("Authorization header is missing.");
         logger?.LogWarning("Authorization header is missing.");
         return;
      }
      
  3. Deny Access from Unknown Entra ID Tenants
    • Compare the tenant ID from the incoming token and activity to your allowed tenant IDs.
    • Example logic:

      if (!string.IsNullOrEmpty(_tenantId) && !string.Equals(activity.Conversation?.TenantId, _tenantId, StringComparison.OrdinalIgnoreCase)) {
          _logger.LogWarning("Unauthorized serviceUrl detected: {ServiceUrl}. Expected TenantId: {TenantId}", activity?.ServiceUrl, _tenantId);
          await turnContext.SendActivityAsync("Unauthorized service URL.", cancellationToken: cancellationToken);
          return;
      }
      
  4. Additional Protections
    • Implement IP filtering, network security groups (NSG), and Azure Firewall where possible.
    • Always use HTTPS and consider mutual TLS if practical.

Code Walkthrough

  • The author includes code samples for ASP.NET Core Program.cs and AspNetExtensions.cs to show how to add and configure token validation for bot requests.
  • Highlights how to decode and inspect JWTs to confirm required claims (audience and tenant).
  • Demonstrates defense-in-depth by layering configuration-level and runtime application controls.

Key Takeaways

  • Full network isolation is not feasible for Teams-integrated bots due to SaaS constraints.
  • Application-level security (JWT validation, tenant filtering) is essential.
  • Service Principals must have proper API permissions (e.g., User.Read.All) to ensure tokens are issued and can be validated.
  • Developers must ensure authentication logic is strict—do not let requests without tokens through.
  • Continuous monitoring, code inspection, and reviewing latest best practices are advised.

Further Reading and References


For feedback and discussion, connect with daisami on the Microsoft Tech Community.

This post appeared first on “Microsoft Tech Community”. Read the entire article here