Volver al Blog
Plataforma

Permissions Policy para funciones del navegador incrustadas

Guía práctica para delegar funciones del navegador a iframes y separar la política de permisos, CSP, COOP y COEP.

BotBrowser Team

Documentación

Quieres la documentación estructurada de Plataforma?

Este artículo forma parte de la biblioteca editorial. Para pasos de configuración, material de referencia y actualizaciones continuas, entra en la sección de docs.

Una página delega una función a un iframe y separa política, permiso y resultado

Permissions Policy limita qué documentos pueden usar determinadas funciones del navegador. La respuesta del documento principal establece el máximo permitido y el atributo allow del iframe delega una función al origen hijo. No es una concesión de permiso del usuario ni una prueba de que exista un dispositivo o de que la aplicación haya terminado.

En una cámara, micrófono, geolocalización o pantalla completa incrustada, registra por separado la política entregada, el origen final, el estado de permiso y el resultado visible. Así se evita ampliar el acceso solo porque falló un proveedor. El ejemplo compara https://app.example y https://widget.example.

El ejemplo compara https://app.example y https://widget.example.

Qué controla la política

La especificación de W3C define una función y una lista de orígenes. Por ejemplo, Permissions-Policy: geolocation=(self "https://widget.example") limita la respuesta al origen principal y al widget indicado. El iframe debe coincidir con ese origen: allow="geolocation" no convierte un origen distinto en autorizado. Los redirects, el esquema, el puerto y todos los ancestros importan. Los valores predeterminados varían por función; comprueba la documentación actual de MDN.

Una política permitida solo significa que el documento puede intentar la API. El navegador puede exigir contexto seguro, gesto del usuario, permiso explícito, administrador, dispositivo o una opción específica. navigator.permissions puede mostrar prompt o granted mientras el iframe permanece bloqueado. Una negativa del usuario, un dispositivo ausente y un bloqueo de política son observaciones distintas.

EtapaEvidenciaLo que no demuestra
Origen y contextoURL final, esquema, puerto y contexto seguroQue la API exista
ImplementaciónPrueba estrecha como typeof navigator.geolocation.getCurrentPositionQue la llamada sea permitida
Permissions PolicyHeader, allow, ancestros y origen hijoPermiso del usuario o dispositivo
Decisión de plataformaprompt, rechazo, ajuste administrador, dispositivoResultado de negocio
AplicaciónEstado visible y acuse propio con timeoutRegistro remoto sin evidencia del servidor

camera, microphone, geolocation y fullscreen son entradas diferentes. Declara solo la función que necesita el recorrido. No uses * en un sistema multiinquilino: valida el origen después de redirects y conserva una lista revisable.

Límite con CSP, COOP y COEP

CSP decide qué scripts, conexiones, imágenes y frames pueden cargarse mediante directivas como script-src, connect-src y frame-src. CSP puede impedir que el frame cargue antes de evaluar Permissions Policy; un frame que carga puede quedar bloqueado después por la política. No relajes CSP para compensar una delegación ausente.

COOP modifica la relación entre contextos principales, sobre todo ventanas y opener. COEP controla si recursos cross-origin pueden incrustarse bajo requisitos CORS o CORP. Ninguno delega cámara, micrófono o geolocalización, y Permissions Policy tampoco crea aislamiento cross-origin ni hace que un recurso sea compatible con CORS. Comprueba red y CSP, origen y COOP/COEP cuando proceda, luego header y allow, y solo entonces la solicitud mediada por el usuario.

Ninguna de estas cabeceras sustituye autorización del servidor, validación, consentimiento, accesibilidad o controles del dispositivo. Una solicitud permitida sigue necesitando una decisión de producto sobre cuenta, duración y eliminación de la transmisión.

Una solicitud tiene varias puertas

Comprueba primero el origen final y el contexto seguro.

Después comprueba que el navegador expone la interfaz esperada.

Registra el header, el atributo allow, la cadena de ancestros y el origen del hijo.

Si la política pasa, todavía pueden intervenir gesto, permiso, administrador y dispositivo.

Por último verifica el estado que la aplicación muestra al usuario.

Contrato de integración y alternativa

Antes del cambio, escribe origen principal, origen hijo después de redirects, función, propósito, gesto requerido, dueño del header y del markup, y alternativa visible. Para una cámara, esa alternativa puede ser carga manual; para pantalla completa, navegación normal; para geolocalización, una entrada manual. Rechazo y timeout deben mantener foco, datos y controles utilizables. Detén tracks al terminar y no repitas prompts silenciosamente.

Fixture control/candidate propio

Sirve /fixtures/permissions-policy/control.html y /fixtures/permissions-policy/candidate.html desde el host propio. Ambos deben usar el mismo frame, botón y marcador visible; solo candidate recibe el header de delegación y control lo omite. Un script del hijo muestra policy=blocked o policy=allowed tras pulsar el botón. Mantén permiso sintético y no recojas ubicación real.

import { test, expect } from '@playwright/test';

const cases = [
  { name: 'control', url: 'https://qa.example.test/fixtures/permissions-policy/control.html', expected: 'blocked' },
  { name: 'candidate', url: 'https://qa.example.test/fixtures/permissions-policy/candidate.html', expected: 'allowed' },
];

for (const scenario of cases) {
  test(`Permissions Policy ${scenario.name}`, async ({ page }) => {
    try {
      const response = await page.goto(scenario.url, { waitUntil: 'domcontentloaded', timeout: 8000 });
      expect(response?.ok(), `respuesta HTTP para ${scenario.name}`).toBeTruthy();
    } catch (error) {
      throw new Error(`NETWORK_ERROR antes de la aserción de política: ${error.message}`);
    }
    await page.getByRole('button', { name: 'Request location' }).click();
    await expect(page.getByTestId('policy-result')).toHaveText(new RegExp(`^${scenario.expected}$`), { timeout: 5000 });
  });
}

El timeout de navegación o de estado no es una negativa de política. DNS, certificado, HTTP y ruta ausente deben conservarse como NETWORK_ERROR, nunca convertirse en un falso blocked. Cierra el contexto y elimina datos temporales en teardown; conserva el primer error. La ruta es atribuible porque origen, frame, gesto y marcador son iguales y solo cambia la delegación.

Despliegue y diagnóstico

En staging usa el routing y orígenes reales. Tras redirects, CDN, service worker y proxy, inspecciona el header final y allow final. Clasifica el primer fallo: header incorrecto es configuración; frame cargado con blocked es cadena de política; allowed seguido de rechazo es consentimiento o estado del navegador; API exitosa seguida de error es aplicación; timeout o DNS es disponibilidad.

Prueba deliberadamente quitar la función, un origen inesperado, un redirect no listado y un frame anidado sin delegación. Guarda configuración previa, markup y versión para rollback. No arregles una incidencia eliminando el header o añadiendo *; una excepción temporal debe indicar función, origen, dueño y vencimiento.

Qué puede validar BotBrowser

BotBrowser puede ejecutar estos recorridos autorizados en contextos controlados, aislar estado sintético y comparar el resultado visible en un build declarado. BotBrowser no puede modificar la política entregada ni conceder permisos. La documentación de aislamiento describe contextos separados para sesiones independientes.

BotBrowser no escribe headers, cambia orígenes, concede permisos, crea dispositivos, sobreescribe CSP/COOP/COEP, repara respuestas de terceros ni demuestra una operación remota. La especificación de W3C y los headers entregados por la aplicación son la autoridad. La responsabilidad queda en los dueños de aplicación, infraestructura, proveedor y consentimiento.

No registres cookies, credenciales, coordenadas ni contenido de streams.

Usa una cuenta sintética para cada intento autorizado.

Cuando cambie el proveedor, vuelve a comprobar el origen final.

Una excepción de emergencia debe tener propietario y fecha de caducidad.

El rollback debe restaurar header y markup como pareja.

En soporte, entrega la primera puerta fallida, no una etiqueta genérica.

Para contexto seguro, consulta la guía de contextos seguros.

Para CSP, consulta la guía de CSP.

Para aislamiento, consulta la guía de aislamiento cross-origin.

El consentimiento debe explicar el propósito antes del gesto.

Fuentes

BotBrowser Team

#Permissions Policy#Iframes#Seguridad Web#Funciones Del Navegador

Lleva BotBrowser de la investigación a producción

Usa estas guías para entender el modelo y después avanzar hacia validación multiplataforma, contextos aislados y despliegue de navegador preparado para escalar.