MCPcopy Create free account
hub / github.com/coder/coder / authMiddleware

Method authMiddleware

enterprise/aibridgeproxyd/aibridgeproxyd.go:639–695  ·  view source on GitHub ↗

authMiddleware is a CONNECT middleware that extracts the Coder token from the Proxy-Authorization header and stores it in a requestContext in ctx.UserData for use by downstream handlers. Requests without valid credentials receive a 407 Proxy Authentication Required response with a challenge header,

(host string, ctx *goproxy.ProxyCtx)

Source from the content-addressed store, hash-verified

637//
638// The token is extracted from the password field of basic auth.
639func (s *Server) authMiddleware(host string, ctx *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) {
640 // Generate a unique connect session ID for this CONNECT request.
641 // A UUID is used instead of goproxy's ctx.Session because ctx.Session is an
642 // incrementing int64 that resets on process restart and is not globally unique.
643 connectSessionID := uuid.New()
644
645 logger := s.logger.With(
646 slog.F("connect_id", connectSessionID.String()),
647 slog.F("host", host),
648 )
649
650 // Determine the provider from the request hostname.
651 provider := s.loadProviderRouter().providerFromHost(ctx.Req.URL.Hostname())
652 // A concurrent Reload can swap the router between CONNECT matching
653 // and provider lookup, so treat a missing mapping as a runtime miss.
654 if provider == "" {
655 logger.Warn(s.ctx, "rejecting CONNECT request with no provider mapping")
656 return goproxy.RejectConnect, host
657 }
658
659 logger = logger.With(
660 slog.F("provider", provider),
661 )
662
663 proxyAuth := ctx.Req.Header.Get("Proxy-Authorization")
664 coderToken := extractCoderTokenFromProxyAuth(proxyAuth)
665
666 // Reject requests for both missing and invalid credentials
667 if coderToken == "" {
668 hasAuth := proxyAuth != ""
669 logger.Warn(s.ctx, "rejecting CONNECT request",
670 slog.F("reason", map[bool]string{true: "invalid_credentials", false: "missing_credentials"}[hasAuth]),
671 )
672
673 // Send 407 challenge to allow clients to retry with credentials.
674 ctx.Resp = newProxyAuthRequiredResponse(ctx.Req) //nolint:bodyclose // Response body is written by goproxy to the client
675 return goproxy.RejectConnect, host
676 }
677
678 // Store the request context in UserData for downstream handlers.
679 // goproxy propagates UserData to subsequent request/response contexts
680 // for decrypted requests within this MITM session.
681 ctx.UserData = &requestContext{
682 ConnectSessionID: connectSessionID,
683 CoderToken: coderToken,
684 Provider: provider,
685 }
686
687 logger.Debug(s.ctx, "request CONNECT authenticated")
688
689 // Record successful MITM CONNECT session establishment.
690 if s.metrics != nil {
691 s.metrics.ConnectSessionsTotal.WithLabelValues(RequestTypeMITM).Inc()
692 }
693
694 return goproxy.MitmConnect, host
695}
696

Callers

nothing calls this directly

Calls 8

loadProviderRouterMethod · 0.95
providerFromHostMethod · 0.80
WithLabelValuesMethod · 0.80
NewMethod · 0.65
GetMethod · 0.65
StringMethod · 0.45

Tested by

no test coverage detected