The audience for this document is people intending on implementing their own signed exchange generator, independent of webpackager, and those implementing their own SXG cache for the purposes of privacy-preserving prefetch. Users of webpkgserver need not read this, as the tool should automatically guarantee the following requirements are met.
The Google SXG cache sets these requirements in addition to the ones set by the SXG spec:
- The SXG must have a freshness lifetime of at least 120 seconds, as computed for a shared cache from its outer headers.
- The signed
fallback URLmust approximately equal the URL at which the SXG was served. Where possible, aim to make them byte-equal. The set of allowed differences is not precisely specified, but approximately:- Characters may be substituted by their percent encodings, and vice versa,
with the exception of meaningful delimiters like
/,;,?,&, and=. - Query parameters may be re-ordered.
- Valueless query parameters may be encoded with or without a trailing
=. - Extra
&s in the query string are allowed.
- Characters may be substituted by their percent encodings, and vice versa,
with the exception of meaningful delimiters like
- The signed
cert-urlmust behttps. - The signature header must contain only:
- One parameterised identifier.
- Parameter values of type string, binary, or integer.
- The payload must be non-empty.
- The signed
cache-controlheader cannot have ano-cacheorprivatedirective, even with a value (e.g.no-cache=some-headeris disallowed). - The
content-typemust satisfy themedia-typegrammar. - The
linkheader, if present, must lead to successful substitution per the Loading spec. Specifically, it must meet these requirements, in addition to the ones set by the Link spec:- Each
URI-Referencemust be an absolutehttpsURL. - Parameter names can only be
as,header-integrity,media,rel,imagesrcset,imagesizes, orcrossorigin. - All
relparameters must be eitherpreloadorallowed-alt-sxg. - All
imagesrcsetvalues must parse as a srcset attribute. - There may be no more than 20
rel=preloads. - All
crossoriginvalues must either be the empty string, oranonymous. - Every
rel=preloadmust have a correspondingrel=allowed-alt-sxgwith the same URI, which in turn must contain aheader-integrityparameter with a value that satisfies the CSPhash-sourcegrammar using thesha256variant. - The preloaded URLs, when requested with an SXG-preferring
Acceptheader, must respond with valid SXGs that match their givenheader-integrity.
- Each
- The
linkheader must not be present on subresources, i.e. SXGs that are themselves preloaded from other SXGs. - There must not be a signed
variant-key-04orvariants-04header. - The signature's lifetime (
expiresminutes request time) must be >= 120 seconds. - The SXG must be no larger than 8 megabytes.
- The page should be responsive, i.e. correct on all media, or contain a supported-media annotation to indicate which media it supports.
Some of the above limitations are overly strict for an SXG cache's needs, and were implemented as such for the sake of expediency. They may be loosened over time, especially in response to publisher feedback.
Other SXG caches could define their own set of requirements. It would be most useful for publishers and users, however, if the requirements were the same across all caches. If you see a need for a different requirement on your cache, please file an issue.
The Google AMP Cache has a different set of requirements for SXGs. See advice for sites with a mix of AMP and non-AMP.
For SXGs on the internet, one can use the SXG Validator Chrome extension. This queries the Google SXG Cache to see if the SXG meets the above requirements.
Alternatively, one can query the cache directly. This is an example that meets the requirements:
$ curl -siH 'Accept: application/signed-exchange;v=b3' https://signed--exchange--testing-dev.webpkgcache.com/doc/-/s/signed-exchange-testing.dev/sxgs/valid.html | grep -aiE 'content-type:|warning:'
content-type: application/signed-exchange;v=b3
and this does not meet requirements:
$ curl -siH 'Accept: application/signed-exchange;v=b3' https://signed--exchange--testing-dev.webpkgcache.com/doc/-/s/signed-exchange-testing.dev/sxgs/invalid-signature-date.html | grep -aiE 'content-type:|warning:'
warning: 199 - "debug: content has ingestion error: SXG ingestion failure: sig_date is in the future"
content-type: text/html; charset=UTF-8
Cache ingestion is asynchronous. Documents not yet ingested will have a text/html content type but no Warning header.