Privacy & Security

Wat de Permissions-Policy-header daadwerkelijk kan beperken

Een praktische gids voor de browserfuncties die je kunt beperken, wat je niet kunt controleren en hoe je de header uitrolt zonder nuttige functionaliteit te breken.

The Wux Webtools Team The Wux Webtools Team 8 min lezen AI-ondersteund, door mensen beoordeeld
A browser interface with feature toggles limiting access for a page and embedded frames.
Inhoudsopgave
  1. De korte versie
  2. Wat Permissions-Policy controleert
  3. Wat het op je eigen pagina’s kan beperken
  4. Wat het in iframes kan beperken
  5. Wat het niet kan beperken
  6. Een verstandig standaardbeleid
  7. Uitrollen zonder dingen te breken
  8. 1. Inventariseer functiegebruik
  9. 2. Begin in een omgeving met laag risico
  10. 3. Gebruik paginaspecifiek beleid waar nodig
  11. 4. Verifieer de echte respons
  12. 5. Documenteer uitzonderingen
  13. Veelvoorkomende syntaxisfouten
  14. De praktische privacywaarde

De korte versie

Permissions-Policy is een HTTP-responsheader waarmee een site de toegang tot bepaalde browserfuncties kan beperken: camera, microfoon, geolocatie, fullscreen, betaling, sensoren en een lange lijst kleinere API’s.

Het is geen algemeen privacyschild. Het stopt niet alle tracking, blokkeert geen cookies, voorkomt geen netwerkverzoeken en maakt third-party JavaScript niet veilig. Wat het wel goed kan, is beperkter en toch waardevol: de browsermogelijkheden verminderen die beschikbaar zijn voor je eigen pagina’s en voor ingesloten frames.

Dat is belangrijk omdat moderne websites zijn opgebouwd uit analytics-snippets, media-embeds, chatwidgets, consentmanagers, advertentiescripts, kaarten, betalingsflows en interne experimenten. De meeste van die componenten hebben geen toegang nodig tot krachtige apparaat-API’s. Een goed beleid maakt dat expliciet.

Als je headers in productie al beoordeelt, combineer dit werk dan met een directe controle van de daadwerkelijke respons. Onze gids over redirects en HTTP-headers debuggen in productie behandelt de gewoonte die hier telt: inspecteer wat de browser echt ontvangt, niet wat je configuratiebestand zegt dat er zou moeten gebeuren.

Wat Permissions-Policy controleert

De header controleert toegang tot benoemde browserfuncties. De exacte lijst verandert in de loop van de tijd omdat browser-API’s veranderen, maar veelvoorkomende directives zijn onder andere:

  • camera
  • microphone
  • geolocation
  • fullscreen
  • payment
  • usb
  • bluetooth
  • accelerometer
  • gyroscope
  • magnetometer
  • screen-wake-lock
  • clipboard-read
  • clipboard-write
  • publickey-credentials-get
  • interest-cohort in oudere discussies, nu vooral historisch

Een directive kan een functie toestaan voor niemand, voor de huidige origin of voor geselecteerde origins. Bijvoorbeeld:

Permissions-Policy: camera=(), microphone=(), geolocation=(self)

Dit betekent dat camera en microfoon zijn uitgeschakeld voor het document en de geneste browsing contexts, terwijl geolocatie alleen is toegestaan voor dezelfde origin.

Een permissiever voorbeeld:

Permissions-Policy: geolocation=(self "https://maps.example"), fullscreen=(self "https://video.example")

Dit staat je eigen origin en één genoemde kaartprovider toe geolocatie te gebruiken, en je eigen origin plus een videoprovider om fullscreen aan te vragen.

Het beleid wordt door de browser geëvalueerd. Als een functie niet is toegestaan, hoort JavaScript dat die API gebruikt te falen of zich te gedragen alsof de functie niet beschikbaar is. De exacte foutmodus hangt af van de API. Soms wordt een promise rejected. Soms lijkt een mogelijkheid simpelweg niet bruikbaar.

Wat het op je eigen pagina’s kan beperken

Op first-party pagina’s is Permissions-Policy vooral nuttig als vangrail. Het vermindert de impact van toevallige of onverwachte code.

Een marketingpagina heeft bijvoorbeeld waarschijnlijk geen microfoon, camera, Bluetooth, USB, bewegingssensoren of payment-API’s nodig. Je kunt die functies globaal weigeren:

Permissions-Policy: camera=(), microphone=(), bluetooth=(), usb=(), payment=(), accelerometer=(), gyroscope=(), magnetometer=()

Dat maakt niet elk script op de pagina betrouwbaar. Het betekent wel dat als een tagmanagerexperiment, gecompromitteerde dependency of geplakte widget een beperkte API probeert aan te roepen, de browser er geen toegang toe zou moeten geven.

Voor teams met veel bijdragers is dit een nuttige standaard. Het verschuift het gesprek van vaag vertrouwen naar expliciete mogelijkheden. Als een toekomstige functie de camera echt nodig heeft, moet iemand het beleid aanpassen en uitleggen waarom.

