Skip to content

reference project for obo auth app registration - #253

Open
Meghanshu Bhatt (meghanshubhatt) wants to merge 4 commits into
mainfrom
mebhatt/oboappregistration
Open

reference project for obo auth app registration#253
Meghanshu Bhatt (meghanshubhatt) wants to merge 4 commits into
mainfrom
mebhatt/oboappregistration

Conversation

@meghanshubhatt

Copy link
Copy Markdown

feat: add Agent Framework sample with manual App Registration setup (OBO auth)

Description

Adds a new sample demonstrating how to set up a Custom Engine Agent using manual Azure AD app registration with On-Behalf-Of (OBO) authentication, deployed as a Docker container on Azure App Service.

This complements the existing agent-framework sample by showing the app-registration-based approach — useful for partners and scenarios where automated provisioning isn't available.

What's included

File Purpose
Agent/MyAgent.cs Agent logic — message handling, LLM orchestration, MCP tool loading, Teams SSO
Program.cs ASP.NET host setup, DI registration, /api/messages endpoint
appsettings.json Bot auth, Azure OpenAI, agent configuration (placeholder secrets)
appPackage/manifest.json Teams app manifest for sideloading (placeholder IDs)
telemetry/AgentMetrics.cs OpenTelemetry instrumentation for HTTP and agent operations
telemetry/A365OtelWrapper.cs A365 observability wrapper with baggage propagation
telemetry/AgentOTELExtensions.cs OpenTelemetry pipeline configuration
Tools/ Local tools — weather lookup and datetime
Dockerfile Multi-stage Docker build targeting port 8080
README.md Architecture overview, key files reference, prerequisites
claude.md Complete step-by-step setup guide covering app registration, bot resource, Docker deployment, Teams sideloading, and common issue resolution
docs/design.md Design notes and architecture decisions

Key features

  • Manual App Registration: Full SingleTenant Azure AD setup with api://botid-{appId} identifier URI
  • Teams SSO + OBO: Token exchange via GraphOBoConnection OAuth connection
  • MCP Tooling: Agent 365 Tools integration with delegated permissions
  • Docker Deployment: Containerized on Azure App Service (Linux) with ACR
  • Observability: OpenTelemetry tracing with A365 Service Exporter
  • Comprehensive troubleshooting guide: Documents 8 common setup issues and their fixes

Notable fix

Fixed an async void bug in AgentMetrics.InvokeObservedHttpOperation — the method accepted Action func but was called with async lambdas, causing fire-and-forget behavior that crashed the container with ObjectDisposedException. Changed to Func<Task> func with proper await.

Testing

  • ✅ DirectLine: Bot processes messages and returns OAuthCard sign-in prompts
  • ✅ Teams: Bot responds after sideloading, SSO flow completes, MCP tools load
  • ✅ Health endpoint: /api/health returns 200

Copilot AI review requested due to automatic review settings March 24, 2026 18:34
@github-actions

github-actions Bot commented Mar 24, 2026

Copy link
Copy Markdown

⚠️ Deprecation Warning: The deny-licenses option is deprecated for possible removal in the next major release. For more information, see issue 997.

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 5 package(s) with unknown licenses.
See the Details below.

License Issues

dotnet/obo-auth-samples/agent-framework-appRegistration/sample-agent/AgentFrameworkSampleAgent.csproj

PackageVersionLicenseIssue Type
Microsoft.Agents.A365.Notifications0.2.151-betaNullUnknown License
Microsoft.Agents.A365.Tooling.Extensions.AgentFramework0.2.151-betaNullUnknown License
Microsoft.Agents.AI1.0.0NullUnknown License
Microsoft.Extensions.AI.OpenAI10.4.1NullUnknown License
Microsoft.OpenTelemetry1.0.0-beta.1NullUnknown License
Denied Licenses: GPL-3.0-only, AGPL-3.0-only

OpenSSF Scorecard

