Uma landing page criada por IA pode pedir localização para sugerir uma unidade, câmera para ler um código ou microfone para gravar uma mensagem. Também pode carregar um widget que tenta usar esses recursos sem que a equipe tenha percebido. O navegador ainda exibe uma decisão para a pessoa, mas um pedido inesperado, precoce ou sem explicação destrói confiança e pode deixar a jornada em um estado quebrado quando o acesso é negado.

Revisar permissões do navegador é relacionar cada capacidade sensível a uma finalidade, a um gesto da pessoa e a um comportamento seguro de recusa. A revisão também precisa cobrir iframes e a política entregue pela resposta HTTP. O objetivo não é fazer toda página pedir permissões: é provar que cada pedido é necessário, previsível e limitado ao menor escopo possível.

Este guia organiza o inventário no código, o desenho da experiência e a verificação na build e nas URLs publicadas.

Diferencie três camadas de controle

Permissões do navegador não são um único botão. Há pelo menos três camadas:

  1. o código chama uma API, como geolocalização ou captura de mídia;
  2. o navegador e a pessoa decidem se aquela origem pode usar a capacidade;
  3. Permissions-Policy e o atributo allow de um iframe limitam quais documentos podem tentar usá-la.

A especificação Permissions descreve a decisão concedida e controlada pela interface do navegador. Já a Permissions Policy permite habilitar ou desabilitar recursos em documentos e conteúdo incorporado.

Uma camada não substitui a outra. Incluir allow="geolocation" em um iframe não concede localização automaticamente. A política só permite que aquele documento chegue à etapa em que o navegador pode consultar ou pedir a decisão da pessoa. Da mesma forma, remover uma diretiva de Permissions-Policy não torna a experiência adequada por si só.

Comece por um inventário orientado a capacidades

Procure as APIs, bibliotecas e embeds antes de editar:

Terminal window
rg -n \
'getUserMedia|mediaDevices|geolocation|requestPermission|Notification|clipboard|permissions\.query|requestFullscreen|allow=' \
src public
rg -n '<iframe|camera|microphone|geolocation|payment|fullscreen|web-share' src public

Amplie os caminhos conforme o projeto e inspecione wrappers. Um SDK pode solicitar câmera ou notificações sem chamar a API diretamente no componente da página.

Registre cada ocorrência:

capacidade:
arquivo e fluxo:
finalidade para a pessoa:
origem que executa:
gesto que inicia o pedido:
momento do pedido:
comportamento quando permitido:
comportamento quando negado ou indisponível:
iframe ou terceiro envolvido:
política esperada:
evidência na URL publicada:

Inclua recursos que parecem periféricos: player em tela cheia, clipboard, compartilhamento, notificações e widgets de vídeo podem mudar a superfície de permissões. O guia de scripts de terceiros ajuda a encontrar capacidades escondidas em SDKs e embeds.

Remova pedidos sem uma finalidade concreta

Uma página institucional comum não precisa de câmera, microfone ou geolocalização. Se uma capacidade entrou por template, experimento abandonado ou biblioteca não usada, remova a chamada e a dependência correspondente.

Para o que permanece, responda:

  • a funcionalidade principal depende disso ou existe alternativa manual?
  • a pessoa entende o benefício antes de decidir?
  • o pedido acontece depois de uma ação relacionada?
  • o acesso precisa durar além daquele uso?
  • um valor menos preciso resolveria?
  • o mesmo resultado pode ser obtido sem um terceiro?

Evite pedir acesso no carregamento da página. Um botão como “usar minha localização” cria contexto melhor que um prompt disparado antes de a pessoa entender a oferta. Para uma busca de endereço, permita digitação manual. Para um QR code, ofereça upload ou código textual quando isso fizer sentido.

Minimização também reduz estados que precisam de suporte. Se o produto não precisa da capacidade, não existe motivo para manter telas de recusa, instruções por navegador e testes de recuperação.

Desenhe o caminho de recusa como parte do produto

Negar é um resultado normal, não uma exceção impossível. A pessoa pode recusar, o navegador pode bloquear a API, o dispositivo pode não possuir o sensor ou uma política superior pode impedir o uso.

Para cada capacidade, defina:

Estado Resposta da interface
ainda não solicitado explicar valor e oferecer ação explícita
permitido usar somente para a finalidade anunciada
negado manter a página utilizável e mostrar alternativa
bloqueado pela política não insistir; registrar diagnóstico técnico
API indisponível oferecer fluxo compatível sem o recurso
permissão revogada interromper uso e permitir nova escolha consciente

Não crie um loop que chama a API novamente depois de cada recusa. Muitos navegadores reduzem ou bloqueiam prompts repetitivos, e insistência não transforma ausência de consentimento em autorização.

Mensagens também precisam ser precisas. “Seu navegador bloqueou a câmera” só é verdade depois de diagnosticar o estado. Antes disso, prefira “Não foi possível acessar a câmera; envie o arquivo ou revise a permissão do site”.

Consulte estado sem depender dele como verdade universal

A Permissions API pode ajudar a observar algumas decisões:

const status = await navigator.permissions.query({ name: "geolocation" });
status.addEventListener("change", () => {
console.info("Geolocation permission changed", status.state);
});

Os nomes aceitos e o comportamento variam entre APIs e navegadores. Não presuma que toda capacidade aparece em navigator.permissions nem que um resultado elimina a necessidade de tratar erros da chamada real. Verifique a matriz de navegadores suportados e teste o fluxo no ambiente de destino.

