Skip to content

proposal: net/http2: add SensitiveHeaders to HTTP/2 Transport #78306

@AmritM18

Description

@AmritM18

Proposal Details

Go's HTTP/2 implementation indexes all headers in the HPACK dynamic table by default. This has two primary impacts:

  • Go lacks a mechanism to follow the RFC 7541 recommendation to use a "Never Indexed" representation for sensitive secrets like Authorization or X-API-Key.
  • Large, unique headers cause table thrashing by frequently evicting useful static headers. This causes fleet-wide CPU overhead and degrades compression efficiency by forcing common headers to be re-transmitted as literals.

I propose adding a SensitiveHeaders []string field to the Transport. This field allows users to specify case-insensitive header names that the HPACK encoder should flag as "Never Indexed." Setting this at the Transport level ensures a consistent policy across all pooled connections. This applies to the client side of the connection.

type Transport struct {
    // ... existing fields ...
    
    // SensitiveHeaders specifies header names that should never be
    // indexed in HTTP/2 HPACK dynamic tables. Header names are
    // matched case-insensitively. This prevents sensitive data
    // from being stored in HPACK tables and reduces table thrashing
    // from large, unique headers.
    SensitiveHeaders []string
}

Alternatives considered:

  • We considered a mechanism to set these headers dynamically using a "magic" header or a "Trailer-like" internal signaling trick (e.g., Headers.Set("__sensitive", "header-name")). We decided on a global approach because it is less cumbersome for headers that are consistently sensitive across a service.
  • Libraries like nghttp2 avoid indexing headers larger than 75% of the table size to prevent thrashing. This could be a separate proposal in the future.

Metadata

Metadata

Assignees

No one assigned

    Labels

    LibraryProposalIssues describing a requested change to the Go standard library or x/ libraries, but not to a toolProposal

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions