diff --git a/server/server.go b/server/server.go
index e65463b0d2fd9ab67bb18f37e23e89e19d4f2e8e..ba17efd1f119b6f3528e78a56a244752282ddc77 100644
--- a/server/server.go
+++ b/server/server.go
@@ -47,7 +47,7 @@ func (s *keyStoreServer) handleGet(w http.ResponseWriter, r *http.Request) {
 		// Return an appropriate error code.
 		switch err {
 		case errUnauthorized, errBadUser:
-			http.Error(w, err.Error(), http.StatusUnauthorized)
+			http.Error(w, err.Error(), http.StatusForbidden)
 		case errNoKeys:
 			http.NotFound(w, r)
 		default:
diff --git a/vendor/git.autistici.org/ai3/go-common/serverutil/http.go b/vendor/git.autistici.org/ai3/go-common/serverutil/http.go
index 32329492c8a490485b7094fd4e2d608246aa78d8..09cc9bb39440f01b502cf375d9a3ec28777e4955 100644
--- a/vendor/git.autistici.org/ai3/go-common/serverutil/http.go
+++ b/vendor/git.autistici.org/ai3/go-common/serverutil/http.go
@@ -115,8 +115,9 @@ func Serve(h http.Handler, config *ServerConfig, addr string) error {
 
 	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
 
-	// Notify systemd that we are ready to serve.
-	daemon.SdNotify(false, "READY=1")
+	// Notify systemd that we are ready to serve. This call is
+	// allowed to fail (in case there is no systemd).
+	daemon.SdNotify(false, "READY=1") // nolint
 
 	err = srv.Serve(l)
 	if err != http.ErrServerClosed {
@@ -132,7 +133,7 @@ func defaultHandler(h http.Handler) http.Handler {
 
 	// Add an endpoint for HTTP health checking probes.
 	root.Handle("/health", http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
-		io.WriteString(w, "OK")
+		io.WriteString(w, "OK") // nolint
 	}))
 
 	// Add an endpoint to serve Prometheus metrics.
diff --git a/vendor/git.autistici.org/ai3/go-common/serverutil/tls.go b/vendor/git.autistici.org/ai3/go-common/serverutil/tls.go
index 7e5adff9134af3efd35e26a08b36f26704064bc5..5d0d98456bb9e1c73e6149f352a81c135decaa81 100644
--- a/vendor/git.autistici.org/ai3/go-common/serverutil/tls.go
+++ b/vendor/git.autistici.org/ai3/go-common/serverutil/tls.go
@@ -2,6 +2,8 @@ package serverutil
 
 import (
 	"crypto/tls"
+	"fmt"
+	"log"
 	"net/http"
 	"regexp"
 
@@ -119,6 +121,13 @@ func (c *TLSServerConfig) TLSAuthWrapper(h http.Handler) (http.Handler, error) {
 			h.ServeHTTP(w, r)
 			return
 		}
-		http.Error(w, "Unauthorized", http.StatusUnauthorized)
+
+		// Log the failed access, useful for debugging.
+		var tlsmsg string
+		if r.TLS != nil && len(r.TLS.PeerCertificates) > 0 {
+			tlsmsg = fmt.Sprintf(" TLS client '%s' at", r.TLS.PeerCertificates[0].Subject.CommonName)
+		}
+		log.Printf("unauthorized access to %s from %s%s", r.URL.Path, tlsmsg, r.RemoteAddr)
+		http.Error(w, "Forbidden", http.StatusForbidden)
 	}), nil
 }
diff --git a/vendor/git.autistici.org/id/go-sso/README.md b/vendor/git.autistici.org/id/go-sso/README.md
index 9bd4afb1d0e1b61389a27fb58d6914c5ae79987f..341f91ae6a601007b0d913dad59f87208bc044f1 100644
--- a/vendor/git.autistici.org/id/go-sso/README.md
+++ b/vendor/git.autistici.org/id/go-sso/README.md
@@ -115,13 +115,17 @@ parameters:
 * `cur_nonce`: nonce for *cur_tkt*
 * `new_svc`: destination SSO service
 * `new_nonce`: nonce for the new SSO ticket
-* `new_groups` (optional): a comma-separated list of groups that the
-  destination service might check membership for
 
 Note that annoyingly *cur_svc* and *cur_nonce* are redundant, as they
 are already contained within *cur_tkt*, but the SSO ticket API won't
 allow us to decode the ticket without verifying it at the same time.
 
+The new ticket will not be valid any longer than the original one, or
+the configured TTL for the new service, whichever comes first.
+
+Group membership in the original ticket is passed along unchanged to
+the new ticket.
+
 
 # Implementation notes
 
diff --git a/vendor/git.autistici.org/id/go-sso/sso.go b/vendor/git.autistici.org/id/go-sso/sso.go
index 13e600143bd5cb56dcfa45a1c3c0e6592c75ab26..37c5832ed917999f8c86beabdae303c5841cfca6 100644
--- a/vendor/git.autistici.org/id/go-sso/sso.go
+++ b/vendor/git.autistici.org/id/go-sso/sso.go
@@ -270,3 +270,21 @@ func (v *ssoValidator) Validate(encoded, nonce, service string, allowedGroups []
 
 	return t, nil
 }
+
+// InspectTicket reads a ticket without validating it (beyond syntax),
+// returning user and service. The results are untrusted.
+func InspectTicket(encoded string) (string, string, error) {
+	decoded, err := base64.RawURLEncoding.DecodeString(encoded)
+	if err != nil {
+		return "", "", err
+	}
+	if len(decoded) < signatureLen {
+		return "", "", ErrMessageTooShort
+	}
+	serialized := decoded[signatureLen:]
+	t, err := deserializeTicket(string(serialized))
+	if err != nil {
+		return "", "", err
+	}
+	return t.User, t.Service, nil
+}
diff --git a/vendor/github.com/cenkalti/backoff/context.go b/vendor/github.com/cenkalti/backoff/context.go
index d7005522942c3b5c5b2ec45735a4e106add8041b..7706faa2b6005710090d1c047cb60807bbea4468 100644
--- a/vendor/github.com/cenkalti/backoff/context.go
+++ b/vendor/github.com/cenkalti/backoff/context.go
@@ -51,9 +51,13 @@ func (b *backOffContext) Context() context.Context {
 
 func (b *backOffContext) NextBackOff() time.Duration {
 	select {
-	case <-b.Context().Done():
+	case <-b.ctx.Done():
 		return Stop
 	default:
-		return b.BackOff.NextBackOff()
 	}
+	next := b.BackOff.NextBackOff()
+	if deadline, ok := b.ctx.Deadline(); ok && deadline.Sub(time.Now()) < next {
+		return Stop
+	}
+	return next
 }
diff --git a/vendor/github.com/cenkalti/backoff/exponential.go b/vendor/github.com/cenkalti/backoff/exponential.go
index d9de15a177bf47b61964e0b149e741eec2c14d19..a031a659799fc24fc0d368de9c9bf83bfbbe5952 100644
--- a/vendor/github.com/cenkalti/backoff/exponential.go
+++ b/vendor/github.com/cenkalti/backoff/exponential.go
@@ -63,7 +63,6 @@ type ExponentialBackOff struct {
 
 	currentInterval time.Duration
 	startTime       time.Time
-	random          *rand.Rand
 }
 
 // Clock is an interface that returns current time for BackOff.
@@ -89,7 +88,6 @@ func NewExponentialBackOff() *ExponentialBackOff {
 		MaxInterval:         DefaultMaxInterval,
 		MaxElapsedTime:      DefaultMaxElapsedTime,
 		Clock:               SystemClock,
-		random:              rand.New(rand.NewSource(time.Now().UnixNano())),
 	}
 	b.Reset()
 	return b
@@ -118,10 +116,7 @@ func (b *ExponentialBackOff) NextBackOff() time.Duration {
 		return Stop
 	}
 	defer b.incrementCurrentInterval()
-	if b.random == nil {
-		b.random = rand.New(rand.NewSource(time.Now().UnixNano()))
-	}
-	return getRandomValueFromInterval(b.RandomizationFactor, b.random.Float64(), b.currentInterval)
+	return getRandomValueFromInterval(b.RandomizationFactor, rand.Float64(), b.currentInterval)
 }
 
 // GetElapsedTime returns the elapsed time since an ExponentialBackOff instance
diff --git a/vendor/github.com/cenkalti/backoff/retry.go b/vendor/github.com/cenkalti/backoff/retry.go
index e65cc700de71f561a5939c3577c637074a316444..49a30e9b12796c1eff0bb27ba61e17ebc7322e0c 100644
--- a/vendor/github.com/cenkalti/backoff/retry.go
+++ b/vendor/github.com/cenkalti/backoff/retry.go
@@ -41,7 +41,7 @@ func RetryNotify(operation Operation, b BackOff, notify Notify) error {
 			return permanent.Err
 		}
 
-		if next = b.NextBackOff(); next == Stop {
+		if next = cb.NextBackOff(); next == Stop {
 			return err
 		}
 
diff --git a/vendor/vendor.json b/vendor/vendor.json
index 55e5e7b2045836c0bd0a34bef31db0795016b115..322856b94e7f1e0b061a243318e4127530bba55a 100644
--- a/vendor/vendor.json
+++ b/vendor/vendor.json
@@ -5,44 +5,44 @@
 		{
 			"checksumSHA1": "pLvPnUablirQucyALgrso9hLG4E=",
 			"path": "git.autistici.org/ai3/go-common",
-			"revision": "b5271f0caf05207e352c14bcf69e5c172e9e37cc",
-			"revisionTime": "2018-10-29T06:42:37Z"
+			"revision": "6916834dec86e761a3091c9628cbff9b6c389867",
+			"revisionTime": "2018-10-29T11:03:54Z"
 		},
 		{
 			"checksumSHA1": "Xd4ClmFykFMOg8b2ZFXimSS3Uj0=",
 			"path": "git.autistici.org/ai3/go-common/clientutil",
-			"revision": "b5271f0caf05207e352c14bcf69e5c172e9e37cc",
-			"revisionTime": "2018-10-29T06:42:37Z"
+			"revision": "6916834dec86e761a3091c9628cbff9b6c389867",
+			"revisionTime": "2018-10-29T11:03:54Z"
 		},
 		{
 			"checksumSHA1": "kQbBWZqrXc95wodlrOKEshQVaBo=",
 			"path": "git.autistici.org/ai3/go-common/ldap",
-			"revision": "b5271f0caf05207e352c14bcf69e5c172e9e37cc",
-			"revisionTime": "2018-10-29T06:42:37Z"
+			"revision": "6916834dec86e761a3091c9628cbff9b6c389867",
+			"revisionTime": "2018-10-29T11:03:54Z"
 		},
 		{
-			"checksumSHA1": "7VBLbwaK1m/jwsk8sLsh4iD9T/s=",
+			"checksumSHA1": "RyFydcBJvLBevfsriijLqHtZ0hs=",
 			"path": "git.autistici.org/ai3/go-common/serverutil",
-			"revision": "b5271f0caf05207e352c14bcf69e5c172e9e37cc",
-			"revisionTime": "2018-10-29T06:42:37Z"
+			"revision": "6916834dec86e761a3091c9628cbff9b6c389867",
+			"revisionTime": "2018-10-29T11:03:54Z"
 		},
 		{
 			"checksumSHA1": "Okvoje2tgehkMo1N9Q601JPgGoE=",
 			"path": "git.autistici.org/ai3/go-common/unix",
-			"revision": "b5271f0caf05207e352c14bcf69e5c172e9e37cc",
-			"revisionTime": "2018-10-29T06:42:37Z"
+			"revision": "6916834dec86e761a3091c9628cbff9b6c389867",
+			"revisionTime": "2018-10-29T11:03:54Z"
 		},
 		{
 			"checksumSHA1": "witSYnNsDhNaoA85UYilt17H+ng=",
 			"path": "git.autistici.org/ai3/go-common/userenckey",
-			"revision": "b5271f0caf05207e352c14bcf69e5c172e9e37cc",
-			"revisionTime": "2018-10-29T06:42:37Z"
+			"revision": "6916834dec86e761a3091c9628cbff9b6c389867",
+			"revisionTime": "2018-10-29T11:03:54Z"
 		},
 		{
-			"checksumSHA1": "SFxqNnYqTQDH4goNZ7v8KevTNzg=",
+			"checksumSHA1": "s3Ao3RV8QQQpqld7jNYqOwA7Sdo=",
 			"path": "git.autistici.org/id/go-sso",
-			"revision": "7b8eca6ac80bb75f798363830b91ca3a75b950d8",
-			"revisionTime": "2018-10-27T13:28:35Z"
+			"revision": "522bc582e4bc44826f52243be5d4e1c6a751e01b",
+			"revisionTime": "2018-11-03T07:08:42Z"
 		},
 		{
 			"checksumSHA1": "0rido7hYHQtfq3UJzVT5LClLAWc=",
@@ -51,10 +51,10 @@
 			"revisionTime": "2018-03-21T16:47:47Z"
 		},
 		{
-			"checksumSHA1": "EAUmmJ4ccZbyuyf8Fnf+KU+DH3w=",
+			"checksumSHA1": "2nTxrtvUecg8v33ZkjIFiUxfUI8=",
 			"path": "github.com/cenkalti/backoff",
-			"revision": "b7325b0f3f1097c6546ea5e83c4a23267e58ad71",
-			"revisionTime": "2018-08-01T15:21:24Z"
+			"revision": "62661b46c4093e2c1f38d943e663db1a29873e80",
+			"revisionTime": "2018-10-03T08:08:54Z"
 		},
 		{
 			"checksumSHA1": "zg16zjZTQ9R89+UOLmEZxHgxDtM=",