design: add DNS based vanity import proposal

See golang/go#26160

Change-Id: Ibd5ccb79ecf3aa71cf93c9d9a8667c7f5db1887f
GitHub-Last-Rev: f90d065955f43bb54e10789f37408c902e8d35c9
GitHub-Pull-Request: golang/proposal#16
Reviewed-on: https://go-review.googlesource.com/121817
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/design/26160-dns-based-vanity-imports.md b/design/26160-dns-based-vanity-imports.md
new file mode 100644
index 0000000..df1fa73
--- /dev/null
+++ b/design/26160-dns-based-vanity-imports.md
@@ -0,0 +1,96 @@
+# Proposal: DNS Based Vanity Imports
+
+Author(s): Sam Whited <sam@samwhited.com>
+
+Last updated: 2018-06-30
+
+Discussion at https://golang.org/issue/26160
+
+
+## Abstract
+
+A new mechanism for performing vanity imports using DNS TXT records.
+
+
+## Background
+
+Vanity imports allow the servers behind Go import paths to delegate hosting of
+a packages source code to another host.
+This is done using the HTTP protocol over TLS which means that expired
+certificates, problems with bespoke servers, timeouts contacting the server, and
+any number of other problems can cause looking up the source to fail.
+Running an HTTP server also adds unnecessary overhead and expense that may be
+difficult for hobbyists that create popular packages.
+To avoid these problems, a new mechanism for looking up vanity imports is
+needed.
+
+
+## Proposal
+
+To create a vanity import using DNS a separate TXT record is created for each
+package with the name `go-import.example.net` where `example.net` is the domain
+from the package import path.
+The record data is the same format that would appear in an HTTP based vanity
+imports "content" attribute.
+This allows us to easily list all packages with vanity imports under a given
+apex domain:
+
+    $ dig +short go-import.golang.org TXT
+    "golang.org/x/vgo git https://go.googlesource.com/vgo"
+    "golang.org/x/text git https://go.googlesource.com/text"
+    …
+
+Because the current system for vanity import paths requires TLS unless the
+`-insecure` flag is provided to `go get`, it is desirable to provide similar
+security guarantees with DNS.
+To this end `go get` should only accept TXT records with a verified DNSSEC
+signature unless the `-insecure` flag has been passed.
+To determine which package to import the Go tool would search each TXT record
+returned for one that starts with the same fully qualified import path that
+triggered the lookup.
+TXT records for a given domain should be fetched only once when the first
+package with a given domain in its import path is found and reused when parsing
+other import lines in the same build.
+
+
+## Rationale
+
+Before we can make an HTTP request (as the current vanity import mechanism
+does), or even establish a TLS connection, we must already have performed a DNS
+lookup.
+Because this happens anyways, it would be ideal to cut out other steps (HTTP,
+TLS, etc.) altogether (and the extra problems they bring with them) and store
+the information in the DNS record.
+Even if vanity imports are deprecated in the near future for ZIP based package
+servers ala vgo, backwards compatibility will be needed for some time and any
+experience gained here may apply to pointing domains at package servers
+(eg. via DNS SRV).
+
+TXT records were chosen instead of a [custom resource record] to simplify
+deployment and avoid the overhead of dealing with the IETF.
+Because TXT records are limited to 255 characters but the apex domain used by a
+package may be significantly longer than this, it is possible that some packages
+may not fit in the record.
+Since fully qualified package names must be typed in import statements this does
+not seem practical or a cause for concern, so it is not addressed here.
+
+[custom resource record]: https://tools.ietf.org/html/rfc6195
+
+
+## Compatibility
+
+If no TXT records are found for a given domain `go get` should fall back to
+using the HTTP-based mechanism.
+Having DNS TXT record lookup also lays the groundwork for discovering package
+servers in a vgo-based future.
+
+
+## Implementation
+
+The author of this proposal has started looking into implementing it in the Go
+tool, but cannot yet commit to a timeframe for an implementation.
+
+
+## Open issues
+
+- Does a DNSSEC implementation exist that could be vendored into the Go tool?