Skip to content

Commit 69f259c

Browse files
authored
Merge pull request #57 from microsoft/adilei
gitignore updates
2 parents 200a806 + 3a2ac76 commit 69f259c

File tree

3 files changed

+252
-34
lines changed

3 files changed

+252
-34
lines changed

.gitignore

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,16 @@ package-lock.json
1717

1818
# IDE configurations
1919
.idea
20-
.vscode/*
21-
!.vscode/settings.json
22-
!.vscode/extensions.json
23-
!.vscode/tasks.json
20+
.vscode/
21+
22+
# macOS system files
23+
.DS_Store
24+
.DS_Store?
25+
._*
26+
.Spotlight-V100
27+
.Trashes
28+
ehthumbs.db
29+
Thumbs.db
2430

2531
# Misc
2632
_sass/vendors

.vscode/settings.json

Lines changed: 0 additions & 30 deletions
This file was deleted.
Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
---
2+
layout: post
3+
title: "Enabling SSO for Custom Connectors in Copilot Studio"
4+
date: 2025-11-15
5+
categories: [copilot-studio, connectors, authentication]
6+
tags: [sso, custom-connectors, entra-id, authentication, api]
7+
description: How to configure custom connectors with Entra ID SSO to enable seamless user authentication and consent flow.
8+
#image: /assets/posts/custom-connector-sso/sso-flow.png
9+
author: adilei
10+
mermaid: true
11+
published: false
12+
---
13+
14+
When building agents in Copilot Studio, you often need to call downstream custom APIs with the user's credentials. Until recently, most builders relied on [manual authentication](https://learn.microsoft.com/en-us/microsoft-copilot-studio/configuration-end-user-authentication#authenticate-manually) to populate `System.User.AccessToken` and pass it as a bearer token to their APIs.
15+
16+
But here's a little-known capability* that makes a difference: **Custom connectors support the same SSO/consent experience as first-party connectors (as long as they support Entra authentication)**.
17+
18+
*At least it wasn't known to me, so I assumed no one else knew about it either. Sorry.
19+
20+
## The Problem with Manual Authentication
21+
22+
While manual authentication works, it has significant drawbacks:
23+
24+
1. **Complex Setup**: requires configuring two app registrations per agent (at least per out best practices)
25+
2. **No Tenant Graph Grounding**: Manual authentication isn't compatible with [Tenant Graph Grounding](https://learn.microsoft.com/en-us/microsoft-copilot-studio/knowledge-copilot-studio#tenant-graph-grounding), which provides higher quality responses grounded in SharePoint and Graph Connectors
26+
3. **Single Resource Limitation**: You configure a single OAuth resource for manual auth, which means you cannot obtain both a Graph token and a token for your custom API simultaneously.
27+
28+
## How Connector SSO Works in Copilot Studio
29+
30+
Before diving into custom connectors, let's understand how Copilot Studio handles authentication for **first-party connectors** that support Entra ID.
31+
32+
### The Consent Card Experience
33+
34+
When a signed-in user is conversing with an agent and the agent invokes a connector configured with [end-user authentication](https://learn.microsoft.com/en-us/microsoft-copilot-studio/configure-enduser-authentication), Copilot Studio presents a **consent card** asking the user to grant permission for the agent to create a connection on their behalf.
35+
36+
![Consent Card](/assets/posts/connector-consent-card-obo/consent.png){: .shadow w="700" h="400"}
37+
_The seamless consent card experience_
38+
39+
This is purely for privacy considerations. When users click `Allow` Copilot Studio handles all the OAuth token exchange automatically behind the scenes, obtaining tokens on behalf of the user (OBO flow).
40+
41+
## This Also Works for Custom Connectors!
42+
43+
Custom connectors configured with Entra authentication can leverage the exact same SSO/consent experience as first-party connectors, but there are specific configuration requirements:
44+
45+
1. A **service app registration** representing your custom API
46+
2. A **connector app registration**, representing your, well custom connector
47+
3. Grant permissions to the connector app to obtain an OBO token with the service app as the resource
48+
4. Configure authentication for your custom connector
49+
50+
This may seem like a lot of steps, but **it's done once per connector, and then any agent can use that connector** with the same seamless SSO experience.
51+
52+
When a signed-in user invokes your custom connector for the first time, they see the consent prompt showing your custom API's scopes. Once granted, subsequent calls work automatically with the user's credentials—just like Office 365 Users, SharePoint, or any other first-party connector using Entra auth.
53+
54+
![Custom Connector Consent Card](/assets/posts/custom-connector-sso/custom-connector-consent.png){: .shadow w="700" h="400"}
55+
_The seamless consent card experience, this time for a custom connector_
56+
57+
![Custom Connector Consent Card](/assets/posts/custom-connector-sso/custom-connector-todos.png){: .shadow w="700" h="400"}
58+
_The agent responds based on connector output_
59+
60+
## The Better Way: Custom Connector SSO
61+
62+
Just like first-party connectors that support Entra ID authentication, custom connectors can trigger the elegant [consent card experience](/posts/connector-consent-card-obo/) instead of the universally disliked connection manager.
63+
64+
![Consent Card](/assets/posts/connector-consent-card-obo/consent.png){: .shadow w="700" h="400"}
65+
_The seamless consent experience - now available for custom connectors_
66+
67+
When a signed-in user is conversing with an agent and invokes a connector configured with Entra auth, they see a consent prompt asking permission for Copilot Studio to sign in on their behalf. This is purely for privacy considerations—**users aren't expected to actually sign in manually**.
68+
69+
## Configuration Overview
70+
71+
Setting up custom connector SSO requires configuring two app registrations and a custom connector. Let's walk through each step in detail.
72+
73+
### Understanding the Authentication Flow
74+
75+
Before diving into configuration, let's visualize how the authentication flow works:
76+
77+
```mermaid
78+
sequenceDiagram
79+
participant User
80+
participant Agent as Copilot Studio Agent
81+
participant ConnFW as Connector Framework
82+
participant EntraID as Microsoft Entra ID
83+
participant API as Your Custom API
84+
85+
User->>Agent: Starts conversation
86+
Agent->>Agent: Determines tool/connector needed
87+
Agent->>User: Shows consent card
88+
Note over User,Agent: "Allow connector to access <br/>data on your behalf?"
89+
90+
User->>Agent: Clicks "Allow"
91+
ConnFW->>EntraID: Request token (OBO flow)
92+
Note over ConnFW,EntraID: Using Connector App credentials<br/>and user's auth context
93+
94+
EntraID-->>ConnFW: Returns access token
95+
Note over ConnFW: Token audience: api://service-app-id<br/>Token scope: access_as_user
96+
97+
Agent->>ConnFW: Invokes action
98+
ConnFW->>API: Calls API with Bearer token
99+
Note over ConnFW,API: Authorization: Bearer eyJ0eXAi...
100+
101+
API->>API: Validates token
102+
Note over API: Checks audience, issuer,<br/>signature, expiration
103+
104+
API-->>ConnFW: Returns data
105+
ConnFW-->>Agent: Returns response
106+
Agent->>User: Displays result
107+
108+
Note over User,API: Subsequent calls use cached token<br/>No additional consent required
109+
```
110+
111+
**Key Points:**
112+
- **One-time consent**: Users consent once per connector
113+
- **OBO (On-Behalf-Of) flow**: Connector Framework requests tokens using the user's context
114+
- **Token audience**: Points to your Service App (`api://service-app-id`)
115+
- **Automatic refresh**: Connector Framework handles token renewal
116+
- **User context preserved**: API receives user's identity and claims
117+
118+
### Step 1: Create the Service App Registration (Your Custom API)
119+
120+
The service app registration represents your custom API. This is the OAuth resource that will be protected and accessed by the connector.
121+
122+
#### 1.1 Create the App Registration
123+
124+
1. Navigate to [Azure Portal](https://portal.azure.com)**Microsoft Entra ID****App registrations**
125+
2. Click **New registration**
126+
3. Configure basic settings:
127+
- **Name**: `Service App 3p` (or your API name)
128+
- **Supported account types**: **Accounts in this organizational directory only (Single tenant)**
129+
- **Redirect URI**: Leave blank (not needed for API)
130+
4. Click **Register**
131+
132+
#### 1.2 Note the Application ID URI
133+
134+
1. After creation, go to **Overview**
135+
2. Note the **Application (client) ID** - you'll need this later
136+
3. The Application ID URI will be in format: `api://<client-id>`
137+
138+
#### 1.3 Expose an API
139+
140+
1. In the left menu, click **Expose an API**
141+
2. Next to **Application ID URI**, click **Add**
142+
3. Accept the default `api://<client-id>` or customize it (e.g., `api://contoso.com/myapi`)
143+
4. Click **Save**
144+
145+
![Expose an API](/assets/posts/custom-connector-sso/expose-api.png){: .shadow w="700" h="400"}
146+
_Setting the Application ID URI_
147+
148+
#### 1.4 Add a Custom Scope
149+
150+
1. Still in **Expose an API**, click **Add a scope**
151+
2. Configure the scope:
152+
- **Scope name**: `access_as_user`
153+
- **Who can consent**: **Admins and users**
154+
- **Admin consent display name**: `Access as user`
155+
- **Admin consent description**: `Access the API as the signed-in user`
156+
- **User consent display name**: `Access as user`
157+
- **User consent description**: `Allow the app to access the API on your behalf`
158+
- **State**: **Enabled**
159+
3. Click **Add scope**
160+
161+
![Edit a Scope](/assets/posts/custom-connector-sso/edit-scope.png){: .shadow w="700" h="400"}
162+
_Defining a custom scope for your API_
163+
164+
The full scope identifier will be: `api://<client-id>/access_as_user`
165+
166+
#### 1.5 Configure API Permissions (Optional)
167+
168+
Your service app registration typically **doesn't need any API permissions** itself, unless your API needs to call other APIs like Microsoft Graph.
169+
170+
If your API needs to call Microsoft Graph:
171+
172+
1. Go to **API permissions**
173+
2. Click **Add a permission****Microsoft Graph****Delegated permissions**
174+
3. Add only what you need (e.g., `User.Read` if you need basic profile info)
175+
4. Click **Add permissions**
176+
5. Click **Grant admin consent for [Your Tenant]** if required
177+
178+
![API Permissions](/assets/posts/custom-connector-sso/api-permissions.png){: .shadow w="700" h="400"}
179+
_Most service apps only need User.Read, if anything_
180+
181+
**Important**: Keep permissions minimal. The service app represents your API, not the connector consuming it.
182+
183+
#### 1.6 Record Key Values
184+
185+
Save these values for later steps:
186+
- **Application (client) ID**: `b52b5b7a-e895-4600-b567-2c4cbe27d2e7` (example)
187+
- **Application ID URI**: `api://b52b5b7a-e895-4600-b567-2c4cbe27d2e7`
188+
- **Scope**: `api://b52b5b7a-e895-4600-b567-2c4cbe27d2e7/access_as_user`
189+
190+
### Step 2: Create the Connector App Registration
191+
192+
[Placeholder: Connector app registration configuration]
193+
194+
### Step 3: Configure the Custom Connector
195+
196+
[Placeholder: Custom connector configuration]
197+
198+
## Best Practices
199+
200+
[Placeholder: Security and implementation best practices]
201+
202+
- Least privilege scopes
203+
- Token caching
204+
- Error handling
205+
- Testing strategies
206+
207+
## Comparison: Manual Auth vs. Custom Connector SSO
208+
209+
| Feature | Manual Auth | Custom Connector SSO |
210+
| ---------------------- | ----------------------- | ------------------------ |
211+
| Setup Complexity | High | Medium |
212+
| Tenant Graph Grounding | ❌ No | ✅ Yes |
213+
| User Experience | Poor (explicit sign-in) | Excellent (consent card) |
214+
| Token Management | Manual | Automatic |
215+
| MCP Server Support | ❌ No | ✅ Yes |
216+
217+
## Real-World Scenarios
218+
219+
Custom connector SSO is perfect for:
220+
221+
- **Enterprise API Integration**: Call internal APIs with user context
222+
- **Multi-tenant Applications**: Maintain user identity across services
223+
- **Compliance Requirements**: Ensure proper user authorization
224+
- **MCP Servers**: Connect to Model Context Protocol servers with Entra auth
225+
226+
## Troubleshooting
227+
228+
[Placeholder: Common issues and solutions]
229+
230+
- Consent not appearing
231+
- Token validation failures
232+
- Scope mismatches
233+
234+
## Further Reading
235+
236+
- [Configure End-User Authentication](https://learn.microsoft.com/en-us/microsoft-copilot-studio/configure-enduser-authentication)
237+
- [Intercepting Connector Consent Cards](/posts/connector-consent-card-obo/)
238+
- [Tenant Graph Grounding](https://learn.microsoft.com/en-us/microsoft-copilot-studio/knowledge-copilot-studio#tenant-graph-grounding)
239+
240+
---
241+
242+
*Special thanks to the Copilot Studio engineering team for clarifying this capability!*

0 commit comments

Comments
 (0)