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 ↗