Agents SDK × SharePoint
Microsoft 365 Agents SDK · validated 7 Oct 2026

Authenticated Copilot Studio agents on any SharePoint site

Tutorial, use cases and test scenarios for publishing a Copilot Studio agent through the Microsoft 365 Agents SDK - one SharePoint web part for the whole tenant, single sign-on with Microsoft Entra ID, and Copilot Studio sharing as the access control. Built and tested end to end in a live Microsoft demo tenant.

12
use cases - 9 validated in the demo tenant
13
tutorial steps with checkpoints and screenshots
27
test scenarios with expected and actual results
16 / 27
passed; 1 limitation, 1 finding, 9 to validate in your tenant
Overview

How the Agents SDK web part works

The page talks to Copilot Studio directly with the user's own Entra ID token - no host site, no hidden files, no anonymous path.

Any site pageSPFx web part (inline chat) Microsoft Entra IDMSAL ssoSilent (SPA app) Copilot Studio (Agents SDK)api.powerplatform.com Agentsharing check token (CopilotStudio.Copilots.Invoke) connection string No host site - nothing to read in any other site

What you get

  • One SPFx package and one Entra SPA app for every site in the tenant.
  • Silent single sign-on with the SharePoint session, including MFA; one-click fallback when a browser blocks it.
  • The agent knows who is chatting (System.User.DisplayName and more).
  • Copilot Studio sharing enforced on every site; changes apply on the next page load.
  • Inline, themable chat; several agents per page; no Microsoft 365 Copilot license needed.

Three independent gates

  1. Microsoft Entra ID - the user is signed in (token for CopilotStudio.Copilots.Invoke).
  2. Copilot Studio sharing - the agent is shared with the user or their group.
  3. SharePoint permission - the user can open the page (Visitor is enough).
Authentication deep dive · configuration re-verified 13 Oct 2026

How this implementation uses authorization code + PKCE

Microsoft deprecated the older implicit grant, not the SPA application type. This web part uses MSAL Browser 4.30, which uses the OAuth 2.0 authorization-code flow with Proof Key for Code Exchange (PKCE). The deployed Entra app has both implicit-token settings turned off.

Deprecated - not used

Implicit grant

  • Requested tokens directly from the authorization endpoint.
  • Returned tokens in the browser URL fragment.
  • No PKCE binding for the authorization response.
  • Implicit access-token and ID-token issuance are disabled on our app registration.
Current Microsoft model - used here

SPA + authorization code + PKCE

  • MSAL requests a short-lived authorization code.
  • A one-time PKCE verifier binds the code to the browser request.
  • MSAL redeems the code at the token endpoint and manages renewal.
  • No client secret is placed in SharePoint or JavaScript.
What we verified: the actual demo-tenant app is single-tenant, has one SPA redirect URI at the SharePoint origin, has delegated CopilotStudio.Copilots.Invoke, and reports enableAccessTokenIssuance: false plus enableIdTokenIssuance: false.

FlowFrom the SharePoint page to the agent

1SharePoint + SPFxLoads the web part with the signed-in user and agent connection string.
2MSAL + PKCERequests an authorization code silently, with a one-time code challenge.
3Microsoft Entra IDReuses the existing session, validates policy and returns the code.
4Power Platform tokenMSAL redeems the code and receives a delegated user token.
5Copilot StudioValidates identity and agent sharing, then streams the conversation to Web Chat.

Step by stepWhat the code does

1

SharePoint loads the tenant-wide SPFx web part

The page supplies the current tenant, signed-in SharePoint user and the agent's Microsoft 365 Agents SDK connection string.

No Copilot Studio credential or secret is stored in the page configuration.

2

The web part initializes MSAL as a public client

MSAL receives the single-tenant client ID, tenant authority and the SharePoint origin as its SPA redirect URI. A public client has no client secret.

Microsoft Entra ID recognizes the request as a browser SPA request.

3

MSAL first checks its token cache

acquireTokenSilent looks for the correct account (matched to the SharePoint UPN) and a usable delegated token.

A valid cached token avoids another round trip and no user interface appears.

4

MSAL reuses the existing Entra session

If the cache has no usable token, ssoSilent starts an authorization-code request in a hidden frame with login_hint set to the SharePoint user.

