2023 System Services
WWDC23 · 12 min · System Services
Ready, set, relay: Protect app traffic with network relays
Learn how relays can make your app’s network traffic more private and secure without the overhead of a VPN. We’ll show you how to integrate relay servers in your own app and explore how enterprise networks can use relays to securely access internal resources.
Watch at developer.apple.com ↗Chapters
Code shown on screen · 6 snippets
Configuring a relay
import Network
let relayEndpoint = NWEndpoint.url(URL(string: "https://relay.example.com")!)
let relayServer = ProxyConfiguration.RelayHop(http3RelayEndpoint: relayEndpoint)
let relayConfig = ProxyConfiguration(relayHops: [relayServer]) Configuring a relay in Network framework
import Network
let relayEndpoint = NWEndpoint.url(URL(string: "https://relay.example.com")!)
let relayServer = ProxyConfiguration.RelayHop(http3RelayEndpoint: relayEndpoint)
let relayConfig = ProxyConfiguration(relayHops: [relayServer])
var context = NWParameters.PrivacyContext(description: "my relay")
context.proxyConfigurations = [relayConfig]
let parameters = NWParameters.tls
parameters.setPrivacyContext(context)
let connection = NWConnection(host: "www.example.com", port: 443, using: parameters)
connection.start(queue: .main) Configuring a relay in URLSession
import Network
let relayEndpoint = NWEndpoint.url(URL(string: "https://relay.example.com")!)
let relayServer = ProxyConfiguration.RelayHop(http3RelayEndpoint: relayEndpoint)
let relayConfig = ProxyConfiguration(relayHops: [relayServer])
let config = URLSessionConfiguration.default
config.proxyConfigurations = [relayConfig]
let mySession = URLSession(configuration: config)
let url = URL(string: "https://www.example.com/api/v1/employees")!
let (data, response) = try await mySession.data(from: url) Configuring a relay in WebKit
import Network
let relayEndpoint = NWEndpoint.url(URL(string: "https://relay.example.com")!)
let relayServer = ProxyConfiguration.RelayHop(http3RelayEndpoint: relayEndpoint)
let relayConfig = ProxyConfiguration(relayHops: [relayServer])
let webkitConfig = WKWebViewConfiguration()
webkitConfig.websiteDataStore = WKWebsiteDataStore.nonPersistent()
webkitConfig.websiteDataStore.proxyConfigurations = [relayConfig]
let webView = WKWebView(frame: .zero, configuration: webkitConfig)
let url = URL(string: "https://www.example.com/api/v1/employees")!
webView.load(URLRequest(url: url)) Configuring a relay on the device with a configuration profile
<dict>
<key>PayloadType</key>
<string>com.apple.relay.managed</string>
<key>Relays</key>
<array>
<dict>
<key>HTTP3RelayURL</key>
<string>https://relay.example.com</string>
<key>PayloadCertificateUUID</key>
<string>5AB702EC-32F3-48A9-94FE-8EA1C67ACF46</string>
</dict>
</array>
<key>MatchDomains</key>
<array>
<string>internal.example.com</string>
</array>
</dict> Configuring a relay on the device with NetworkExtension
import NetworkExtension
let newRelay = NERelay()
let relayURL = URL(string: "https://relay.example.com:443/")
newRelay.http3RelayURL = relayURL
newRelay.http2RelayURL = relayURL
newRelay.additionalHTTPHeaderFields = ["Authorization" : "PrivateToken=123"]
let manager = NERelayManager.shared()
manager.relays = [newRelay]
manager.matchDomains = ["internal.example.com"]
manager.isEnabled = true
do {
try await manager.saveToPreferences()
} catch let saveError {
// Handle error
} Resources
Related sessions
-
29 min -
33 min -
15 min