v151 · Web APIs · Migration Guide
Migration Guide
How to update your Isolated Web App's Permissions Policy headers when migrating from direct-sockets-private to the merged local-network and loopback-network directives.
This migration only affects Isolated Web Apps (IWAs). Standard web pages and Service Worker-backed apps do not use these directives.
directive mapping
| Old directive (pre-Chrome 151) | New directive (Chrome 151+) | Address range covered |
|---|---|---|
direct-sockets-private |
local-network |
RFC 1918 private ranges: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 |
direct-sockets-private |
loopback-network |
Loopback: 127.0.0.0/8, ::1 |
direct-sockets |
direct-sockets |
Unchanged — public internet addresses |
local-network |
local-network |
Already present — now also covers the private socket use case |
header migration
# Step 1 — current IWA manifest (pre-Chrome 151)
# permissions_policy section in the web app manifest:
{
"permissions_policy": {
"direct-sockets": ["self"],
"direct-sockets-private": ["self"],
"local-network": ["self"]
}
}
# Step 2 — updated manifest (Chrome 151+)
# Replace direct-sockets-private with loopback-network.
# local-network already covers the private-range use case.
{
"permissions_policy": {
"direct-sockets": ["self"],
"local-network": ["self"],
"loopback-network": ["self"]
}
}
# Step 3 — if you must support both Chrome ≤150 and Chrome 151+
# Include all directives. Unknown directives are silently ignored,
# so this is safe for all versions.
{
"permissions_policy": {
"direct-sockets": ["self"],
"direct-sockets-private": ["self"],
"local-network": ["self"],
"loopback-network": ["self"]
}
}
IWA manifest: HTTP header equivalent
# If your IWA serves a Permissions-Policy HTTP header directly:
# Before Chrome 151
Permissions-Policy: direct-sockets=self, direct-sockets-private=self, local-network=self
# Chrome 151+ (minimal)
Permissions-Policy: direct-sockets=self, local-network=self, loopback-network=self
# Transitional (safe for all Chrome versions)
Permissions-Policy: direct-sockets=self, direct-sockets-private=self, local-network=self, loopback-network=self
socket address routing
// After Chrome 151 — which policy covers which address?
// local-network covers RFC 1918 private ranges:
await navigator.openTCPSocket({ remoteAddress: '192.168.1.100', remotePort: 8080 });
// → requires: local-network in Permissions Policy
await navigator.openTCPSocket({ remoteAddress: '10.0.0.1', remotePort: 22 });
// → requires: local-network
await navigator.openTCPSocket({ remoteAddress: '172.16.0.5', remotePort: 443 });
// → requires: local-network
// loopback-network covers 127.x.x.x and ::1:
await navigator.openTCPSocket({ remoteAddress: '127.0.0.1', remotePort: 3000 });
// → requires: loopback-network
await navigator.openTCPSocket({ remoteAddress: '::1', remotePort: 5432 });
// → requires: loopback-network
// direct-sockets covers public addresses (unchanged):
await navigator.openTCPSocket({ remoteAddress: '203.0.113.1', remotePort: 80 });
// → requires: direct-sockets
see also
implementation reference
Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