The existing SharePoint / Entra session normally satisfies sign-in and MFA without another prompt.

5

PKCE binds the authorization code to this browser request

MSAL creates a one-time code verifier and sends its derived challenge to Microsoft Entra ID. The returned authorization code can only be redeemed with that verifier.

A stolen authorization code cannot be redeemed by a different client.

6

MSAL redeems the code for a delegated Power Platform token

MSAL calls the Microsoft identity platform token endpoint and requests the scope derived from the connection string (for example https://api.powerplatform.com/.default).

The token represents the signed-in user and contains the consented CopilotStudio.Copilots.Invoke permission.

7

The Copilot Studio client starts the conversation

The web part gives the access token and connection settings to CopilotStudioClient, then bridges its activity stream to Bot Framework Web Chat.

The token is sent only to the Power Platform / Copilot Studio endpoint.

8

Copilot Studio checks both identity and sharing

Copilot Studio validates the token, identifies the user and enforces whether the agent is shared with that user or one of their groups.

Shared users chat; unshared users receive the agent's access-denied response.

9

Interactive fallback uses the same secure flow

If silent sign-in is blocked by browser privacy controls or Conditional Access, the user selects Sign in with Microsoft. acquireTokenPopup still uses authorization code + PKCE.

The popup does not switch to implicit grant. One completed sign-in reconnects the other agent web parts on the page.

ConfigurationVerified Entra settings

SettingValue used by this implementationStatus
Application typeSingle-page application (public client)Supported
OAuth flowAuthorization code with Proof Key for Code Exchange (PKCE)Supported
Implicit access-token issuanceDisabled (enableAccessTokenIssuance: false)Verified
Implicit ID-token issuanceDisabled (enableIdTokenIssuance: false)Verified
Sign-in audienceSingle tenant (AzureADMyOrg)Verified
SPA redirect URIhttps://<tenant>.sharepoint.comVerified
Copilot Studio permissionPower Platform API / CopilotStudio.Copilots.Invoke (delegated)Verified
Client credentialNone - a browser public client must not contain a secretVerified
Authentication libraryMSAL Browser 4.30 (PublicClientApplication)Verified
Current token cachelocalStorage; use sessionStorage or memoryStorage if policy requires less persistenceOptional hardening

Code pathMSAL configuration and token acquisition

Public-client configuration

A browser SPA has a client ID and redirect URI, but no client secret.

const pca = new PublicClientApplication({
  auth: {
    clientId: "<single-tenant-app-client-id>",
    authority: "https://login.microsoftonline.com/<tenant-id>",
    redirectUri: window.location.origin,
    navigateToLoginRequestUrl: false
  },
  cache: {
    cacheLocation: "localStorage"
    // Use "sessionStorage" or "memoryStorage" for less persistence.
  }
});
await pca.initialize();

Silent first, interactive only when required

All three MSAL APIs below use authorization code + PKCE in MSAL Browser 4.

const scopes = [CopilotStudioClient.scopeFromSettings(settings)];

// 1. Cache / refresh token.
const account = findAccount(pca, sharePointUserUpn);
if (account) {
  return await pca.acquireTokenSilent({ scopes, account });
}

// 2. Existing SharePoint / Entra session (authorization code + PKCE).
return await pca.ssoSilent({ scopes, loginHint: sharePointUserUpn });

// 3. User-initiated fallback; still authorization code + PKCE.
return await pca.acquireTokenPopup({ scopes, loginHint: sharePointUserUpn });

VerifyHow to confirm implicit grant is disabled

Portal checks

  1. Entra admin center > App registrations > your app > Authentication.
  2. Confirm the redirect URI is under Single-page application.
  3. Under Implicit grant and hybrid flows, leave both token checkboxes clear.
  4. Under API permissions, confirm delegated Power Platform API / CopilotStudio.Copilots.Invoke.
  5. Confirm Supported account types is your organization only.

Azure CLI check

az ad app show --id <app-client-id> --query "{
  signInAudience: signInAudience,
  spaRedirectUris: spa.redirectUris,
  implicitAccessToken: web.implicitGrantSettings.enableAccessTokenIssuance,
  implicitIdToken: web.implicitGrantSettings.enableIdTokenIssuance
}" -o json

Expected shape:

{
  "signInAudience": "AzureADMyOrg",
  "spaRedirectUris": ["https://<tenant>.sharepoint.com"],
  "implicitAccessToken": false,
  "implicitIdToken": false
}

Current cache and hardening choice

The tested package uses localStorage so several web parts and browser tabs can reuse the account. MSAL Browser 4 encrypts local-storage artifacts while the browser session exists, but Microsoft states that cache encryption is not a replacement for XSS prevention.

Where policy requires less persistence, change the MSAL cache to sessionStorage (Microsoft default) or memoryStorage (strongest isolation, but sign-in state is lost on refresh).

Use cases

What the Agents SDK web part enables

Status reflects this engagement: Validated = executed in the demo tenant, To validate = run it in your tenant before relying on it, By design = supported pattern that was not tested here.

UC-01Validated

One assistant on every intranet site

Employees open the intranet home, HR, IT or a project site and chat with the same company agent, already signed in.

How: One tenant-wide SPFx package and one Entra SPA app serve every site. Each page stores only the agent's connection string.

Evidence: Agent A answered every shared tester on every site they could open (8 of 8 runs across Sites A, B and C).

UC-02Validated

Only approved people can chat

HR shares the HR agent with the HR team. Anyone else who opens the page is refused, on every site.

How: Copilot Studio sharing (End user access) is enforced on every Agents SDK call. Use Entra security groups in production.

Evidence: Unshared users got You don't have access to talk to this bot on every site. Revoking and re-sharing took effect on the next page load.

UC-03Validated

The agent knows who is chatting

The agent greets employees by name and can use their identity in topics, for example to look up their own requests.

How: With Authenticate with Microsoft, Copilot Studio receives the signed-in user, so System.User.* variables are filled in.

Evidence: Every greeting used the tester's name (Hello Agents SDK User A!). The web part footer shows the signed-in account.

UC-04Validated

Single sign-on, also with MFA

People already signed in to SharePoint start chatting without another prompt. If the browser blocks silent sign-in, one click fixes it.

How: MSAL acquireTokenSilent, then ssoSilent with the SharePoint user as login hint. Fallback: Sign in with Microsoft popup; one sign-in serves every agent on the page.

Evidence: 24 of 24 Agents SDK sessions signed in silently. With silent SSO blocked, one click on the sign-in button led to an answer in about 20 s.

UC-05Validated

Several agents on one page, or one agent per site

A hub page shows an HR agent and an IT agent side by side; each department site shows its own agent.

How: Every web part instance has its own connection string and conversation.

Evidence: Each test page hosted three agent web parts with independent results.

UC-06Validated

No host site to open up

A person may use the agent but must not see the agent owner's site. They still chat from their own site.

How: The web part calls Copilot Studio directly - there is no .agent file or host site in the path.

Evidence: Shared User C with no access to Site A chatted from Site B. The Agent link (SharePoint channel) blocked the same user.

UC-07Validated

Employees without Microsoft 365 Copilot

Employees without a Microsoft 365 Copilot license use the agent; usage is billed to Copilot Studio capacity.

How: Standard-harness agents reached through the Agents SDK consume the tenant's Copilot Studio capacity (Copilot Credits).

Evidence: Every test user had Microsoft 365 E5 (no Teams) only - no Microsoft 365 Copilot or Copilot Studio license.

UC-08Validated

Never reachable anonymously

Security requires that the agent cannot be used without an Entra sign-in, even if a URL leaks.

How: Agents SDK endpoints accept only user tokens for CopilotStudio.Copilots.Invoke.

Evidence: Anonymous calls to both connection strings returned HTTP 401 (re-checked on 7 Oct 2026). The hosted embed of the GitHub Copilot harness agent did not enforce sign-in.

UC-09Validated

Update once, every site follows

IT ships a new web part version once and every site gets it; makers publish agent changes without touching pages.

How: Tenant app catalog with Enable this app and add it to all sites; agent changes go live when the agent is published.

Evidence: Package 1.0.1.0 -> 1.0.3.0 was rolled out tenant-wide without editing a page; the regression run on Site A passed.

UC-10To validate

Answers that respect SharePoint permissions

The agent answers from policy documents in SharePoint and only uses documents the user can read.

