Approximate Geolocation: Permissions Model Comparison

PR #195 adds approximate location support to the Geolocation API. Both sides agree on letting developers pass {accuracyMode: "approximate"} to getCurrentPosition() to declare what accuracy they need.

The question we need to settle: should "geolocation-approximate" be a separately queryable permission via permissions.query()?

This demo tests both models against real developer patterns. Toggle the permission state above to see how each model behaves.

Weather App

A weather app only needs city-level location. It declares what accuracy it needs and handles the result. Under both models, this works identically.

const status = await navigator.permissions.query({
  name: "geolocation"
});
navigator.geolocation.getCurrentPosition(
  showWeather, showManualEntry, {accuracyMode: "approximate"}
);
Chromium proposal (two permissions):
WebKit proposal (one permission):

Upgrade Flow

A ride-sharing app starts with approximate location (show nearby drivers), then requests precise when the user taps "Set pickup location." In both models, the approximate call succeeds. The precise call prompts when only "geolocation-approximate" was granted, because the user is being asked for more. The difference: under the two-permission model, the developer can predict this prompt via query(). Under the single-permission model, they call the API and handle the result.

navigator.geolocation.getCurrentPosition(
  showNearbyDrivers, showManualAddress, {accuracyMode: "approximate"}
);

navigator.geolocation.getCurrentPosition(
  setPrecisePickup, handleError, {accuracyMode: "precise"}
);
Chromium proposal (two permissions):
then
WebKit proposal (one permission):
then

The enableHighAccuracy Precedent

Today, enableHighAccuracy is a PositionOptions hint with no separate queryable permission and no result attribute reporting what the UA did. query({name: "geolocation"}) returning "granted" has never guaranteed high-accuracy results. The developer checks coords.accuracy after the call. This is the existing precedent for how option hints interact with the permission model.

const status = await navigator.permissions.query({
  name: "geolocation"
});
navigator.geolocation.getCurrentPosition(success, error, {
  enableHighAccuracy: true
});
Chromium proposal (two permissions):
WebKit proposal (one permission):

Passive Queryability

Under the two-permission model, a script can determine whether the user chose approximate-only by querying both permission names on page load, without calling getCurrentPosition() and without a user gesture. Under the single-permission model, only "geolocation" is queryable, so this distinction is not observable until the API is actually called. See w3c/permissions#52 for background on passive queryability concerns.

const approx = await navigator.permissions.query({
  name: "geolocation-approximate"
});
const precise = await navigator.permissions.query({
  name: "geolocation"
});
if (approx.state === "granted" && precise.state === "prompt") {
  trackUserPrivacyPreference("approximate-only");
}
Chromium proposal (two permissions):
approx: + precise:
WebKit proposal (one permission):
geolocation: (only queryable)

The onchange Scenario

Under the two-permission model, a script can subscribe to permission state changes via onchange. This has a legitimate use: a site adapts its UI when the user changes settings. It also has a privacy concern: a third-party script can subscribe, wait for the user to grant access to the embedding page, then call the API at that moment without an additional prompt appearing.

const status = await navigator.permissions.query({
  name: "geolocation-approximate"
});
status.onchange = () => {
  if (status.state === "granted") {
    navigator.geolocation.getCurrentPosition(callback);
  }
};
Chromium proposal (two permissions):
WebKit proposal (one permission):

Full 12-scenario matrix
State Action Two-Permission predicts? Single-Permission predicts?