Dat is de juiste soort frictie.

Wat het in iframes kan beperken

De header wordt vooral nuttig rond ingesloten content.

Browsers behandelen iframes al als afzonderlijke browsing contexts, maar ingesloten third-party content kan nog steeds krachtige functies aanvragen als dat door beleid en iframe-attributen wordt toegestaan. Met Permissions-Policy kan de bovenliggende pagina een bovengrens instellen.

Als je pagina bijvoorbeeld een videospeler, een supportwidget en een kaart insluit, kun je voorkomen dat elk frame toegang krijgt tot elke functie. Je kunt fullscreen alleen toestaan voor het videoframe en geolocatie alleen voor het kaartframe.

Er zijn twee lagen om te begrijpen:

  1. De HTTP-header Permissions-Policy stelt beleid in voor het document.
  2. Het iframe-attribuut allow kan specifieke functies delegeren aan een frame, maar alleen binnen wat het bovenliggende beleid toestaat.

Een eenvoudige iframe kan er zo uitzien:

<iframe src="https://video.example/embed/123" allow="fullscreen"></iframe>

Als je header fullscreen volledig weigert, kan het iframe-attribuut die weigering niet overschrijven. Als je header fullscreen toestaat voor die origin, kan het iframe-attribuut dit delegeren.

Deze hiërarchie is één reden waarom de header de moeite waard is. Het geeft platform- of securityteams een manier om sitebrede grenzen te stellen, terwijl productteams nog steeds specifieke embeds kunnen inschakelen waar dat nodig is.

Wat het niet kan beperken

Hier overschatten teams de header soms.

Permissions-Policy vervangt geen content security policy. Het bepaalt niet welke scripts mogen laden. Het stopt een script niet met het versturen van data via het netwerk. Het sanitizet geen HTML. Het voorkomt geen XSS. Het blokkeert geen formulier-spam. Als misbruik van formulieren het probleem is, begin dan met de mechanismen die worden beschreven in waarom je contactformulier je grootste spamrisico is, niet met deze header.

Het vervangt ook geen cookiebeheer. Cookies, local storage, consent, third-party embeds en browserbescherming tegen tracking zijn afzonderlijke onderwerpen. Als je privacycontroles breed beoordeelt, verdient het cookielandschap een eigen ronde; de praktische wijzigingen worden behandeld in wat er in 2026 voor cookies veranderde en wat je eraan moet doen.

Het belangrijkste is dat Permissions-Policy third-party JavaScript niet privé maakt. Als je een third-party script in je first-party pagina laadt, draait het doorgaans met de rechten van je pagina, onder voorbehoud van andere browserbeperkingen en je securityheaders. Cameratoegang weigeren is goed. Het stopt dat script niet met het lezen van DOM-content, het observeren van gebruikersacties of het doen van toegestane netwerkverzoeken.

Daarvoor heb je andere controles nodig: zorgvuldige leveranciersselectie, CSP, sandboxed iframes, Subresource Integrity waar van toepassing, dataminimalisatie en saaie maar noodzakelijke reviews.

Een verstandig standaardbeleid

Er is geen universele header die voor elke site past, maar de meeste content- en marketingsites kunnen restrictief beginnen.

Een redelijke eerste stap:

Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=(), bluetooth=(), accelerometer=(), gyroscope=(), magnetometer=(), screen-wake-lock=()

Voeg daarna alleen terug wat de site daadwerkelijk gebruikt.

Bijvoorbeeld:

  • Een winkel die de Payment Request API gebruikt, heeft mogelijk payment=(self) nodig.
  • Een locatiezoeker heeft mogelijk geolocation=(self) of een vertrouwde kaart-origin nodig.
  • Een conferencing-app heeft mogelijk camera=(self) en microphone=(self) nodig.
  • Een site met veel video heeft mogelijk fullscreen=(self "https://trusted-video.example") nodig.

Het belangrijkste is niet om een enorm beleid uit een checklist te kopiëren en het daarbij te laten. Begin met je functie-inventaris. Welke pagina’s hebben welke browsermogelijkheden nodig? Welke embeds hebben delegatie nodig? Welke functies zouden verrassend zijn als ze werden aangevraagd?

Uitrollen zonder dingen te breken

Rol dit uit zoals elke andere productieheader: weloverwogen.

1. Inventariseer functiegebruik

Doorzoek je codebase op browser-API-aanroepen zoals getUserMedia, geolocation, requestFullscreen, PaymentRequest, Web Bluetooth, WebUSB en wake lock-API’s.

Controleer daarna third-party embeds. Documentatie voor video-, kaart-, betaal- en identityproviders vermeldt vaak vereiste iframe-waarden voor allow.

2. Begin in een omgeving met laag risico

Voeg een restrictieve header toe in staging en test de kernflows. Let op meldingen in de browserconsole. Browsers rapporteren vaak wanneer een functie door permissions policy wordt geblokkeerd.

3. Gebruik paginaspecifiek beleid waar nodig

Forceer geen één globaal beleid als je product heel verschillende paginatypen heeft. Een blog, checkout, kaartpagina en videoruimte hebben waarschijnlijk verschillende mogelijkheden nodig.

De meeste webservers, frameworks en edgeplatforms kunnen headers conditioneel per pad instellen. Dat is vaak schoner dan de hele site verzwakken voor één functie.

4. Verifieer de echte respons

Headers kunnen worden toegevoegd, overschreven, gedupliceerd of verwijderd door CDNs, reverse proxies, appservers en middleware. Controleer de uiteindelijke respons in browser DevTools of met command-line tools.

Test ook ingesloten contexts. Een top-level pagina die correct lijkt, garandeert niet dat een iframe de delegatie heeft ontvangen die je bedoelde.

5. Documenteer uitzonderingen

Elke toegestane functie moet een eigenaar en een reden hebben. Dit klinkt bureaucratisch tot zes maanden later niemand meer weet waarom geolocation is opengesteld voor een vendordomein dat niet langer op de pagina lijkt voor te komen.

Veelvoorkomende syntaxisfouten

De moderne headersyntaxis is compact, maar het is makkelijk om er net naast te zitten.

Gebruik lege haakjes om een functie te weigeren:

Permissions-Policy: microphone=()

Gebruik self voor de huidige origin:

Permissions-Policy: geolocation=(self)

Gebruik origins tussen aanhalingstekens voor specifieke externe origins:

Permissions-Policy: fullscreen=(self "https://video.example")

Vermijd vertrouwen op oude Feature-Policy-voorbeelden, tenzij je bewust legacygedrag ondersteunt. De oudere header gebruikte een andere syntaxis en is niet iets waar je vandaag je ontwerp op zou moeten baseren.

Onthoud ook dat browserondersteuning per directive verschilt. Een browser kan de header ondersteunen, maar niet een specifieke feature directive. Dat is normaal. Beschouw de header als een defense-in-depth-maatregel, niet als je enige privacy- of securitycontrole.

<!-- tool-cta:start -->

💡 Probeer dit: Controleer of je Permissions-Policy wordt geleverd zoals bedoeld met Get Headers, dat de ruwe responsheaders toont die je server verzendt.

<!-- tool-cta:end -->

De praktische privacywaarde

De privacywaarde van Permissions-Policy is niet dat het een site anoniem of vrij van trackers maakt. Dat doet het niet.

De waarde zit erin dat het toegang tot gevoelige browsermogelijkheden vernauwt. Locatie, camera, microfoon, apparaatsensoren, lokale hardware-API’s en betalingsflows zijn krachtig. De meeste pagina’s hebben ze niet nodig. Veel ingesloten componenten zouden er nooit om moeten kunnen vragen.

Dat is een echte verbetering. Het vermindert onbedoelde prompts, beperkt onnodige blootstelling van mogelijkheden en geeft je team een concreet artefact om te beoordelen wanneer nieuwe functionaliteit live gaat.

De beste versie van deze header is saai: standaard restrictief, alleen versoepeld waar een gebruikersgerichte functie dat vereist, en getest als onderdeel van het normale releaseproces.

Veelgestelde vragen

Is Permissions-Policy hetzelfde als Feature-Policy?
Nee. Permissions-Policy is de moderne vervanging voor de oudere Feature-Policy-header. Sommige oudere artikelen en snippets gebruiken nog Feature-Policy-syntaxis, maar nieuwe implementaties zouden Permissions-Policy moeten gebruiken.
Kan Permissions-Policy third-party tracking stoppen?
Niet op zichzelf. Het kan toegang tot bepaalde browserfuncties blokkeren, maar het stopt scripts niet met laden, cookies plaatsen waar dat is toegestaan, paginacontent lezen of netwerkverzoeken versturen. Gebruik het naast CSP, consentcontroles, dataminimalisatie en zorgvuldig leveranciersbeheer.
Moet elke site camera en microfoon weigeren?
Voor de meeste sites wel, ja. Als je site geen video-opnames, conferencing, identiteitsverificatie of een andere functie biedt die duidelijk mediacapture nodig heeft, is het weigeren van camera en microfoon een verstandige standaard.
Kan een iframe allow-attribuut de header overschrijven?
Nee. Het beleid van het bovenliggende document bepaalt de bovengrens. Het iframe-attribuut allow kan een functie alleen delegeren als het bovenliggende beleid die functie toestaat voor de frame-origin.
Breken niet-ondersteunde directives oude browsers?
Over het algemeen worden niet-ondersteunde directives genegeerd. Je moet belangrijke gebruikersflows nog steeds testen in de browsers die je ondersteunt, omdat individueel API-gedrag en consolemeldingen kunnen verschillen.

Bronnen & verder lezen

  1. MDN Web Docs: Permissions-Policy header
  2. W3C: Permissions Policy specification
  3. web.dev: Permissions Policy
  4. Chrome Developers: Controlling browser features with Permissions Policy
Over de auteur
The Wux Webtools Team

Laatst bijgewerkt:

Blijf lezen