- Will signed exchanges work for me?
- Implementing signed exchanges
- Signed exchange service providers
Serve AMP using signed exchanges
Important: this documentation is not applicable to your currently selected format stories!
AMP provides speed benefits above and beyond the format through techniques like caching and preloading. These benefits can have downsides like extra URLs being displayed when embeded inside an AMP Viewer. By serving AMP content using signed exchanges, you can use a new web platform feature to overcome all of these.
A signed exchange is made up of a valid AMP document and the original URL of the content. This information is protected by digital signatures that securely tie the document to its claimed URL. This enables browsers to safely display the original URL in the URL bar instead of the hostname of the machine that delivered the bytes to the browser.
Signed AMP content is delivered in addition to (rather than instead of) regular AMP content.
This feature is currently supported on Chrome, but implementation is planned for additional browsers.
Will signed exchanges work for me?
To implement signed exchanges, you must meet the following requirements:
- Ability to configure and control the HTTP headers generated by your server. (Most purely web-based hosting solutions such as Blogger are not compatible with signed exchanges.)
- The ability to generate AMP signed exchanges, such as by running
amppackager, as a Go binary, or within a Docker VM.
- The packager needs to be updated every six weeks.
- The ability to Vary on
AMP-Cache-Transformheaders on edge HTTP servers, returning different content for the same URL.
- The system running the
amppackagerneeds to be able to make outgoing network requests to:
- The certificate authority that issues your certificate
- The publisher server that hosts the AMP documents to sign
cdn.ampproject.orgto obtain the current version of AMP
- A persistent shared storage filesystem between all instances of
amppackagerrunning in the same data center.
Implementing signed exchanges
Below is the suggested order of implementation to support signed exchanges on your AMP documents.
Acquire a supported TLS certificate
In order to generate the certificate, the Certificate Authority (CA) will require a Certificate Signing Request (CSR), which can be generated by
openssl. An example CSR for
# generate private key (if necessary) $ openssl ecparam -out ampbyexample-packager.key -name prime256v1 -genkey # generate CSR (the file ampbyexample-packager.csr) $ openssl req -new -key ampbyexample-packager.key -nodes -out ampbyexample-packager.csr -subj "/C=US/ST=California/L=Mountain View/O=Google LLC/CN=ampbyexample.com"
Determine which URLs will be signed
You will need to create a URL pattern that defines which documents should be signed. It is critical that private content, such as personalized information should not be signed, to avoid sending misleading or incorrect content.
For performance purposes, the packager should only be passed valid AMP documents as input. Some invalid AMP documents are fine if needed, but you should avoid sending all traffic through the packager.
Deploy packager to a staging server
You should first set up signed exchanges on a staging server to verify your setup is correct before migrating to production.
We recommend using
amppackager to generate signed exchanges. However if this is not a good fit for your production environment you can instead use the command-line clients
gen-signedexchange, and handle the content negotiation and certificate management tasks yourself.
The following instructions apply to the deployments using
amppackager's config file (
amppkg.toml) calls for a CertFile and a KeyFile.
The KeyFile is the private key (
ampbyexample-packager.key in the example above), and it should have the following format. (Note: do not share your own private key, and protect it from inadvertent sharing!)
-----BEGIN EC PARAMETERS----- BggqhkjOPQMBBw== -----END EC PARAMETERS----- -----BEGIN EC PRIVATE KEY----- MHcCAQEEINDgf1gprbdD6hM1ttmRC9+tOqJ+lNRtHwZahJIXfLADoAoGCCqGSM49 … 4j1NY29jVmAMQYrBYb+6heiv6ok+8c/zJQ== -----END EC PRIVATE KEY-----
The CertFile is the public certificate. If DigiCert provided the certificate, this can be created by concatenating together the origin-specific certificate provided by DigiCert and the
-----BEGIN CERTIFICATE----- MIIE0zCCBFmgAwIBAgIQCkEgeFknZluZtdcJnvdFCjAKBggqhkjOPQQDAjBMMQsw CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMSYwJAYDVQQDEx1EaWdp Q2VydCBFQ0MgU2VjdXJlIFNlcnZlciBDQTAeFw0xODEwMzAwMDAwMDBaFw0xOTEx MDYxMjAwMDBaMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJjYTEWMBQGA1UEBxMN TW91bnRhaW4gVmlldzETMBEGA1UEChMKR29vZ2xlIExMQzEZMBcGA1UEAxMQYW1w YnlleGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABAGu0CjzWa6i … PXLGRK8i0lr7Jv6ZKPY8tfaB/c5yK404QU4HNggmAiEAlnNjIerjJOLHb8CvVaUQ nhhn0a35nHp1yvE651W14fMwCgYIKoZIzj0EAwIDaAAwZQIwI4/7dpqJQxkQwpP3 DAjVOFdjC6PDcUIRPll3bF0srrTUXSyZ8xkM4q/RhB51A0hVAjEAsUGNYBje9RIO wf9qyV2iHB+9cBwgKfC0KvEcBugbgHShypM8hPhV9UMC3qTpdKPx -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDrDCCApSgAwIBAgIQCssoukZe5TkIdnRw883GEjANBgkqhkiG9w0BAQwFADBh MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaMEwxCzAJBgNVBAYTAlVT … loB5hWp2Jp2VDCADjT7ueihlZGak2YPqmXTNbk19HOuNssWvFhtOyPNV6og4ETQd Ea8/B6hPatJ0ES8q/HO3X8IVQwVs1n3aAr0im0/T+Xc= -----END CERTIFICATE-----
Follow instructions here to set up
amppackager for your site.
packager.js (used by
amp.dev) for an example of the server-side changes you will need to make to route the required requests to
Verify that your staging site responds with content of MIME type
application/signed-exchange when specified by the HTTP request. For example (replace
staging.example.com with your staging server):
$ curl -si -H 'amp-cache-transform: google;v="1..100"' -H 'accept: application/signed-exchange;v=b3;q=0.9,*/*;q=0.8' https://staging.example.com/ | less
The output must include this line:
v="1..100" in the request is a placeholder. Do not match on this exact value; instead, as described in the amppackager installation instructions, check for the existence of the
amp-cache-transform header only, and ignore the value.
v=b3 version string in the response is the version as of August 2019. This version will change.
The bulk of the response should be your AMP page (in plaintext). There's a small binary header, and, if the page is >16kb, a few binary bytes sprinkled throughout.
dump-signedexchange tool can be used to inspect the response:
$ curl -s --output - -H 'amp-cache-transform: google;v="1..100"' -H 'accept: application/signed-exchange;v=b3;q=0.9,*/*;q=0.8' https://staging.example.com/ > example.sxg $ dump-signedexchange -i example.sxg format version: 1b3
(Note that the
-verify switch will not work at this point because the required certificates are not on the
Verify that the response always include the
Vary header with the value
Accept,AMP-Cache-Transform (irrespective of whether the MIME type is
application/signed-exchange, or something else):
$ curl -si https://staging.example.com/ | less
This output must include this line:
Deploy packager to production
Adjust the staging deployment steps above as appropriate for your production environment.
With command-line tools
Run through the same tests as above.
dump-signedexchange -verify should now also succeed.
You can also test in Chrome with the help of the ModHeader extension. Install it from the Chrome Webstore and configure the
Request Headers to
amp-cache-transform with a
https://example.com/ your server will deliver a signed exchange, but it should look and behave the same as before. You will need to check that a signed exchange is correctly being returned via the DevTools console.
Network tab, click on your domain name and check that
Signed HTTP exchange appears under
With the Google AMP Cache
Confirm that the signed exchanges are compatible with the Google AMP cache. This related to their discoverability on search engines such as Google Search.
To test signed exchanges in the Google AMP cache, open the network tab in DevTools, enable
Preserve log, and visit a URL such as
DevTools will show a
200 with a
signed-exchange row, and a
from signed-exchange row, if the request was successful.
If unsuccessful, the signed-exchange rows will be missing, or they will be highlighted red. A
warning header may also be present that provides additional information.
Signed exchanges in Google Search
If your AMP pages were successfully distributed as signed exchanges, their search results will display the AMP lightning bolt, same as before, but tapping on the results will show
https://example.com in the URL bar, instead of a URL beginning with
https://www.google.com/amp/….. Additionally, the
viewer bar will not appear.
Within the DevTools console, under the
network tab, you will be able to see
signed-exchange under the
Signed exchange service providers
Here is a list of CDNs and hosting providers offering out-of-the-box support for signed exchanges. Using one of these is the easiest way to get started with signed exchanges:
Written by @CrystalOnScript