HTTPS Edge Boundaries: TLS, SNI, ALPN, and HSTS

LESSON

HTTP Protocol and Content Delivery

016 25 min advanced

HTTPS Edge Boundaries: TLS, SNI, ALPN, and HSTS

The core idea: HTTPS is an edge contract before it is an application request: the client must prove it reached the right name, negotiate the protocol, and learn whether future visits must use HTTPS, while the platform decides where encrypted traffic is terminated and re-encrypted.

Core Insight

Imagine a deployment where most users can open https://www.shop.test, but older Android clients fail, one enterprise network falls back from HTTP/3 to HTTP/2, and a few users report a certificate warning only on checkout.shop.test. The application code did not change. The cart API is healthy. The failure is at the secure edge, before the request reaches the application.

That edge has several jobs. DNS points the client toward an address. TLS proves that the server is allowed to speak for the requested name. SNI, the Server Name Indication extension, lets the client tell a shared edge which hostname it is trying to reach. ALPN, Application-Layer Protocol Negotiation, lets client and server choose http/1.1, h2, or h3-related behavior during secure setup. HSTS, HTTP Strict Transport Security, teaches browsers to use HTTPS for future requests without trying insecure HTTP first.

The hard part is ownership. "HTTPS is enabled" is not a complete design. Which component presents the certificate? Which names are covered? Which protocols are advertised? Where is TLS terminated? Is traffic re-encrypted to the origin? Which team owns HSTS policy? Which telemetry proves that clients negotiated the protocol you expected?

The trade-off is latency and centralized edge control versus stricter trust-chain operations. Terminating TLS at an edge can reduce latency, enable protocol negotiation, and centralize certificates. It also makes the edge the component that must get identity, encryption, protocol, renewal, and browser policy right. A mistake at that boundary can break clients before your application has any chance to return a useful error.

What Happens Before HTTP

A user enters:

https://www.shop.test/product/42

Before the browser can send GET /product/42, it needs a secure connection to a server it trusts for www.shop.test. A simplified TCP/TLS path looks like this:

DNS resolves www.shop.test to an edge address
-> client opens a TCP connection to the edge
-> client sends TLS ClientHello
   - SNI: www.shop.test
   - ALPN: h2, http/1.1
-> edge chooses certificate for www.shop.test
-> edge and client complete TLS handshake
-> ALPN result chooses h2 or http/1.1
-> browser sends the HTTP request inside TLS

For HTTP/3, the transport is QUIC over UDP and TLS is integrated into QUIC, but the shape of the edge decision is similar: the client still needs a secure connection for the name, and ALPN still identifies the application protocol. The previous lesson's QUIC details change the transport path, not the need to prove the secure origin.

SNI matters because many hostnames can share one edge IP address. Without SNI, the edge may not know which certificate to present during the handshake. With SNI, it can map www.shop.test to the right certificate and policy. If the SNI routing table is wrong, a subset of hostnames can show certificate warnings even though the application servers behind the edge are fine.

The certificate chain matters because the browser needs to verify identity. The certificate must cover the hostname, be within its validity period, chain to a trusted root through valid intermediates, and satisfy modern client rules. A missing intermediate certificate can work for some clients that have cached it and fail for others that do not.

ALPN matters because the client and server need to agree which HTTP version will run on the secure connection. A client may offer h2 and http/1.1; the server chooses one it supports. If the edge stops advertising h2, clients may fall back to HTTP/1.1. If HTTP/3 support is advertised but UDP is blocked on part of the path, clients may try and then fall back. The application may still work, but latency and connection behavior change.

TLS Termination Is a Trust Boundary

TLS termination is the point where encrypted client traffic becomes decrypted HTTP that some component can inspect and route. In many systems, this happens at an edge load balancer, CDN, ingress gateway, or reverse proxy:

browser
  -- TLS for www.shop.test -->
edge
  -- HTTP or TLS to origin -->
application

That first arrow is the public HTTPS contract. The second arrow is an internal delivery contract. It might be plaintext HTTP on a private network, TLS to the origin, or mutual TLS between services. The important point is not that one shape is always correct. The important point is that the edge termination point owns security-sensitive facts.

At termination, the edge can see request paths, headers, cookies, authorization headers, and bodies unless additional application-layer encryption is used. It can also add or normalize forwarding headers, choose upstreams, enforce redirects, attach WAF rules, and select HTTP versions on either side. The next lesson goes deeper on proxy and header trust. Here, keep the boundary clear: after TLS terminates, the platform must decide how trust is preserved to the next hop.

A common production shape is:

client -> CDN/edge: HTTPS, public certificate, ALPN h2/h3
CDN/edge -> origin load balancer: HTTPS, origin certificate or mTLS
origin load balancer -> app: HTTP inside trusted cluster, or mTLS again

Each arrow has a separate owner and failure mode. The public certificate can expire while the origin certificate is fine. ALPN can select HTTP/2 at the client edge while the edge uses HTTP/1.1 upstream. HSTS can force browsers to use HTTPS even if a rollback temporarily breaks HTTPS. Observability has to name which arrow failed.

The useful design question is:

For this hostname, which component proves identity to the client,
which protocol is negotiated, where is traffic decrypted,
and how is trust carried to the origin?

If the answer is not explicit, incident debugging becomes guesswork.

ALPN and Protocol Choice

ALPN happens inside the secure setup. The client says which application protocols it supports. The server chooses one. For HTTPS over TCP, examples include:

client offers: h2, http/1.1
server picks:  h2

That decision determines whether the HTTP/2 stream and flow-control behavior from the previous lesson applies on that connection. If the server picks http/1.1, the client uses HTTP/1.1 semantics over the secure connection. Both are still HTTPS. The difference is the HTTP version running inside the encrypted channel.

For HTTP/3, clients discover and negotiate support differently depending on deployment details, but ALPN still identifies the HTTP/3 protocol in the QUIC/TLS handshake. In practice, a site may support all of these at once:

HTTP/1.1 over TLS/TCP
HTTP/2 over TLS/TCP
HTTP/3 over QUIC/UDP

This makes rollout safer, but it also means "the site is up" can hide protocol-specific problems. A user behind a UDP-blocking network may use HTTP/2. A mobile browser on a clean path may use HTTP/3. An old client may use HTTP/1.1. If only one group is failing, protocol negotiation is one of the first things to inspect.

Protocol choice should be observable. Edge logs should show negotiated protocol, TLS version, cipher family, SNI hostname, certificate selection, and fallback behavior. Application logs alone usually cannot explain why a client negotiated HTTP/1.1 instead of HTTP/2, or why HTTP/3 connection setup failed before a request arrived.

HSTS: A Browser Memory of HTTPS

HSTS is different from TLS, SNI, and ALPN. It is not part of the handshake. It is an HTTP response policy that tells browsers to use HTTPS for future visits to a host.

A response can include:

Strict-Transport-Security: max-age=31536000; includeSubDomains

After a browser receives this over HTTPS, it remembers that the host should be reached through HTTPS for the configured duration. If the user later types http://www.shop.test, the browser upgrades the request to HTTPS before making the network request. This prevents downgrade attempts where an attacker tries to keep the user on insecure HTTP.

That protection is strong because it is sticky. The browser does not ask the server again over HTTP whether HTTPS is still required. It remembers. That means a bad HSTS rollout can also be sticky. If you set includeSubDomains for shop.test, then preview.shop.test, old-admin.shop.test, and every other subdomain may be forced to HTTPS in browsers that have seen the policy. If some of those names do not have working certificates, users can be locked out until certificates are fixed or the policy expires.

HSTS preload lists go further. A domain can be included in browser-distributed lists so browsers know to use HTTPS before the first visit. That is powerful for mature domains with complete HTTPS coverage. It is risky for domains with forgotten subdomains, temporary environments, or unclear certificate ownership.

The operational rule is: roll out HSTS gradually. Start with a short max-age, verify every hostname that needs to work, then increase duration and consider includeSubDomains or preload only when ownership is clean.

Worked Path: The Checkout Certificate Incident

The shop team deploys a new certificate bundle at the edge. Most pages work. Checkout fails for some users with a certificate warning.

Trace the edge path:

requested URL: https://checkout.shop.test/pay
DNS target: global edge
SNI sent by client: checkout.shop.test
edge certificate selected: *.shop.test
ALPN selected: h2
TLS result: fails on some clients

At first, *.shop.test looks correct. It covers checkout.shop.test. The application is healthy. HTTP/2 support is enabled. But older clients fail because the deployed certificate chain is missing an intermediate certificate they do not already have. Newer clients or clients with cached intermediates can build the chain. Older ones cannot.

The fix is not in checkout application code. It is at the edge certificate bundle. The corrected deployment includes the full chain. The team verifies:

certificate covers checkout.shop.test
certificate is not expired
intermediate chain is served
ALPN still negotiates h2 for capable clients
HTTP/1.1 fallback still works
HSTS policy does not force broken subdomains

Now add a second issue: a team wants to enable HSTS with includeSubDomains at shop.test. Before doing that, they inventory subdomains:

www.shop.test          HTTPS ready
checkout.shop.test     HTTPS ready
api.shop.test          HTTPS ready
preview.shop.test      self-signed certificate
legacy.shop.test       no HTTPS

Enabling includeSubDomains now would make preview and legacy fail in browsers that receive the policy. The right move is to fix or retire those hosts first, start with a short max-age, then expand. HSTS is a security improvement only when the certificate and hostname inventory can support it.

Operational Failure Modes

Failure: certificate exists but chain is incomplete. Some clients can build a path because they cached intermediates. Others fail. Always test the full chain from clients that do not have your intermediate cached.

Failure: SNI routing selects the wrong certificate. Shared edges host many names. A bad SNI map can present a valid certificate for the wrong hostname, causing only certain domains to fail.

Failure: ALPN changes silently. A configuration change can stop advertising h2 or h3, pushing clients to another protocol. The site still loads, but latency, connection count, and failure modes change.

Failure: TLS terminates earlier than the app assumes. Application code may believe it is seeing direct client HTTPS, but the edge may be forwarding HTTP internally. Security decisions should use trusted edge metadata and explicit internal transport policy, not assumptions.

Failure: HSTS is rolled out before the domain is ready. Long max-age, includeSubDomains, or preload can make certificate mistakes persistent for users. Treat HSTS as a staged browser policy, not a header to paste everywhere.

Useful signals include certificate expiration and chain checks, SNI hostname, selected certificate, TLS version, ALPN result, HTTP protocol used, HSTS header by hostname, HTTP-to-HTTPS redirect rates, TLS handshake errors by client family, HTTP/3 fallback rates, and edge-to-origin encryption status. These signals belong at the edge because failures often occur before application logs exist.

Connections

The HTTP/3 lesson showed that modern HTTPS delivery can involve QUIC, UDP, and TLS integrated into the transport. This lesson names the edge decisions that make those protocols safe to use for a hostname.

The next lesson goes deeper into reverse proxies and header trust. Once TLS terminates, the proxy may add forwarding headers and route traffic. That is a separate trust problem: after the secure edge proves identity to the client, the internal path must preserve the facts the application relies on.

Close the lesson and trace one hostname you operate or know: DNS target, SNI name, certificate coverage, full chain, ALPN result, TLS termination point, edge-to-origin encryption, and HSTS policy. Then identify which team or component owns each item.

Resources

Key Takeaways

PREVIOUS HTTP/3, QUIC Streams, and Packet Loss Recovery NEXT Reverse Proxies, Load Balancers, and Header Trust