Website Permissions
Dumber handles website permission requests for media access (microphone, camera, screen sharing) following W3C standards.
Permission Types
Auto-Allowed
These permissions are automatically granted without user interaction:
User-Confirmed
These permissions require explicit user approval:
- Microphone - Websites can request audio capture access
- Camera - Websites can request video capture access
When both microphone and camera are requested together, a combined dialog is shown.
WebAuthn / passkeys / security keys
Dumber currently disables WebAuthn (PublicKeyCredential, passkeys, FIDO2/security keys) in embedded CEF panes. The current CEF integration uses windowless/OSR Alloy browsers and does not expose the Chromium WebAuthn request UI/delegate needed for PIN, account selection, or transport UI.
If a site requires passkeys or hardware security keys, use the system browser for that auth flow until a dedicated Chrome-runtime auth-window prototype exists.
⚠️ Developer override (unsupported): Set DUMBER_CEF_ENABLE_WEBAUTHN_UNSAFE=1 to temporarily re-enable WebAuthn. This is unsupported and may crash.
Permission Dialog
When a site requests mic/camera access, a dialog appears with four options:
| Button |
Action |
Persistence |
| Allow |
Grant permission once |
Not saved |
| Always Allow |
Grant and remember |
Saved per origin |
| Deny |
Block permission once |
Not saved |
| Always Deny |
Block and remember |
Saved per origin |
How Permissions Work
Origin-Based Storage
Permissions are stored per-origin (scheme + host + port), not per-page.
Default ports are normalized away (:80 for http, :443 for https). This means:
https://meet.google.com/room1 and https://meet.google.com/room2 share the same permission (same origin)
https://meet.google.com:443/room1 and https://meet.google.com/room1 share the same permission (default https port)
https://meet.google.com:8443/room1 and https://meet.google.com/room1 have different permissions (different port)
https://github.com and https://gist.github.com have different permissions (different hosts)
Permission States
- Granted - Permission was allowed (manually or via "Always Allow")
- Denied - Permission was blocked (manually or via "Always Deny")
- Prompt - No decision made yet, will show dialog on next request
W3C Compliance
The permission system follows W3C specifications:
- Display capture permissions are never persisted (always prompt via portal)
- Mic/camera permissions can be persisted with user consent
- Permissions are scoped to origins (scheme + host + port)
Managing Stored Permissions
Currently, stored permissions can only be cleared by:
- Site-specific reset:
navigator.permissions.revoke() was removed from the Permissions API and is not supported in modern browsers; direct users to browser/site permission settings (or account-level controls when available) to reset access.
- Full reset: Remove
~/.local/share/dumber/dumber.db (deletes all data including permissions)
A permission management UI is planned for a future release.
Privacy Notes
- Permissions are stored in your local SQLite database (
~/.local/share/dumber/dumber.db)
- No permission data is sent to any server
- "Always Deny" is useful for blocking persistent permission requests from unwanted sites
- The default response is "Deny" (conservative security posture)
Troubleshooting
Permission dialog not appearing
- Check if the site uses HTTPS (required for media permissions)
- Verify the site isn't already in your stored permissions
- Check browser logs:
dumber --log-level=debug
Permission keeps prompting
- Display capture always prompts (W3C requirement)
- Check if database is writable:
ls -la ~/.local/share/dumber/
Site says permission denied but I clicked Allow
- Check if you clicked "Deny" or "Always Deny" previously
- Clear permissions by removing the database (see above)
source
1# Website Permissions
2
3Dumber handles website permission requests for media access (microphone, camera, screen sharing) following W3C standards.
4
5## Permission Types
6
7### Auto-Allowed
8
9These permissions are automatically granted without user interaction:
10
11- **Display Capture** (screen sharing) - The XDG Desktop Portal handles the UI
12
13 > ⚠️ **WebKit fallback known issue**: Screen sharing does **not work** on Wayland with WebKitGTK 2.50.x due to a GStreamer caps negotiation failure ([WebKit bug #306440](https://bugs.webkit.org/show_bug.cgi?id=306440)). This was fixed on January 29, 2026 and backported to the 2.52 stable branch. **Workaround for the WebKit backend**: Upgrade to WebKitGTK 2.52+ when available from your distribution. Camera and microphone permissions work correctly.
14
15- **Device Enumeration** (listing microphones/cameras) - Low security risk
16
17### User-Confirmed
18
19These permissions require explicit user approval:
20
21- **Microphone** - Websites can request audio capture access
22- **Camera** - Websites can request video capture access
23
24When both microphone and camera are requested together, a combined dialog is shown.
25
26## WebAuthn / passkeys / security keys
27
28Dumber currently **disables** WebAuthn (`PublicKeyCredential`, passkeys, FIDO2/security keys) in embedded CEF panes. The current CEF integration uses windowless/OSR Alloy browsers and does not expose the Chromium WebAuthn request UI/delegate needed for PIN, account selection, or transport UI.
29
30If a site requires passkeys or hardware security keys, use the system browser for that auth flow until a dedicated Chrome-runtime auth-window prototype exists.
31
32> ⚠️ **Developer override (unsupported)**: Set `DUMBER_CEF_ENABLE_WEBAUTHN_UNSAFE=1` to temporarily re-enable WebAuthn. This is unsupported and may crash.
33
34## Permission Dialog
35
36When a site requests mic/camera access, a dialog appears with four options:
37
38| Button | Action | Persistence |
39|--------|--------|-------------|
40| **Allow** | Grant permission once | Not saved |
41| **Always Allow** | Grant and remember | Saved per origin |
42| **Deny** | Block permission once | Not saved |
43| **Always Deny** | Block and remember | Saved per origin |
44
45## How Permissions Work
46
47### Origin-Based Storage
48
49Permissions are stored per-origin (scheme + host + port), not per-page.
50Default ports are normalized away (`:80` for `http`, `:443` for `https`). This means:
51
52- `https://meet.google.com/room1` and `https://meet.google.com/room2` share the same permission (same origin)
53- `https://meet.google.com:443/room1` and `https://meet.google.com/room1` share the same permission (default `https` port)
54- `https://meet.google.com:8443/room1` and `https://meet.google.com/room1` have different permissions (different port)
55- `https://github.com` and `https://gist.github.com` have different permissions (different hosts)
56
57### Permission States
58
59- **Granted** - Permission was allowed (manually or via "Always Allow")
60- **Denied** - Permission was blocked (manually or via "Always Deny")
61- **Prompt** - No decision made yet, will show dialog on next request
62
63### W3C Compliance
64
65The permission system follows W3C specifications:
66
67- Display capture permissions are **never persisted** (always prompt via portal)
68- Mic/camera permissions **can be persisted** with user consent
69- Permissions are scoped to origins (scheme + host + port)
70
71## Managing Stored Permissions
72
73Currently, stored permissions can only be cleared by:
74
751. **Site-specific reset**: `navigator.permissions.revoke()` was removed from the Permissions API and is not supported in modern browsers; direct users to browser/site permission settings (or account-level controls when available) to reset access.
762. **Full reset**: Remove `~/.local/share/dumber/dumber.db` (deletes all data including permissions)
77
78A permission management UI is planned for a future release.
79
80## Privacy Notes
81
82- Permissions are stored in your local SQLite database (`~/.local/share/dumber/dumber.db`)
83- No permission data is sent to any server
84- "Always Deny" is useful for blocking persistent permission requests from unwanted sites
85- The default response is "Deny" (conservative security posture)
86
87## Troubleshooting
88
89### Permission dialog not appearing
90
911. Check if the site uses HTTPS (required for media permissions)
922. Verify the site isn't already in your stored permissions
933. Check browser logs: `dumber --log-level=debug`
94
95### Permission keeps prompting
96
97- Display capture always prompts (W3C requirement)
98- Check if database is writable: `ls -la ~/.local/share/dumber/`
99
100### Site says permission denied but I clicked Allow
101
102- Check if you clicked "Deny" or "Always Deny" previously
103- Clear permissions by removing the database (see above)