Skip to content

connectrpc/authn-go

authn

Build Report Card GoDoc Slack

connectrpc.com/authn provides authentication middleware for Connect. It works with any authentication scheme (including HTTP basic authentication, cookies, bearer tokens, and mutual TLS), and it's carefully designed to minimize the resource consumption of unauthenticated RPCs. Middleware built with authn covers both unary and streaming RPCs made with the Connect, gRPC, and gRPC-Web protocols.

For more on Connect, see the announcement blog post, the documentation on connectrpc.com (especially the Getting Started guide for Go), the demo service, or the protocol specification.

A small example

Curious what all this looks like in practice? From a Protobuf schema, we generate a small RPC package. Using that package, we can build a server and wrap it with some basic authentication:

package main

import (
  "context"
  "crypto/subtle"
  "net/http"

  "connectrpc.com/authn"
  "connectrpc.com/authn/internal/gen/authn/ping/v1/pingv1connect"
)

func authenticate(_ context.Context, req *http.Request) (any, error) {
  username, password, ok := req.BasicAuth()
  if !ok {
    return nil, authn.Errorf("invalid authorization")
  }
  if !equal(password, "open-sesame") {
    return nil, authn.Errorf("invalid password")
  }
  // The request is authenticated! We can propagate the authenticated user to
  // Connect interceptors and services by returning it: the middleware we're
  // about to construct will attach it to the context automatically.
  return username, nil
}

func equal(left, right string) bool {
  // Using subtle prevents some timing attacks.
  return subtle.ConstantTimeCompare([]byte(left), []byte(right)) == 1
}

func main() {
  mux := http.NewServeMux()
  service := &pingv1connect.UnimplementedPingServiceHandler{}
  mux.Handle(pingv1connect.NewPingServiceHandler(service))

  middleware := authn.NewMiddleware(authenticate)
  handler := middleware.Wrap(mux)
  http.ListenAndServe("localhost:8080", handler)
}

Cookie and token-based authentication is similar. Mutual TLS is a bit more complex, but pkg.go.dev includes a complete example.

Ecosystem

  • connect-go: the Go implementation of Connect's RPC runtime
  • examples-go: service powering demo.connectrpc.com, including bidi streaming
  • grpchealth: gRPC-compatible health checks
  • grpcreflect: gRPC-compatible server reflection
  • cors: CORS support for Connect servers
  • connect-es: Type-safe APIs with Protobuf and TypeScript
  • conformance: Connect, gRPC, and gRPC-Web interoperability tests

Status: Unstable

This module isn't stable yet, but it's fairly small — we expect to reach a stable release quickly.

It supports the three most recent major releases of Go. Keep in mind that only the last two releases receive security patches.

Within those parameters, authn follows semantic versioning. We will not make breaking changes in the 1.x series of releases.

Legal

Offered under the Apache 2 license.