How: SharePoint knowledge with Microsoft authentication runs generative answers on behalf of the signed-in user (documented for Teams, Power Apps and Microsoft 365 Copilot).

Evidence: Not tested through the Agents SDK in this engagement - validate before relying on it.

UC-11By design - not tested here

Agent that knows the page it is on

On a project site the agent already knows the project and tailors its answers.

How: Post a custom event with site/page context after the first agent message and read it in an OnEventActivity topic (Microsoft Learn pattern). Needs a small web part extension.

Evidence: Not implemented in this web part yet.

UC-12By design - not tested here

Same agent in other web apps

The agent is also embedded in a line-of-business portal or a native app with the same sign-in.

How: Copilot Studio client library for JavaScript, .NET or Python with the same connection string and a user token (service principal tokens are not supported).

Evidence: Integrate with web or native apps - not tested here.

Tutorial

Build it step by step

About 60-90 minutes the first time; adding the agent to another site takes about 2 minutes. Scripts and the SPFx solution are in the repository. Every checkpoint below was observed in the demo tenant.

You need: Copilot Studio maker access and capacity · permission to register an Entra app and grant tenant-wide consent · SharePoint Administrator + app catalog site admin · Windows with PowerShell 7, Azure CLI and Node.js 22.

Part 1Prepare the agent in Copilot Studio

1

Create a standard-harness agent

The Copilot Studio client library (Agents SDK) supports agents built on the standard harness.

  1. Copilot Studio > Home > Other ways to build > Agent (Standard), enter a name, select Create.
  2. Add a description and instructions on the Overview page.
Checkpoint: The agent opens with Overview, Knowledge, Topics and Channels tabs.
Home > Other ways to build > Agent (Standard)
Home > Other ways to build > Agent (Standard)
2

Require Microsoft sign-in

The Agents SDK only works with authenticated agents, and it is what makes the agent know the user.

  1. Settings > Security > Authentication > Authenticate with Microsoft (default for new agents) > Save.
Checkpoint: Channels shows You're using Microsoft authentication, so only Teams and Microsoft 365 and SharePoint channels are available.
Settings > Security > Authentication
Settings > Security > Authentication
3

Greet the user by name (recommended)

A personalised greeting proves on every page that the user's identity reaches the agent.

  1. Topics > System > Conversation Start > ... > Open code editor.
  2. Replace only the text of the first message (keep the existing id), then Save.
    text:
      - "Hello {System.User.DisplayName}! I'm {System.Bot.Name}. How can I help?"
Checkpoint: The topic saves without errors. After you publish, the greeting shows the signed-in user's name (seen on every test page).
Conversation Start topic in the code editor
Conversation Start topic in the code editor
4

Publish and copy the connection string

Pages connect to the published agent through this string. It contains no secret.

  1. Select Publish.
  2. Channels > Web app (or Native app) > Microsoft 365 Agents SDK > Copy.
https://<environment>.environment.api.powerplatform.com/copilotstudio/dataverse-backed/authenticated/bots/<schema-name>/conversations?api-version=2022-03-01-preview
Checkpoint: The string ends with /bots/<agent schema name>/conversations?api-version=....
Channels > Web app > Microsoft 365 Agents SDK
Channels > Web app > Microsoft 365 Agents SDK
5

Share the agent

Sharing decides who can chat - on every site and page.

  1. ... > Share > add users or Entra security groups > keep End user access > Share.
Checkpoint: The people or groups appear under Existing users as Viewer.
Share with users or security groups
Share with users or security groups

Part 2One-time tenant setup

6

Register the Entra SPA app

SPFx's built-in token provider cannot get the Copilot Studio scope, so the web part signs in with its own app.

  1. Copy scripts/variables.sample.ps1 to scripts/variables.ps1 and fill it in.
  2. Run the script (idempotent). It adds the SPA redirect URI (your SharePoint origin), the delegated Power Platform API > CopilotStudio.Copilots.Invoke permission and tenant-wide consent.
. .\scripts\variables.ps1
az login --tenant $TenantDomain --allow-no-subscriptions
.\scripts\New-AgentsSdkSpaApp.ps1 -TenantId $TenantDomain -SharePointRootUrl $SharePointRootUrl
Checkpoint: The output shows "adminConsent": "granted"; note the appClientId.
7

Build the SharePoint package

