WARNING: This code is still evolving, and is a developer preview. The specification is still changing, and this is an implementation of a snapshot of it. Feel free to use it, but treat with care how you configure and deploy it.
AMP Packager is a tool to improve AMP URLs. By running it in a proper configuration, web publishers may (eventually) have origin URLs appear in AMP search results.
The AMP Packager works by creating Signed HTTP
containing AMP documents, signed with a certificate associated with the origin,
with a maximum lifetime of 7 days. In the future, the Google AMP
Cache will fetch,
cache, and serve them, similar to what it does for normal AMP HTML documents.
When a user loads such an SXG, Chrome validates the signature and then displays
the certificate's domain in the URL bar instead of
google.com, and treats the
web page as though it were on that domain.
The packager is an HTTP server that sits behind a frontend server; it fetches and signs AMP documents as requested by the AMP Cache.
How to use
In all the instructions below, replace
amppackageexample.com with a domain you
own and can obtain certificates for.
Install Go version 1.10 or higher. Optionally, set $GOPATH to something (default is
~/go) and/or add
go get -u github.com/ampproject/amppackager/cmd/amppkg
Optionally, move the built
~/go/bin/amppkgwherever you like.
Create a file
amppkg.toml. A minimal config looks like this:
LocalOnly = true PackagerBase = 'https://localhost:8080/' CertFile = 'path/to/fullchain.pem' KeyFile = 'path/to/privkey.pem' OCSPCache = '/tmp/amppkg-ocsp' [[URLSet]] [URLSet.Sign] Domain = "amppackageexample.com"
More details can be found in amppkg.example.toml.
amppkg.tomlis not in the current working directory, pass
Follow the instructions here on how to deploy a local Docker container.
Test your config
- Run Chrome with the following commandline flags:
--user-data-dir=/tmp/udd --ignore-certificate-errors-spki-list=$(openssl x509 -pubkey -noout -in path/to/fullchain.pem | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64) --enable-features=SignedHTTPExchange 'data:text/html,<a href="https://localhost:8080/priv/doc/https://amppackageexample.com/">click me'
- Open DevTools. Check 'Preserve log'.
- Click the
- Watch the URL transmogrify! Verify it came from an SXG by switching
DevTools to the Network tab and looking in the
(from signed-exchange)and in the
signed-exchange. Click on that row and then click on the Preview tab, to see if there are any errors.
Demonstrate privacy-preserving prefetch
This step is optional; just to show how privacy-preserving prefetch works with SXGs.
go get -u github.com/ampproject/amppackager/cmd/amppkg_dl_sxg.
go get -u github.com/ampproject/amppackager/cmd/amppkg_test_cache.
- Open Chrome and DevTools, as above.
https://localhost:8000/. Observe the prefetch of
- Click the link. Observe that the cached SXG is used.
For now, productionizing is a bit manual. The minimum steps are:
- Don't pass
amppkg. This causes it to serve HTTP rather than HTTPS, among other changes.
- Don't expose
amppkgto the outside world; keep it on your internal network.
- Configure your TLS-serving frontend server to conditionally proxy to
- If the URL starts with
/amppkg/, forward the request unmodified.
- If the URL points to an AMP page and the
AMP-Cache-Transformrequest header is present, rewrite the URL by prepending
/priv/docand forward the request.
- If at all possible, don't send URLs of non-AMP pages to
amppkg; its transforms may break non-AMP HTML.
- DO NOT forward
/priv/docrequests; these URLs are meant to be generated by the frontend server only.
- If the URL starts with
- For HTTP compliance, ensure the
Varyheader set to
AMP-Cache-Transform, Acceptfor all URLs that point to an AMP page, irrespective of whether the response is HTML or SXG. (SXG responses that come from
amppkgwill have the appropriate
Varyheader set, so it may only be necessary to explicitly set the
Varyheader for HTML responses.)
- Get an SXG cert from your CA. It must use an EC key with the prime256v1
algorithm, and it must have a CanSignHttpExchanges
You MUST use this in
amppkg.toml, and MUST NOT use it in your frontend.
You may also want to:
amppkgas a restricted user.
- Save its stdout to a rotated log somewhere.
- Use the provided tools to verify that your published AMP documents are valid, for instance just before publication, or with a regular audit of a sample of documents. The transforms are designed to work on valid AMP pages, and may break invalid AMP in small ways.
Once you've done the above, you should be able to test by launching Chrome
without any comamndline flags; just make sure
chrome://flags/#enable-signed-http-exchange is enabled. To test by visiting the
packager URL directly, first add a Chrome extension to send an
AMP-Cache-Transform: any request header. Otherwise, follow the above
"Demonstrate privacy-preserving prefetch" instructions.
If you need to load balance across multiple instances of
amppkg, you'll want
OCSPCache to be backed by a shared storage device (e.g. NFS). It doesn't
need to be shared among all instances globally, but perhaps among all instances
per datacenter. The reason for this is to reduce the number of OCSP requests
amppkg needs to make, per OCSP stapling
How will these web packages be discovered by Google?
For now, the presence of the
Vary: AMP-Cache-Transform response header on an
AMP HTML page will allow the Google AMP Cache to make a second request with
AMP-Cache-Transform: google for the SXG.
The Google Search developer preview only runs on Chrome M71+ (as of 2018-11-12, Beta or Dev).
In the future, Googlebot may make all requests with
eliminating the double fetch.
Currently, the packager will refuse to sign any AMP documents larger than 4 MB. Patches that allow for streamed signing are welcome.
The packager refuses to sign any URL that results in a redirect. This is by design, as neither the original URL nor the final URL makes sense as the signed URL.
To account for possible clock skew in user agents, the packager back-dates packages by 24h, which means they effectively last only 6 days for most users.
This tool only packages AMP documents. To sign non-AMP documents, look at the commandline tools on which this was based, at https://github.com/WICG/webpackage/tree/master/go/signedexchange.
The local transformer is a library within the AMP Packager that transforms AMP HTML for security and performance improvements. Ports of or alternatives to the AMP Packager will need to include these transforms.
More info here.