pomerium/internal/controlplane/http.go
Denis Mishin 1a19ccabd8
mcp: add global runtime flag (#5604)
## Summary

Adds global runtime flag to enable/disable MCP support. (off by
default).

```yaml
runtime_flags:
  mcp: true
```

## Related issues

Fix:
https://linear.app/pomerium/issue/ENG-2367/place-mcp-support-behind-a-runtime-flag

## User Explanation

<!-- How would you explain this change to the user? If this
change doesn't create any user-facing changes, you can leave
this blank. If filled out, add the `docs` label -->

## Checklist

- [x] reference any related issues
- [ ] updated unit tests
- [ ] add appropriate label (`enhancement`, `bug`, `breaking`,
`dependencies`, `ci`)
- [ ] ready for review
2025-05-02 16:33:42 -04:00

91 lines
3.2 KiB
Go

// Package controlplane contains the HTTP and gRPC base servers and the xDS gRPC implementation for envoy.
package controlplane
import (
"context"
"fmt"
"net/http"
"time"
"github.com/CAFxX/httpcompression"
"github.com/gorilla/mux"
"github.com/rs/zerolog"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"github.com/pomerium/pomerium/config"
"github.com/pomerium/pomerium/internal/handlers"
"github.com/pomerium/pomerium/internal/log"
"github.com/pomerium/pomerium/internal/mcp"
"github.com/pomerium/pomerium/internal/middleware"
"github.com/pomerium/pomerium/internal/telemetry"
"github.com/pomerium/pomerium/internal/urlutil"
hpke_handlers "github.com/pomerium/pomerium/pkg/hpke/handlers"
"github.com/pomerium/pomerium/pkg/telemetry/requestid"
"github.com/pomerium/pomerium/pkg/telemetry/trace"
)
func (srv *Server) addHTTPMiddleware(ctx context.Context, root *mux.Router, _ *config.Config) {
logger := log.Ctx(ctx)
compressor, err := httpcompression.DefaultAdapter()
if err != nil {
panic(err)
}
root.Use(compressor)
root.Use(srv.reproxy.Middleware)
root.Use(requestid.HTTPMiddleware())
root.Use(log.NewHandler(func() *zerolog.Logger { return logger }))
root.Use(log.AccessHandler(func(r *http.Request, status, size int, duration time.Duration) {
log.FromRequest(r).Debug().
Dur("duration", duration).
Int("size", size).
Int("status", status).
Str("method", r.Method).
Str("host", r.Host).
Str("path", r.URL.String()).
Msg("http-request")
}))
root.Use(middleware.Recovery)
root.Use(log.RemoteAddrHandler("ip"))
root.Use(log.UserAgentHandler("user_agent"))
root.Use(log.RefererHandler("referer"))
root.Use(log.RequestIDHandler("request-id"))
root.Use(telemetry.HTTPStatsHandler(func() string {
return srv.currentConfig.Load().Options.InstallationID
}, srv.name))
}
func (srv *Server) mountCommonEndpoints(root *mux.Router, cfg *config.Config) error {
authenticateURL, err := cfg.Options.GetAuthenticateURL()
if err != nil {
return fmt.Errorf("invalid authenticate URL: %w", err)
}
signingKey, err := cfg.Options.GetSigningKey()
if err != nil {
return fmt.Errorf("invalid signing key: %w", err)
}
hpkePrivateKey, err := cfg.Options.GetHPKEPrivateKey()
if err != nil {
return fmt.Errorf("invalid hpke private key: %w", err)
}
hpkePublicKey := hpkePrivateKey.PublicKey()
root.HandleFunc("/healthz", handlers.HealthCheck)
root.HandleFunc("/ping", handlers.HealthCheck)
traceHandler := trace.NewHTTPMiddleware(otelhttp.WithTracerProvider(srv.tracerProvider))
root.Handle("/.well-known/pomerium", traceHandler(handlers.WellKnownPomerium(authenticateURL)))
root.Handle("/.well-known/pomerium/", traceHandler(handlers.WellKnownPomerium(authenticateURL)))
root.Path("/.well-known/pomerium/jwks.json").Methods(http.MethodGet).Handler(traceHandler(handlers.JWKSHandler(signingKey)))
root.Path(urlutil.HPKEPublicKeyPath).Methods(http.MethodGet).Handler(traceHandler(hpke_handlers.HPKEPublicKeyHandler(hpkePublicKey)))
if cfg.Options.IsRuntimeFlagSet(config.RuntimeFlagMCP) {
root.Path("/.well-known/oauth-authorization-server").
Methods(http.MethodGet, http.MethodOptions).
Handler(mcp.AuthorizationServerMetadataHandler(mcp.DefaultPrefix))
}
return nil
}