The package carries the app ID as tenant default, so page authors only paste a connection string.

  1. Node 22 is required for SPFx 1.21.1. MSAL, the Agents SDK client and Web Chat are bundled - no CDN or API-access approvals.
.\scripts\Build-SpfxPackage.ps1 -AppClientId $AppClientId -Version $PackageVersion -NodePath $Node22Path
# -> spfx-copilot-agent\sharepoint\solution\copilot-studio-agent-webpart.sppkg
Checkpoint: copilot-studio-agent-webpart.sppkg is created.
8

Deploy it to every site

One deployment makes the web part available on all current and future sites.

  1. SharePoint admin center > Active sites > Apps > Membership > add yourself as site admin of the app catalog.
  2. App catalog > Manage apps > Upload the .sppkg (Replace for updates) > Enable this app and add it to all sites > Enable app.
Checkpoint: Manage apps lists the package as Enabled and Added to all sites: Yes.
Enable this app and add it to all sites
Enable this app and add it to all sites
Version 1.0.3.0 enabled for all sites
Version 1.0.3.0 enabled for all sites

Part 3Add the agent to your sites

9

Add the web part and paste the connection string

Each page decides which agent it shows; repeat on as many sites as you like.

  1. Edit the page > + > Copilot Studio Agent (Agents SDK).
  2. Edit properties > Integration mode Microsoft 365 Agents SDK > paste the connection string. Leave app and tenant ID empty (package defaults).
  3. Republish the page.
Checkpoint: The chat shows your personalised greeting, even in edit mode.
Toolbox: Copilot Studio Agent (Agents SDK)
Toolbox: Copilot Studio Agent (Agents SDK)
Property pane: paste the connection string
Property pane: paste the connection string
10

Give people access to the site

SharePoint still decides who can open the page. Visitor (Read) is enough.

  1. Grant site or page access as usual. Agent sharing and site permissions are independent - people need both.
Checkpoint: A test user opens the page and sees the chat.
Published page with two agents
Published page with two agents

Part 4Verify

11

Run the core test scenarios

Five checks prove sign-in, identity, access control and the security boundary.

  1. Shared user: greeting by name and an answer (TC-01, TC-02, TC-05).
  2. Unshared user: You don't have access to talk to this bot (TC-06).
  3. Anonymous call to the connection string returns HTTP 401 (TC-04).