Scorecard details
PackageVersionScoreDetails
nuget/AdaptiveCards 3.1.0 UnknownUnknown
nuget/Azure.AI.OpenAI 2.9.0-beta.1 🟢 7.2
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 17 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 10all changesets reviewed
Packaging⚠️ -1packaging workflow not detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Security-Policy🟢 10security policy file detected
Token-Permissions🟢 9detected GitHub workflow tokens with excessive permissions
Branch-Protection🟢 5branch protection is not maximal on development and all release branches
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
Binary-Artifacts🟢 9binaries present in source code
Pinned-Dependencies🟢 5dependency not pinned by hash detected -- score normalized to 5
Fuzzing⚠️ 0project is not fuzzed
nuget/Azure.Identity 1.20.0 🟢 7.2
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 17 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 10all changesets reviewed
Packaging⚠️ -1packaging workflow not detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Security-Policy🟢 10security policy file detected
Token-Permissions🟢 9detected GitHub workflow tokens with excessive permissions
Branch-Protection🟢 5branch protection is not maximal on development and all release branches
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
Binary-Artifacts🟢 9binaries present in source code
Pinned-Dependencies🟢 5dependency not pinned by hash detected -- score normalized to 5
Fuzzing⚠️ 0project is not fuzzed
nuget/Microsoft.Agents.A365.Notifications 0.2.151-beta UnknownUnknown
nuget/Microsoft.Agents.A365.Tooling.Extensions.AgentFramework 0.2.151-beta UnknownUnknown
nuget/Microsoft.Agents.AI 1.0.0 UnknownUnknown
nuget/Microsoft.Agents.Authentication.Msal 1.5.90-beta UnknownUnknown
nuget/Microsoft.Agents.Hosting.AspNetCore 1.5.90-beta UnknownUnknown
nuget/Microsoft.Extensions.AI.OpenAI 10.4.1 🟢 6.4
Details
CheckScoreReason
Packaging⚠️ -1packaging workflow not detected
Code-Review🟢 8Found 12/15 approved changesets -- score normalized to 8
Security-Policy🟢 10security policy file detected
Maintained🟢 1030 commit(s) and 20 issue activity found in the last 90 days -- score normalized to 10
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
License🟢 10license file detected
Binary-Artifacts🟢 10no binaries found in the repo
Signed-Releases⚠️ -1no releases found
Branch-Protection🟢 5branch protection is not maximal on development and all release branches
Pinned-Dependencies🟢 9dependency not pinned by hash detected -- score normalized to 9
Fuzzing⚠️ 0project is not fuzzed
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
nuget/Microsoft.OpenTelemetry 1.0.0-beta.1 UnknownUnknown
nuget/OpenWeatherMapSharp 4.2.0 UnknownUnknown

Scanned Files

  • dotnet/obo-auth-samples/agent-framework-appRegistration/sample-agent/AgentFrameworkSampleAgent.csproj

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new .NET Agent Framework sample under dotnet/obo-auth-samples/agent-framework-appRegistration/ that demonstrates manual Azure AD app registration for a Custom Engine Agent using Teams SSO + OBO, packaged for Docker deployment on Azure App Service, with OpenTelemetry/A365 observability and MCP tooling configuration.

Changes:

  • Adds a complete runnable sample agent (ASP.NET host, agent implementation, tools, auth/token validation helpers, Dockerfile).
  • Adds observability helpers (OpenTelemetry pipeline extensions, custom metrics/tracing wrappers) and documentation (README + detailed setup guide + design notes).
  • Adds Teams sideloading assets (manifest + icons) and sample configuration files.

Reviewed changes

Copilot reviewed 19 out of 23 changed files in this pull request and generated 20 comments.

