Target SharePoint environment
SharePoint Online
What SharePoint development model, framework, SDK or API is this about?
💥 SharePoint Framework
Developer environment
None
What browser(s) / client(s) have you tested
Additional environment details
SPFx version: 1.24.0-beta.2
@microsoft/sp-copilot-component version: 1.24.0-beta.2
@azure/communication-react version: 1.34.0
@azure/communication-calling (peer dep): 1.43.1
@azure/communication-common: 2.5.0
Browser + version: [FILL IN - e.g. Edge 12x]
Tested via: Copilot Workbench (works), Microsoft 365 Copilot production (fails)
Describe the bug / error
A Copilot Component that uses getUserMedia() for live camera/microphone streaming (via @azure/communication-react's CallComposite, which wraps the ACS Calling SDK) works correctly when run through the Copilot Workbench, but camera/microphone access is fully blocked once the same component is deployed and invoked through production Microsoft 365 Copilot. The browser never even shows a permission prompt in production - the request is rejected at the Permissions Policy level by the host's iframe container, despite devicePermissions: ["media"] being declared in the app manifest.
Steps to reproduce
Scaffold a Copilot Component that calls navigator.mediaDevices.getUserMedia({ video: true, audio: true }) (directly, or indirectly via CallComposite/ACS Calling SDK).
Run locally via Copilot Workbench (/_layouts/15/copilotworkbench.aspx) and trigger the code path that calls getUserMedia(). Camera/mic access is granted correctly.
Deploy the same component and invoke it through production Microsoft 365 Copilot instead.
Trigger the same code path.
Expected behavior
The browser prompts the user for camera/microphone permission (or honors previously-granted permission), consistent with devicePermissions: ["media"] being declared in the manifest.
Actual behavior
No permission prompt appears. Browser console shows:
[Violation] Permissions policy violation: microphone is not allowed in this document.
[Violation] Permissions policy violation: camera is not allowed in this document.
Hardware access blocked by host container permissions: NotAllowedError: Permission denied
Traced the third line to @microsoft/sp-copilot-component's own compiled client runtime (bundled into our component's output), not our application code. It is an internal permission-probe helper with this shape:
js
try {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true });
stream.getTracks().forEach(track => track.stop()); // probe only, tracks released immediately
onGranted();
} catch (e) {
console.error("Hardware access blocked by host container permissions:", e);
}
This appears to be the SDK's own built-in mechanism for checking/granting media device capability to a Copilot Component - i.e. this is not a failure in our custom getUserMedia usage, it is Microsoft's own first-party permission-check code hitting the same Permissions Policy block.
Additional notes
We initially suspected this was a script/tool-input timing issue (a separate Error: Host did not send tool-input within 30000ms we hit and resolved by making an unused required property optional in our Zod properties schema) - once that was fixed and the component initialized correctly, this Permissions Policy block is what's actually surfacing.
devicePermissions: ["media"] is documented for the microsoftTeams.media.* capture APIs (captureImage/selectMedia/getMedia) per https://learn.microsoft.com/en-us/microsoftteams/platform/concepts/device-capabilities/media-capabilities - not confirmed to apply to raw getUserMedia() streaming inside a Copilot Component.
Suspect the production M365 Copilot host is not adding allow="camera; microphone" (or equivalent Permissions-Policy header) to the iframe hosting the Copilot Component, regardless of the devicePermissions manifest declaration.
Confirmed via direct comparison: the same permission probe succeeds without issue in the Copilot Workbench (/_layouts/15/copilotworkbench.aspx) - camera/mic access works there. It only fails once the component is deployed and invoked through production Microsoft 365 Copilot. This points to a difference in how the two hosts construct/permission the component's iframe, rather than anything in our manifest or code.
Target SharePoint environment
SharePoint Online
What SharePoint development model, framework, SDK or API is this about?
💥 SharePoint Framework
Developer environment
None
What browser(s) / client(s) have you tested
Additional environment details
SPFx version: 1.24.0-beta.2
@microsoft/sp-copilot-component version: 1.24.0-beta.2
@azure/communication-react version: 1.34.0
@azure/communication-calling (peer dep): 1.43.1
@azure/communication-common: 2.5.0
Browser + version: [FILL IN - e.g. Edge 12x]
Tested via: Copilot Workbench (works), Microsoft 365 Copilot production (fails)
Describe the bug / error
A Copilot Component that uses getUserMedia() for live camera/microphone streaming (via @azure/communication-react's CallComposite, which wraps the ACS Calling SDK) works correctly when run through the Copilot Workbench, but camera/microphone access is fully blocked once the same component is deployed and invoked through production Microsoft 365 Copilot. The browser never even shows a permission prompt in production - the request is rejected at the Permissions Policy level by the host's iframe container, despite devicePermissions: ["media"] being declared in the app manifest.
Steps to reproduce
Scaffold a Copilot Component that calls navigator.mediaDevices.getUserMedia({ video: true, audio: true }) (directly, or indirectly via CallComposite/ACS Calling SDK).
Run locally via Copilot Workbench (/_layouts/15/copilotworkbench.aspx) and trigger the code path that calls getUserMedia(). Camera/mic access is granted correctly.
Deploy the same component and invoke it through production Microsoft 365 Copilot instead.
Trigger the same code path.
Expected behavior
The browser prompts the user for camera/microphone permission (or honors previously-granted permission), consistent with devicePermissions: ["media"] being declared in the manifest.
Actual behavior
No permission prompt appears. Browser console shows:
[Violation] Permissions policy violation: microphone is not allowed in this document.
[Violation] Permissions policy violation: camera is not allowed in this document.
Hardware access blocked by host container permissions: NotAllowedError: Permission denied
Traced the third line to @microsoft/sp-copilot-component's own compiled client runtime (bundled into our component's output), not our application code. It is an internal permission-probe helper with this shape:
js
try {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true });
stream.getTracks().forEach(track => track.stop()); // probe only, tracks released immediately
onGranted();
} catch (e) {
console.error("Hardware access blocked by host container permissions:", e);
}
This appears to be the SDK's own built-in mechanism for checking/granting media device capability to a Copilot Component - i.e. this is not a failure in our custom getUserMedia usage, it is Microsoft's own first-party permission-check code hitting the same Permissions Policy block.
Additional notes
We initially suspected this was a script/tool-input timing issue (a separate Error: Host did not send tool-input within 30000ms we hit and resolved by making an unused required property optional in our Zod properties schema) - once that was fixed and the component initialized correctly, this Permissions Policy block is what's actually surfacing.
devicePermissions: ["media"] is documented for the microsoftTeams.media.* capture APIs (captureImage/selectMedia/getMedia) per https://learn.microsoft.com/en-us/microsoftteams/platform/concepts/device-capabilities/media-capabilities - not confirmed to apply to raw getUserMedia() streaming inside a Copilot Component.
Suspect the production M365 Copilot host is not adding allow="camera; microphone" (or equivalent Permissions-Policy header) to the iframe hosting the Copilot Component, regardless of the devicePermissions manifest declaration.
Confirmed via direct comparison: the same permission probe succeeds without issue in the Copilot Workbench (/_layouts/15/copilotworkbench.aspx) - camera/mic access works there. It only fails once the component is deployed and invoked through production Microsoft 365 Copilot. This points to a difference in how the two hosts construct/permission the component's iframe, rather than anything in our manifest or code.