Invoke-WebRequest -Method Post -Uri $AgentConnectionString -ContentType 'application/json' `
  -Body '{"emitStartConversationEvent":true}' -SkipHttpErrorCheck | Select-Object StatusCode   # 401
Checkpoint: All five results match the expected results in the test scenarios.
Shared user: personalised greeting and answer
Shared user: personalised greeting and answer
Unshared user: blocked by Copilot Studio
Unshared user: blocked by Copilot Studio
12

Run the resilience checks

Confirms the experience when silent sign-in is blocked, access changes, or a user restarts.

  1. Silent sign-in blocked: Sign in with Microsoft opens the popup on the first click (TC-03).
  2. Remove and re-add a user on the agent (TC-07, TC-08); select New chat (TC-22).
Checkpoint: The chat connects after one click and access changes apply on the next page load.
Silent sign-in blocked: one-click sign-in
Silent sign-in blocked: one-click sign-in
After the popup: greeting and answer
After the popup: greeting and answer
13

Automate the regression run (optional)

Re-run the same scenarios after every agent or package change.

  1. Edit tests/agents-sdk-matrix/settings.py, then run the harness (Edge + Playwright, one profile per test user).
cd tests\agents-sdk-matrix
.\launch-edge.ps1
foreach ($p in 'mario','a','b','c','d') { python run_matrix.py $p }
python run_extra_scenarios.py a A      # TC-03 sign-in fallback + TC-22 New chat
python summarize.py
Checkpoint: output/results/summary.md shows the expected result for every persona and site.
Test scenarios

27 scenarios with expected and actual results

Executed in the demo tenant on 7 Oct 2026 with 4 test users, 3 sites, 2 agents and the maker as control (web part 1.0.3.0). Select a row for steps, expected result, actual result and evidence.

Results in the demo tenant

Pass: 16Confirmed limitation: 1Security finding: 1Not run: 9

Defect found and fixed during testing: TC-03 (sign-in popup blocked on pages with several agents) - fixed in web part 1.0.2.0/1.0.3.0 and re-tested.

By area

AreaScenariosPassLimitation / findingNot run
Sign-in and identity4400
Access control6501
Sites and pages5401
Licensing and capacity2101
Agent types2020
Lifecycle and operations4202
Extended scenarios4004
Status
Priority
IDScenarioAreaPriorityResult in the demo tenant

Test setup

Agent A = standard harness, shared with User A and User B. Agent B (Weather) = GitHub Copilot harness, shared with User A and User C. User D has no agent. Every site page hosts Agent A and Agent B via the Agents SDK web part plus Agent B's hosted embed for comparison. Test users: Microsoft 365 E5 (no Teams), no Copilot licenses, MFA.

PersonaAgent sharingSite ASite BSite C
User AAgent A + Agent BVisitorMemberOwner
User BAgent AMemberVisitorNo access
User CAgent BNo accessMemberVisitor
User DNoneVisitorNo accessMember
MarioR (maker)Owner of bothOwnerOwnerOwner

Reading the results

Pass behaved as expected. Confirmed limitation documented product limitation reproduced. Security finding behaviour to be aware of (not the Agents SDK path). Not run recommended for your tenant - the expected result is the requirement to verify.

The core set (TC-01, TC-02, TC-04, TC-05, TC-06) is the quick regression after any agent or package change.

Run it in your tenant

From demo results to your sign-off

1. Use the Excel test plan

The Excel test plan lists every scenario with preconditions, steps, expected result and the demo result. Fill in Your result, Tester, Date and Notes; the Summary sheet counts passes, failures and the P1 pass rate.

2. Start with P1 and the core set

11 scenarios are P1 (must pass before go-live), including the ones this engagement could not run: security-group sharing (TC-09) and SharePoint knowledge permissions (TC-26, when used).

3. Automate the regression

The Playwright harness drives real Edge windows, one profile per test user, and records greeting, answer, errors and a screenshot per web part.

cd tests\agents-sdk-matrix
.\launch-edge.ps1
foreach ($p in 'mario','a','b','c','d') { python run_matrix.py $p }
python run_extra_scenarios.py a A   # TC-03 + TC-22
python summarize.py

4. Keep test accounts safe

Test-user passwords and MFA seeds stay in a secrets folder outside the repository ($env:AGENTS_SDK_TEST_SECRETS_DIR). Delete the test users and the SPA app registration when you are done (guide section 13).

Limits

Not supported, and known design limits

Not supported

  • GitHub Copilot harness agents through the Agents SDK - Copilot Studio replies This action doesn't support agents built with the GitHub Copilot harness. - verified for every user including the owner. Build SharePoint-facing agents on the standard harness.
  • SPFx built-in token provider (AadTokenProvider) - Cannot obtain CopilotStudio.Copilots.Invoke (sp-dev-docs #10775). The web part uses MSAL.js with its own SPA app instead.
  • App-only (service principal) tokens - Not supported by the Agents SDK client (Microsoft Learn). Use Direct Line for server-to-server scenarios.
  • Hosted web chat embed as an access boundary - Copilot Studio offers the embed code only for agents without authentication. The GitHub Copilot harness embed answered unshared and signed-out users in this test.

Design limits of this web part

  • Token lifetime - the client receives an access token, not a token provider. If a long-open conversation stops answering, New chat signs in again silently (TC-23).
  • Embedded hosts - Teams, Viva Connections or the mobile app can block the hidden sign-in frame or popups; validate TC-15 before using these entry points.
  • Page context - not passed to the agent yet; the documented event pattern needs a small extension (UC-11).
  • Capacity - unlicensed users consume Copilot Studio capacity; monitor it (TC-17).
Resources

Companion material and references

Companion material

Source code and guide

https://github.com/patmeh1/copilot-studio-agents-sdk-sharepoint

  • docs/Agents-SDK-SharePoint-Tutorial.md and docs/Agents-SDK-SharePoint-Use-Cases-and-Test-Scenarios.md - this page as markdown
  • docs/Agents-SDK-SharePoint-Guide.md - full guide, findings and troubleshooting
  • spfx-copilot-agent/, scripts/, tests/agents-sdk-matrix/ - web part, setup scripts, test harness