Show a summary per file
File Description
dotnet/obo-auth-samples/agent-framework-appRegistration/sample-agent/telemetry/AgentOTELExtensions.cs Adds OpenTelemetry configuration helpers for the sample.
dotnet/obo-auth-samples/agent-framework-appRegistration/sample-agent/telemetry/AgentMetrics.cs Adds custom ActivitySource/Meter instrumentation helpers for HTTP + agent operations.
dotnet/obo-auth-samples/agent-framework-appRegistration/sample-agent/telemetry/A365OtelWrapper.cs Wraps agent operations with A365 observability baggage + token registration.
dotnet/obo-auth-samples/agent-framework-appRegistration/sample-agent/docs/design.md Documents architecture and key flows for the sample.
dotnet/obo-auth-samples/agent-framework-appRegistration/sample-agent/claude.md Provides a step-by-step setup/deployment guide (manual app registration + bot + Docker/App Service + Teams).
dotnet/obo-auth-samples/agent-framework-appRegistration/sample-agent/appsettings.json Default configuration template for OBO setup, AOAI, tooling, and logging.
dotnet/obo-auth-samples/agent-framework-appRegistration/sample-agent/appsettings.Playground.json Playground-specific configuration template.
dotnet/obo-auth-samples/agent-framework-appRegistration/sample-agent/appPackage/outline.png Teams app outline icon.
dotnet/obo-auth-samples/agent-framework-appRegistration/sample-agent/appPackage/manifest.json Teams app manifest template with placeholders for IDs/domains.
dotnet/obo-auth-samples/agent-framework-appRegistration/sample-agent/appPackage/color.png Teams app color icon.
dotnet/obo-auth-samples/agent-framework-appRegistration/sample-agent/Tools/WeatherLookupTool.cs Adds a local tool for weather lookup via OpenWeatherMap.
dotnet/obo-auth-samples/agent-framework-appRegistration/sample-agent/Tools/DateTimeFunctionTool.cs Adds a local tool for current date/time.
dotnet/obo-auth-samples/agent-framework-appRegistration/sample-agent/ToolingManifest.json Declares MCP server(s) for tool loading.
dotnet/obo-auth-samples/agent-framework-appRegistration/sample-agent/README.md Sample overview, prerequisites, and references to setup docs.
dotnet/obo-auth-samples/agent-framework-appRegistration/sample-agent/Program.cs ASP.NET host wiring, DI, auth middleware, /api/messages + health endpoint, AOAI client setup.
dotnet/obo-auth-samples/agent-framework-appRegistration/sample-agent/Dockerfile Multi-stage Docker build targeting port 8080.
dotnet/obo-auth-samples/agent-framework-appRegistration/sample-agent/AspNetExtensions.cs Adds JWT validation/authentication wiring for the sample.
dotnet/obo-auth-samples/agent-framework-appRegistration/sample-agent/AgentFrameworkSampleAgent.csproj Sample project definition and package references.
dotnet/obo-auth-samples/agent-framework-appRegistration/sample-agent/Agent/MyAgent.cs Main agent implementation: handlers, SSO/OBO selection, tool loading, streaming/UX behavior.
dotnet/obo-auth-samples/agent-framework-appRegistration/sample-agent/.gitignore Sample-specific gitignore for local artifacts.
dotnet/obo-auth-samples/agent-framework-appRegistration/AgentFrameworkSample.sln Adds a solution file for the new sample project.

Replace A365.Observability.* packages and standalone OpenTelemetry packages
with Microsoft.OpenTelemetry 1.0.0-beta.1 distro. Remove manual token cache,
baggage scope construction, and MSAL token acquisition from A365OtelWrapper —
the distro handles export via TokenResolver callback. Remove OpenWeatherApiKey
validation from Program.cs startup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
async () =>
{
// Send an immediate acknowledgment for non-agentic requests only.
if (!turnContext.IsAgenticRequest())
Comment on lines +195 to +202
if (turnContext.IsAgenticRequest())
{
ToolAuthHandlerName = AgenticAuthHandlerName;
}
else
{
ToolAuthHandlerName = OboAuthHandlerName;
}
{
if (attachment.ContentType == "application/vnd.microsoft.teams.file.download.info" && !string.IsNullOrEmpty(attachment.ContentUrl))
{
userText += $"\n\n[User has attached a file: {attachment.Name}. The file can be downloaded from {attachment.ContentUrl}]";
Comment on lines +137 to +143
foreach (ChannelAccount member in turnContext.Activity.MembersAdded)
{
if (member.Id != turnContext.Activity.Recipient.Id)
{
await turnContext.SendActivityAsync(AgentWelcomeMessage);
}
}
Comment on lines +248 to +254
foreach (var attachment in turnContext.Activity.Attachments)
{
if (attachment.ContentType == "application/vnd.microsoft.teams.file.download.info" && !string.IsNullOrEmpty(attachment.ContentUrl))
{
userText += $"\n\n[User has attached a file: {attachment.Name}. The file can be downloaded from {attachment.ContentUrl}]";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants