# Enable TLS 1.3 0-RTT (Early Data)
ssl_early_data on;

# 0-RTT replay risk: data encrypted with a previous PSK, no server random,
# so an attacker can replay captured 0-RTT requests. Only idempotent methods
# (GET, HEAD, OPTIONS) are safe for 0-RTT.
# See RFC 8470, https://blog.cloudflare.com/introducing-0-rtt/#whats-the-catch

# Nginx variable-based logic to reject non-idempotent 0-RTT requests with 425 Too Early.
set $reject_early "";

# Flag part 'E' if request used 0-RTT
if ($ssl_early_data = "1") {
    set $reject_early "E";
}

# Flag part 'M' if method is non-idempotent
if ($request_method !~ ^(GET|HEAD|OPTIONS)$) {
    set $reject_early "${reject_early}M";
}

# Reject when both conditions are true ('EM')
if ($reject_early = "EM") {
    return 425;
}