Evite usar o estado para rastrear pessoas ou enviar telemetria desnecessária. Registre o mínimo necessário para diagnosticar a funcionalidade, sem transformar uma decisão local em perfil comportamental.

Restrinja recursos com Permissions Policy

Quando a camada de resposta permite configurar cabeçalhos, negue capacidades não usadas e autorize somente as necessárias. Um exemplo conservador para uma página que não usa sensores é:

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

A lista vazia desativa a capacidade nos contextos cobertos. Para permitir geolocalização na própria origem e em um parceiro específico, a sintaxe usa uma allowlist:

Permissions-Policy: geolocation=(self "https://mapa.example")

A documentação da diretiva de geolocalização na MDN ressalta que o header pode limitar outras origens mesmo quando o iframe possui allow.

Não copie uma política enorme sem validar suporte. Algumas diretivas são experimentais ou têm compatibilidade desigual. Comece pelas capacidades realmente presentes, teste navegadores prioritários e trate warnings do console como evidência para investigar, não como prova isolada de proteção.

Reduza o poder de cada iframe

Um iframe cross-origin deve receber somente as capacidades necessárias ao widget. Exemplo:

<iframe
src="https://video.example/chamada"
allow="camera; microphone"
sandbox="allow-scripts allow-forms"
title="Chamada de vídeo"
></iframe>

O exemplo é apenas uma base de revisão. A política superior precisa autorizar a origem, e o sandbox precisa ser compatível com a função real. Não adicione allow-same-origin, popups, downloads ou navegação de topo por tentativa e erro. Cada token amplia o que o conteúdo incorporado pode fazer.

Confirme ainda:

  • se o iframe é necessário;
  • quem controla a origem e os redirects;
  • quais capacidades o fornecedor documenta;
  • se a URL pode navegar para outra origem;
  • como o widget se comporta sem cada permissão;
  • se uma atualização do terceiro muda o contrato.

Verifique o header realmente servido

O contrato de Publicação envia o HTML, o JavaScript e os assets preparados pelo projeto. No contrato atual, o pacote não transforma um arquivo _headers em cabeçalhos HTTP. Portanto, escrever uma Permissions-Policy na fonte não prova que ela foi aplicada.

Inspecione a resposta autorizada:

Terminal window
curl -sS -D - -o /dev/null https://exemplo.sitenoar.app \
| rg -i '^(permissions-policy|content-security-policy):'

Repita no DevTools e em cada domínio próprio mantido. A URL padrão e os hostnames próprios servem o mesmo Site, mas a decisão de permissão é associada à origem vista pelo navegador. Uma autorização concedida a um host não deve ser tratada como autorização automática para outro.

Se o header necessário ainda não pode ser configurado na camada de resposta, registre a política como requisito pendente. Não marque a proteção como ativa e não tente reproduzir o header com uma meta tag: Permissions-Policy é uma política de resposta.

Teste em perfis limpos e estados reais

Faça a matriz com dados sintéticos:

  1. perfil limpo, sem decisão anterior;
  2. permissão concedida;
  3. permissão negada;
  4. permissão revogada durante a sessão;
  5. dispositivo sem a capacidade;
  6. iframe autorizado e não autorizado;
  7. URL padrão e cada domínio próprio;
  8. navegador prioritário em desktop e mobile;
  9. republicação sem mudança de finalidade;
  10. versão que remove a funcionalidade.

No DevTools, acompanhe Console, Network e as configurações de permissão da origem. Confirme que câmera e microfone são encerrados quando a função termina; tracks de mídia não devem permanecer ativos sem necessidade. Para geolocalização contínua, remova o watcher quando a tela ou jornada encerrar.

Depois de corrigir o código, siga uma republicação controlada e repita a matriz na URL entregue. Teste local demonstra comportamento da build; não demonstra o header nem o estado da origem pública.

Prompt copiável para o agente

Revise as permissões do navegador desta landing page sem conceder acesso automaticamente.
Aplicação publicável: [caminho]
Comando de build: [comando]
URLs autorizadas: [lista]
- Inventarie câmera, microfone, geolocalização, notificações, clipboard e outras capacidades.
- Relacione cada pedido a finalidade, gesto da pessoa, origem e fallback.
- Identifique chamadas no carregamento e permissões sem necessidade.
- Inclua SDKs, scripts de terceiros e iframes.
- Revise Permissions-Policy, allow e sandbox sem ampliar allowlists.
- Não trate decisão do navegador como consentimento para outra finalidade.
- Teste permitido, negado, revogado, indisponível e bloqueado por política.
- Verifique headers na resposta publicada e cada origem separadamente.
- Não marque uma política como ativa sem evidência na resposta.
- Devolva inventário, menor diff proposto, testes e riscos restantes.

Checklist final

  • APIs sensíveis e wrappers foram inventariados;
  • cada capacidade tem finalidade e responsável;
  • pedidos acontecem após uma ação contextual;
  • funcionalidades desnecessárias foram removidas;
  • recusa e indisponibilidade possuem alternativa segura;
  • estado de permissão não é usado como autorização de negócio;
  • iframes têm allow e sandbox mínimos;
  • a política esperada foi comparada com o header servido;
  • URL padrão e domínios próprios foram testados separadamente;
  • tracks e watchers terminam quando deixam de ser necessários;
  • navegadores prioritários entraram na matriz;
  • Version publicada corresponde aos arquivos revisados.

Uma boa experiência de permissão é quase invisível: a pessoa entende por que a capacidade é útil, decide no momento certo e continua a jornada mesmo quando recusa. Esse resultado depende menos de um prompt do navegador e mais de código, política e testes que tratam acesso sensível como uma fronteira explícita.