Skip to content

fix(headers): allow the microphone on our own origin - #888

Merged
catomean merged 1 commit into
mainfrom
fix/allow-microphone
Sep 4, 2026
Merged

fix(headers): allow the microphone on our own origin#888
catomean merged 1 commit into
mainfrom
fix/allow-microphone

Conversation

@catomean

@catomean catomean commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

Permissions-Policy sent microphone=() — an empty allowlist, which denies the feature to every origin including this one. The browser therefore never shows a permission prompt at all; getUserMedia rejects immediately with NotAllowedError.

Measured on orangecat.ch before this change:

document.featurePolicy.allowsFeature('microphone') -> false
navigator.permissions.query({name:'microphone'})   -> "denied"   (not "prompt")
getUserMedia({audio:true})                         -> NotAllowedError

That silently disabled speak-to-report in the embedded FleetCrown feedback widget, and no visitor could fix it — there was nothing to allow. The symptom read as "Microphone permission denied", which points at the person rather than at the header actually responsible.

The change

- value: 'camera=(), microphone=(), geolocation=()',
+ value: 'camera=(), microphone=(self), geolocation=()',

(self) permits this origin only, so the browser asks the person — which is the decision that should be theirs. It does not grant the mic to embedded third-party frames.

camera and geolocation stay fully denied: nothing here uses them, and an unused capability should not be reachable.

Verification

npm run verify passes — 282 test files, 2648 tests.

Companion fix in bitbaum/fleetcrown#474 makes the widget detect a policy block and hide the mic button entirely, so sites that keep microphone=() degrade silently instead of showing a control that can only fail. That half is central; this half cannot be — Permissions-Policy is the host document's decision by design.

Permissions-Policy sent `microphone=()` — an EMPTY allowlist, which denies
the feature to every origin INCLUDING this one. The browser therefore never
shows a permission prompt at all; getUserMedia rejects immediately with
NotAllowedError.

Measured on orangecat.ch before this change:
  document.featurePolicy.allowsFeature('microphone') -> false
  navigator.permissions.query({name:'microphone'})   -> "denied"

That silently disabled speak-to-report in the embedded FleetCrown feedback
widget, and no visitor could fix it — there was nothing to allow. The
symptom read as "Microphone permission denied", which points at the person
rather than at the header actually responsible.

`(self)` permits this origin only, so the browser asks the person — which
is the decision that should be theirs. camera and geolocation stay fully
denied: nothing here uses them, and an unused capability should not be
reachable.

npm run verify passes (282 files, 2648 tests).
@catomean
catomean merged commit bdb0999 into main Sep 4, 2026
6 checks passed
@catomean
catomean deleted the fix/allow-microphone branch September 4, 2026 00:26
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.

1 participant