Skip to content

Add privacy and security mitigations to the Web Speech API - #165

Open
evanbliu wants to merge 9 commits into
WebAudio:mainfrom
evanbliu:Privacy
Open

evanbliu wants to merge 9 commits into
WebAudio:mainfrom
evanbliu:Privacy

Conversation

@evanbliu

@evanbliu evanbliu commented Jun 17, 2025 •

Copy link
Copy Markdown
Collaborator

This PR adds the privacy and security mitigations used by the Writing Assistance APIs to the on-device speech recognition part of the Web Speech API.

Closes #158


Preview | Diff

@evanbliu
evanbliu requested a review from padenot June 17, 2025 17:45
@evanbliu

evanbliu commented Mar 4, 2026

Copy link
Copy Markdown
Collaborator Author

@padenot - I just realized this PR was never merged. Can you please take a look when you get a chance?

Comment thread index.bs Outdated
Comment thread index.bs Outdated
Comment thread index.bs Outdated
Comment thread index.bs Outdated
@evanbliu
evanbliu requested a review from marcoscaceres March 5, 2026 00:21
@evanbliu
evanbliu requested a review from hoch August 25, 2026 17:59

@hoch hoch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Mostly nits. Looking good!

Comment thread index.bs Outdated
Comment thread index.bs Outdated
Comment thread index.bs Outdated
- Fix formatting for `true` code span
- Fix typo: 'an per-API' -> 'a per-API'
- Remove redundant Alternate Options subsection
@evanbliu
evanbliu requested a review from hoch September 2, 2026 18:41

@hoch hoch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Mostly nits, but I do have some questions.

Comment thread index.bs Outdated
Comment thread index.bs Outdated
Comment thread index.bs Outdated
Comment thread index.bs Outdated
Comment thread index.bs Outdated
Comment thread index.bs Outdated
Review comments addressed:
- install(): add the transient user activation requirement to the
  algorithm so it matches the privacy section's claim. The check is
  keyed off the (masked) availability status so that whether install()
  requires activation cannot itself leak the true download status.
  Document the NotAllowedError rejection and link the privacy bullet to
  the new step.
- Download Masking: drop the vestigial "API" component from the masking
  state tuple.
- Installation-time friction: name the "on-device-speech-recognition"
  policy-controlled feature directly instead of "per-API".
- Disk Space / Runtime Shared Resources: "set to `true`" and
  "a SpeechRecognitionErrorEvent".
- OS-Provided Models: reword to match the Writing Assistance source text
  ("still need to ensure ... even if the user agent has less control"),
  making clear this restates requirements defined elsewhere rather than
  adding an unmarked normative one.

Editorial cleanups of the same classes found while reviewing:
- Remove remaining vestigial multi-API wording ("these APIs") and the
  "UA" abbreviation; spell out "user agent".
- Mark the user-agent transparency "should" in the cloud section per
  this section's <strong> convention; de-2119 developer guidance.
- Nest Download Masking under Language Pack Availability so that
  masking/friction/cancelation/eviction are siblings, as in the source.
- Title-case the "Installation-Time Friction" heading; fix a subject
  shift in the unmasking sentence; strip trailing whitespace.

Also merges upstream/main (needed because WebAudio#200 restructured install()).
@evanbliu
evanbliu requested a review from hoch October 8, 2026 21:00

@hoch hoch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM!

Comment thread index.bs Outdated

@padenot padenot left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we know why we can't have this be normal normative requirements, and we're putting them in their own sections? It makes it harder to read no?

Comment thread index.bs Outdated
Comment thread index.bs Outdated
@evanbliu

evanbliu commented Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator Author

@padenot Done, I moved all the normative requirements into the API Description section (under processLocally, available(), install(), and start()) and marked the privacy and security subsections in Section 3 as non-normative.

@evanbliu
evanbliu requested a review from padenot October 14, 2026 22:24

@padenot padenot left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I like this, thanks a lot for doing it, and revising it to inline the behaviour inside the normative text. Some comments inline, but generally in favour.

Comment thread index.bs

The Web Speech API can support both server-based (cloud) and client-based/embedded (on-device) recognition and synthesis. The {{SpeechRecognition/processLocally}} attribute allows developers to indicate a requirement for on-device processing.

When {{SpeechRecognition/processLocally}} is `false` (the default), user speech data might be sent to a remote server for processing. Web developers need to be aware of this possibility and the associated privacy implications if they do not explicitly request local processing, and <a href="#req-cloud-transparency">user agents are encouraged to be transparent</a> with users about where speech processing occurs.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This reminds me we might need investigate investigate having processLocally to be true initially, and/or disallowing changing it.

In Firefox, it's always ever local, and will never be remote, and it seems to me that that the advances in technology will make this possible more and more, with high quality.

Comment thread index.bs

As specified in <a href="#req-disk-space">the storage pressure rules</a> for {{SpeechRecognition/install()}}, in the event of storage pressure, user agents are expected to balance the utility of on-device speech recognition with the disk space its language packs take up—possibly by having {{SpeechRecognition/install()}} resolve to `false` for new downloads or by freeing up disk space in other ways, while remaining mindful of the privacy impacts discussed in <a href="#on-device-model-privacy-availability-eviction">Download Eviction</a> and potentially involving the user via download-time prompts or a browser UI for managing downloaded language packs.

If a previously installed language pack is evicted (e.g., by the user or due to extreme storage pressure) while it might be in use or expected to be available, subsequent attempts to use it (e.g., via {{SpeechRecognition/start()}} with {{SpeechRecognition/lang}} set to that language and {{SpeechRecognition/processLocally}} set to `true`) are expected to <a href="#req-eviction-graceful-failure">fail gracefully</a>. This might involve {{SpeechRecognition/available()}} returning {{"downloadable"}} (or {{"unavailable"}} if no longer supported), and {{SpeechRecognition/start()}} firing a {{SpeechRecognitionErrorEvent}} with an appropriate error code like {{SpeechRecognitionErrorCode/service-not-allowed}} or {{SpeechRecognitionErrorCode/language-not-supported}}.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It doesn't have to fail, but it can. In Firefox, you can manage the installed models in couple ways, and delete them when you want, but if a session is running, it will continue to work.

We could imagine making subsequent sessions still work since the model is still in memory. Generally after this it won't work though, e.g. after stop().

Comment thread index.bs

On-device speech recognition can consume significant runtime resources like CPU, memory, and potentially specialized hardware accelerators.

As described in <a href="#req-runtime-resources">the runtime resource requirements</a> of the [=start session algorithm=], user agents are expected to ensure that one web page's use of on-device speech recognition does not overly interfere with another web page's use of the API, another web page's general operation, or overall system stability. For example, a background tab ought not to be able to monopolize speech processing resources and prevent a foreground tab from using them.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This usually doesn't apply for audio-related things. There's is very little notion of "background" for audio, since we can hear things not in foreground. It's also quite hard to know if the text is displayed, e.g. a subtitles, in which case we could conceivably discard them / stop processing the audio.

But realistically, if I'm dictating a document, transcribing a meeting, or talking with an AI agent (that will likely answer in audio), I really want this to work, regardless of background/foreground.

Comment thread index.bs

As described in <a href="#req-runtime-resources">the runtime resource requirements</a> of the [=start session algorithm=], user agents are expected to ensure that one web page's use of on-device speech recognition does not overly interfere with another web page's use of the API, another web page's general operation, or overall system stability. For example, a background tab ought not to be able to monopolize speech processing resources and prevent a foreground tab from using them.

This specification does not mandate any particular mitigation strategy, but possible approaches include queuing requests, rate limiting, prioritizing foreground tabs, or detecting abusive behavior, and failing speech recognition operations (e.g., by firing a {{SpeechRecognitionErrorEvent}} with {{SpeechRecognitionErrorCode/service-not-allowed}}) when necessary to prevent resource exhaustion or instability.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Our current approach (until we generalize hardware inference) is to limit to a single concurrent session. This isn't amazing for fingerprinting, but exhausting the machine's resources isn't amazing at all.

This branch has not been deployed

No deployments
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.

Apply privacy and security mitigations used by the Web Translation API to the Web Speech API

5 participants