cmd/pubsubhelper: migrate secrets to secret manager
This change retrieves the secrets used by pubsubhelper from secret
manager. It is part of the project to store all secrets in a single
location.
The change required updating the ca-certificates in the container. I
made the docker configuration match the gopherbot configuration in
an effort to maintain uniformity.
Updates golang/go#37171
Change-Id: I0d48beccb08ac2e850a99cff1b45df3907b13474
Reviewed-on: https://go-review.googlesource.com/c/build/+/222177
Run-TryBot: Carlos Amedee <carlos@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alexander Rakoczy <alex@golang.org>
diff --git a/cmd/pubsubhelper/Dockerfile b/cmd/pubsubhelper/Dockerfile
index cfff76f..1b93f02 100644
--- a/cmd/pubsubhelper/Dockerfile
+++ b/cmd/pubsubhelper/Dockerfile
@@ -32,5 +32,18 @@
FROM debian:stretch
LABEL maintainer "golang-dev@googlegroups.com"
+# netbase and ca-certificates are needed for dialing TLS.
+# The rest are useful for debugging if somebody needs to exec into the container.
+RUN apt-get update && apt-get install -y \
+ --no-install-recommends \
+ netbase \
+ ca-certificates \
+ curl \
+ strace \
+ procps \
+ lsof \
+ psmisc \
+ && rm -rf /var/lib/apt/lists/*
+
COPY --from=build /go/bin/pubsubhelper /
ENTRYPOINT ["/pubsubhelper"]
diff --git a/cmd/pubsubhelper/github.go b/cmd/pubsubhelper/github.go
index 9e2428f..f4191a0 100644
--- a/cmd/pubsubhelper/github.go
+++ b/cmd/pubsubhelper/github.go
@@ -17,7 +17,6 @@
"net/http"
"strings"
- "cloud.google.com/go/compute/metadata"
"golang.org/x/build/cmd/pubsubhelper/pubsubtypes"
)
@@ -97,16 +96,12 @@
return nil, err
}
- // Compute expected signature.
- key, err := metadata.ProjectAttributeValue("pubsubhelper-webhook-secret")
- if err != nil {
- return nil, err
- }
body, err = ioutil.ReadAll(http.MaxBytesReader(w, r.Body, 5<<20))
if err != nil {
return nil, err
}
- mac := hmac.New(h, []byte(key))
+ // TODO(golang/go#37171): find a cleaner solution than using a global
+ mac := hmac.New(h, []byte(*webhookSecret))
mac.Write(body)
expectSig := mac.Sum(nil)
diff --git a/cmd/pubsubhelper/pubsubhelper.go b/cmd/pubsubhelper/pubsubhelper.go
index 9e084a9..91de894 100644
--- a/cmd/pubsubhelper/pubsubhelper.go
+++ b/cmd/pubsubhelper/pubsubhelper.go
@@ -32,19 +32,22 @@
"github.com/jellevandenhooff/dkim"
"go4.org/types"
"golang.org/x/build/cmd/pubsubhelper/pubsubtypes"
+ "golang.org/x/build/internal/secret"
"golang.org/x/crypto/acme/autocert"
)
var (
- botEmail = flag.String("rcpt", "\x67\x6f\x70\x68\x65\x72\x62\x6f\x74@pubsubhelper.golang.org", "email address of bot. incoming emails must be to this address.")
- httpListen = flag.String("http", ":80", "HTTP listen address")
- acmeDomain = flag.String("autocert", "pubsubhelper.golang.org", "If non-empty, listen on port 443 and serve HTTPS with a LetsEncrypt cert for this domain.")
- smtpListen = flag.String("smtp", ":25", "SMTP listen address")
+ botEmail = flag.String("rcpt", "\x67\x6f\x70\x68\x65\x72\x62\x6f\x74@pubsubhelper.golang.org", "email address of bot. incoming emails must be to this address.")
+ httpListen = flag.String("http", ":80", "HTTP listen address")
+ acmeDomain = flag.String("autocert", "pubsubhelper.golang.org", "If non-empty, listen on port 443 and serve HTTPS with a LetsEncrypt cert for this domain.")
+ smtpListen = flag.String("smtp", ":25", "SMTP listen address")
+ webhookSecret = flag.String("webhook-secret", "", "Development mode GitHub webhook secret. This flag should not be used in production.")
)
func main() {
flag.Parse()
+ ctx := context.Background()
ch := make(chan os.Signal, 1)
signal.Notify(ch, os.Interrupt)
go func() {
@@ -53,6 +56,21 @@
os.Exit(0)
}()
+ // webhooksecret should not be set in production
+ if *webhookSecret == "" {
+ sc := mustCreateSecretClient()
+ defer sc.Close()
+
+ ctxSc, cancel := context.WithTimeout(ctx, 10*time.Second)
+ defer cancel()
+
+ var err error
+ *webhookSecret, err = sc.Retrieve(ctxSc, secret.NamePubSubHelperWebhook)
+ if err != nil {
+ log.Fatalf("unable to retrieve webhook secret %v", err)
+ }
+ }
+
http.HandleFunc("/", handleRoot)
http.HandleFunc("/waitevent", handleWaitEvent)
http.HandleFunc("/recent", handleRecent)
@@ -410,3 +428,11 @@
log.Printf("smtpd: new connection from %v", c.Addr())
return nil
}
+
+func mustCreateSecretClient() *secret.Client {
+ client, err := secret.NewClient()
+ if err != nil {
+ log.Fatalf("unable to create secret client %v", err)
+ }
+ return client
+}