# Notification permission as a fingerprint: 344 said denied

> Notification permission became a fingerprint: Notification.permission read denied on all 344 of our profiles, where an unconfigured Chrome says default.

Source: https://mosaicbrowser.com/blog/notification-permission-denied

## 344 profiles said "denied": one value, everywhere

Notification permission became a fingerprint: Notification.permission read denied on all 344 of our profiles, where an unconfigured Chrome says default.

![344: One value, the same on every profile we had made](https://mosaicbrowser.com/covers/notification-permission-denied.webp)

Notification permission is a fingerprint the moment it is the same everywhere. In September 2026 we found `Notification.permission` reading `denied` on all 344 profiles on our build Mac, while an unconfigured Chrome says `default`. No single profile looked strange on its own. Together they all shared one uncommon value, which is exactly what a site needs to group accounts.

## How notification permission becomes a fingerprint

Two calls report the state without asking the user anything. `Notification.permission` returns `default`, `granted` or `denied`. `navigator.permissions.query({ name: 'notifications' })` returns `prompt`, `granted` or `denied`. Neither shows a dialog, so any script can read them on page load.

A fresh browser that nobody has configured says `default` and `prompt`. `denied` means somebody refused: the person, an administrator's policy, or a setting. That is not rare in itself. It becomes a signal when it arrives on every account a site suspects of being run from one place.

Mosaic is a desktop app

Email yourself the link and open it on your computer.

[How it works: Machines that exist](https://mosaicbrowser.com/features/real-fingerprints)

## Why we forced it

The setting came from our launcher. Each launch wrote the notifications content setting as blocked into the profile's preferences, and the reason was a real one when it was written.

macOS greets every app identity it has not seen before with a banner, once and for ever, saying that app's notifications "may include alerts, sounds and icon badges". Early on, each Mosaic profile ran under its own app bundle with its own identifier, so every new profile risked one more of those banners. Blocking notifications for every launch stopped the browser from asking macOS at all.

Then the bundles changed. They became one per window slot instead of one per profile, which caps the banners at five for the life of an install. The reason for blocking was gone. The cost was not, and nobody re-read the sentence that justified it.

![The Mosaic profiles table, each row a profile with its own tags and proxy](https://mosaicbrowser.com/shots/profiles-list.png)
*Every row here reported the same permission*

## The exemption that hid it

We have a sweep for this class of fault. It draws two profiles that share nothing, reads the same values in both, and reports anything identical that should not be. The notification row was in it, reading `denied` in both halves, and it sat on the list of expected matches with a six-word excuse: "blocked on purpose; see preparePreferences".

That excuse was true. It was blocked on purpose. The purpose had expired, and the exemption had no way to notice. An exemption is only worth as much as someone re-reading its reason.

The fault also runs in the opposite direction from the one we usually look for. We had spent the week finding values that leaked in from the host, like the dark-mode and accessibility settings the computer itself had turned on. This one did not leak in. We pinned it, the same across the whole population and different from stock Chrome. A site reads both cases the same way.

## What changed

Blocking notifications is a privacy setting now, `privacy.blockNotifications`, and it is off by default. We measured the result through the app, on a profile launched the ordinary way:

```
Notification.permission                        "default"
permissions.query({name: 'notifications'})     "prompt"
macOS registered notification bundles          68 before, 68 after

```

The last line is the reason the original block existed. With window-slot bundles, launching a profile no longer registers anything new with macOS, so the banner it was there to prevent does not arrive.

## The rule we took from it

Before a value is pinned across every profile, compare it with what a stock Chrome of the same version on the same machine reports. If they differ, the pin is a fingerprint, whatever it was meant to prevent. [A geolocation that answered once](https://mosaicbrowser.com/blog/geolocation-answered-once) was a value that behaved like no real device. This one behaved like no real population.

Where the rest of a profile's values come from is on [real fingerprints](https://mosaicbrowser.com/features/real-fingerprints), and what a site can read without a prompt is listed in [browser fingerprint](https://mosaicbrowser.com/glossary/browser-fingerprint). The same habit, checking the profile against what it claims, is how we found [a profile in Austria claiming New York](https://mosaicbrowser.com/blog/austria-claimed-new-york).

## Questions

### Can notification permission be used as a fingerprint?

Yes, weakly on its own and strongly in a group. Notification.permission and the Permissions API both report it without a prompt. A value that is uncommon, or the same across many accounts that claim to be different people, helps a site group them.

### What does an unconfigured Chrome report?

On our Mac, a fresh Chrome profile reports Notification.permission as default, and navigator.permissions.query for notifications as prompt. Denied appears only after a person, a policy or a setting has refused.

### Why were Mosaic profiles reporting denied?

We forced the notification content setting off at every launch to avoid a macOS banner per app identity. When identities moved to one per window slot that reason expired, but the forced setting stayed.

### Can I still block notifications on a profile?

Yes. Blocking is a privacy setting now, off by default, so a profile reports what an ordinary Chrome reports unless you ask it not to.

## Related

[A spoof that answers once: the geolocation bug we shipped](https://mosaicbrowser.com/blog/geolocation-answered-once): A geolocation spoofing timeout we shipped: the first getCurrentPosition got the exit's coordinates, every later call failed with code 3. One latch was to blame.

[A profile in Austria claimed New York](https://mosaicbrowser.com/blog/austria-claimed-new-york): Browser location does not match IP: a no-proxy profile made in Austria claimed New York. One failed lookup was never retried, and a table filled the gap.

[Machines that exist: fingerprints drawn from real hardware](https://mosaicbrowser.com/features/real-fingerprints): Mosaic draws each profile's GPU, screen, CPU, memory and fonts from one real device, so the parts of a fingerprint agree with each other and with the host.

[Browser fingerprint: what a site can read about your machine](https://mosaicbrowser.com/glossary/browser-fingerprint): A browser fingerprint is the set of values a site reads about your browser and computer, which together recognize you without cookies. What goes into one.









## Mosaic, on your own computer

The browser this blog is about: its own Chromium, fingerprints from real machines and a proxy exit per profile. Free holds 3 profiles. Pro is $49 a month for any number.

Mosaic is a desktop app

Email yourself the link and open it on your computer.
