proxy

package
v0.11.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 16, 2026 License: MIT Imports: 26 Imported by: 0

Documentation

Overview

Package proxy provides the credential proxy for server-side upstream access. The proxy holds datasource credentials and serves raw credentialed routes.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ProxyRequestsTotal counts proxy requests by datasource, method, and status.
	ProxyRequestsTotal = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Namespace: proxyMetricsNamespace,
			Subsystem: proxyMetricsSubsystem,
			Name:      "requests_total",
			Help:      "Total number of proxy requests",
		},
		[]string{"datasource_type", "datasource", "method", "status_code"},
	)

	// ProxyRequestDurationSeconds measures proxy request duration.
	ProxyRequestDurationSeconds = prometheus.NewHistogramVec(
		prometheus.HistogramOpts{
			Namespace: proxyMetricsNamespace,
			Subsystem: proxyMetricsSubsystem,
			Name:      "request_duration_seconds",
			Help:      "Duration of proxy requests in seconds",
			Buckets:   []float64{0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, 30, 60, 120, 300},
		},
		[]string{"datasource_type", "datasource", "method"},
	)

	// ProxyResponseSizeBytes measures proxy response sizes.
	ProxyResponseSizeBytes = prometheus.NewHistogramVec(
		prometheus.HistogramOpts{
			Namespace: proxyMetricsNamespace,
			Subsystem: proxyMetricsSubsystem,
			Name:      "response_size_bytes",
			Help:      "Size of proxy responses in bytes",
			Buckets:   prometheus.ExponentialBuckets(100, 10, 8),
		},
		[]string{"datasource_type"},
	)

	// ProxyActiveRequests tracks currently in-flight requests.
	ProxyActiveRequests = prometheus.NewGaugeVec(
		prometheus.GaugeOpts{
			Namespace: proxyMetricsNamespace,
			Subsystem: proxyMetricsSubsystem,
			Name:      "active_requests",
			Help:      "Number of currently active proxy requests",
		},
		[]string{"datasource_type"},
	)

	// ProxyRateLimitRejectionsTotal counts rate limit rejections.
	ProxyRateLimitRejectionsTotal = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Namespace: proxyMetricsNamespace,
			Subsystem: proxyMetricsSubsystem,
			Name:      "rate_limit_rejections_total",
			Help:      "Total number of rate limit rejections",
		},
		[]string{"datasource_type"},
	)
)

Request metrics.

View Source
var ErrAuthenticationRequired = errors.New("proxy authentication required")

Functions

func GetUserID

func GetUserID(ctx context.Context) string

GetUserID extracts the authenticated user ID from the request context.

Types

type AuditConfig

type AuditConfig struct {
	// Enabled controls whether audit logging is active.
	Enabled bool `yaml:"enabled"`
}

AuditConfig holds audit logging configuration.

type AuditEntry

type AuditEntry struct {
	Subject        string   `json:"subject,omitempty"`
	Username       string   `json:"username,omitempty"`
	Groups         []string `json:"groups,omitempty"`
	Method         string   `json:"method"`
	Path           string   `json:"path"`
	DatasourceType string   `json:"datasource_type"`
	DatasourceName string   `json:"datasource_name,omitempty"`
	StatusCode     int      `json:"status_code"`
	ResponseBytes  int      `json:"response_bytes"`
	Duration       string   `json:"duration"`
	UserAgent      string   `json:"user_agent,omitempty"`
}

AuditEntry represents a single audit log entry.

type Auditor

type Auditor struct {
	// contains filtered or unexported fields
}

Auditor logs audit entries for proxy requests.

func NewAuditor

func NewAuditor(log logrus.FieldLogger, cfg AuditorConfig) *Auditor

NewAuditor creates a new auditor.

func (*Auditor) Middleware

func (a *Auditor) Middleware() func(http.Handler) http.Handler

Middleware returns an HTTP middleware that logs audit entries.

type AuditorConfig

type AuditorConfig struct{}

AuditorConfig configures the auditor.

type AuthConfig

type AuthConfig struct {
	// Mode is the authentication mode.
	Mode AuthMode `yaml:"mode"`

	// IssuerURL is the external URL clients should use for auth and token validation.
	IssuerURL string `yaml:"issuer_url,omitempty"`

	// ClientID is the OIDC client identifier expected in bearer token audiences.
	ClientID string `yaml:"client_id,omitempty"`

	// GitHub configures the GitHub OAuth app used for user authentication.
	GitHub *simpleauth.GitHubConfig `yaml:"github,omitempty"`

	// AllowedOrgs restricts access to members of these GitHub orgs.
	AllowedOrgs []string `yaml:"allowed_orgs,omitempty"`

	// Tokens configures proxy-issued bearer tokens.
	Tokens simpleauth.TokensConfig `yaml:"tokens"`

	// AccessTokenTTL is the lifetime of proxy-issued access tokens.
	AccessTokenTTL time.Duration `yaml:"access_token_ttl,omitempty"`

	// RefreshTokenTTL is the lifetime of proxy-issued refresh tokens.
	RefreshTokenTTL time.Duration `yaml:"refresh_token_ttl,omitempty"`

	// SuccessPage customizes the OAuth callback success page shown in the browser.
	SuccessPage *simpleauth.SuccessPageConfig `yaml:"success_page,omitempty"`
}

AuthConfig holds authentication configuration for the proxy.

type AuthMode

type AuthMode string

AuthMode determines how the proxy authenticates requests.

const (
	// AuthModeNone disables authentication (for local development only).
	AuthModeNone AuthMode = "none"

	// AuthModeOAuth enables the embedded GitHub-backed OAuth server on the proxy control plane
	// and validates proxy-issued bearer tokens on data-plane routes.
	AuthModeOAuth AuthMode = "oauth"

	// AuthModeOIDC validates bearer tokens from an external OpenID Connect issuer.
	AuthModeOIDC AuthMode = "oidc"
)

type AuthUser added in v0.11.0

type AuthUser struct {
	Subject  string
	Username string
	Groups   []string
}

AuthUser represents the authenticated identity for proxy requests.

func GetAuthUser added in v0.11.0

func GetAuthUser(ctx context.Context) *AuthUser

GetAuthUser returns the authenticated proxy user from the request context.

type Authenticator

type Authenticator interface {
	// Middleware returns an HTTP middleware that authenticates requests.
	Middleware() func(http.Handler) http.Handler

	// Start starts any background processes.
	Start(ctx context.Context) error

	// Stop stops any background processes.
	Stop() error
}

Authenticator validates incoming requests to the proxy.

func NewNoneAuthenticator

func NewNoneAuthenticator(log logrus.FieldLogger) Authenticator

NewNoneAuthenticator creates an authenticator that allows all requests.

func NewOIDCAuthenticator added in v0.11.0

func NewOIDCAuthenticator(log logrus.FieldLogger, cfg OIDCAuthenticatorConfig) (Authenticator, error)

func NewSimpleServiceAuthenticator

func NewSimpleServiceAuthenticator(svc simpleauth.SimpleService) Authenticator

type ClickHouseClusterConfig

type ClickHouseClusterConfig struct {
	Name        string `yaml:"name"`
	Description string `yaml:"description,omitempty"`
	Host        string `yaml:"host"`
	Port        int    `yaml:"port"`
	Database    string `yaml:"database,omitempty"`
	Username    string `yaml:"username"`
	Password    string `yaml:"password"`
	Secure      bool   `yaml:"secure"`
	SkipVerify  bool   `yaml:"skip_verify,omitempty"`
	Timeout     int    `yaml:"timeout,omitempty"`
}

ClickHouseClusterConfig holds ClickHouse cluster configuration.

type Client

type Client interface {
	// Start starts the client and performs initial discovery.
	Start(ctx context.Context) error

	// Stop stops the client.
	Stop(ctx context.Context) error

	// URL returns the proxy URL.
	URL() string

	// RegisterToken returns the current proxy access token for server-to-proxy calls.
	RegisterToken(executionID string) string

	// RevokeToken is a no-op for client-managed bearer tokens.
	RevokeToken(executionID string)

	// ClickHouseDatasources returns the discovered ClickHouse datasource names.
	ClickHouseDatasources() []string
	// ClickHouseDatasourceInfo returns detailed ClickHouse datasource info.
	ClickHouseDatasourceInfo() []types.DatasourceInfo

	// PrometheusDatasources returns the discovered Prometheus datasource names.
	PrometheusDatasources() []string
	// PrometheusDatasourceInfo returns detailed Prometheus datasource info.
	PrometheusDatasourceInfo() []types.DatasourceInfo

	// LokiDatasources returns the discovered Loki datasource names.
	LokiDatasources() []string
	// LokiDatasourceInfo returns detailed Loki datasource info.
	LokiDatasourceInfo() []types.DatasourceInfo

	// EthNodeAvailable returns true if the proxy has ethnode credentials configured.
	EthNodeAvailable() bool

	// Discover fetches datasource information from the proxy.
	Discover(ctx context.Context) error

	// EnsureAuthenticated checks if the user has valid credentials.
	EnsureAuthenticated(ctx context.Context) error
}

Client connects to a proxy server and provides datasource discovery plus proxy-scoped bearer tokens for server-to-proxy calls.

func NewClient

func NewClient(log logrus.FieldLogger, cfg ClientConfig) Client

NewClient creates a new proxy client.

type ClientConfig

type ClientConfig struct {
	// URL is the base URL of the proxy server (e.g., http://localhost:18081).
	URL string

	// IssuerURL is the OAuth issuer URL for proxy authentication.
	// If empty, URL is used and the client will only work against auth.mode=none proxies.
	IssuerURL string

	// ClientID is the OAuth client ID for authentication.
	ClientID string

	// Resource is the OAuth protected resource to request tokens for.
	// Leave empty for standard OIDC providers that do not use RFC 8707 resource parameters.
	Resource string

	// RefreshTokenTTL is the expected lifetime of the refresh token.
	// When set, the credential store will refresh at 50% of this duration
	// to keep the refresh token alive via provider rotation.
	RefreshTokenTTL time.Duration

	// DiscoveryInterval is how often to refresh datasource info (default: 5 minutes).
	// Set to 0 to disable background refresh.
	DiscoveryInterval time.Duration

	// HTTPTimeout is the timeout for HTTP requests (default: 30 seconds).
	HTTPTimeout time.Duration
}

ClientConfig configures the proxy client.

func (*ClientConfig) ApplyDefaults

func (c *ClientConfig) ApplyDefaults()

ApplyDefaults sets default values for the client config.

type DatasourcesResponse

type DatasourcesResponse struct {
	ClickHouse       []string               `json:"clickhouse,omitempty"`
	Prometheus       []string               `json:"prometheus,omitempty"`
	Loki             []string               `json:"loki,omitempty"`
	ClickHouseInfo   []types.DatasourceInfo `json:"clickhouse_info,omitempty"`
	PrometheusInfo   []types.DatasourceInfo `json:"prometheus_info,omitempty"`
	LokiInfo         []types.DatasourceInfo `json:"loki_info,omitempty"`
	EthNodeAvailable bool                   `json:"ethnode_available,omitempty"`
}

DatasourcesResponse is the response from the /datasources endpoint. This is used by the MCP server client to discover available datasources.

type EthNodeInstanceConfig

type EthNodeInstanceConfig struct {
	Username string `yaml:"username"`
	Password string `yaml:"password"`
}

EthNodeInstanceConfig holds Ethereum node API access configuration. A single credential pair is used for all beacon and execution node endpoints.

type HTTPServerConfig

type HTTPServerConfig struct {
	// ListenAddr is the address to listen on (default: ":18081").
	ListenAddr string `yaml:"listen_addr,omitempty"`

	// ReadTimeout is the maximum duration for reading the entire request.
	ReadTimeout time.Duration `yaml:"read_timeout,omitempty"`

	// WriteTimeout is the maximum duration before timing out writes of the response.
	WriteTimeout time.Duration `yaml:"write_timeout,omitempty"`

	// IdleTimeout is the maximum amount of time to wait for the next request.
	IdleTimeout time.Duration `yaml:"idle_timeout,omitempty"`
}

HTTPServerConfig holds HTTP server configuration.

type LokiInstanceConfig

type LokiInstanceConfig struct {
	Name        string `yaml:"name"`
	Description string `yaml:"description,omitempty"`
	URL         string `yaml:"url"`
	Username    string `yaml:"username,omitempty"`
	Password    string `yaml:"password,omitempty"`
}

LokiInstanceConfig holds Loki instance configuration.

type MetricsConfig

type MetricsConfig struct {
	// Enabled controls whether the Prometheus metrics server is active.
	Enabled bool `yaml:"enabled"`

	// ListenAddr is the address to serve the /metrics endpoint on.
	ListenAddr string `yaml:"listen_addr,omitempty"`

	// Port is the port to serve the /metrics endpoint on (default: 9090).
	Port int `yaml:"port,omitempty"`
}

MetricsConfig holds Prometheus metrics configuration for the proxy.

type OIDCAuthenticatorConfig added in v0.11.0

type OIDCAuthenticatorConfig struct {
	IssuerURL string
	ClientID  string
}

type PrometheusInstanceConfig

type PrometheusInstanceConfig struct {
	Name        string `yaml:"name"`
	Description string `yaml:"description,omitempty"`
	URL         string `yaml:"url"`
	Username    string `yaml:"username,omitempty"`
	Password    string `yaml:"password,omitempty"`
}

PrometheusInstanceConfig holds Prometheus instance configuration.

type RateLimitConfig

type RateLimitConfig struct {
	// Enabled controls whether rate limiting is active.
	Enabled bool `yaml:"enabled"`

	// RequestsPerMinute is the maximum requests per minute per user.
	RequestsPerMinute int `yaml:"requests_per_minute,omitempty"`

	// BurstSize is the maximum burst size.
	BurstSize int `yaml:"burst_size,omitempty"`
}

RateLimitConfig holds rate limiting configuration.

type RateLimiter

type RateLimiter struct {
	// contains filtered or unexported fields
}

RateLimiter provides per-user rate limiting for the proxy.

func NewRateLimiter

func NewRateLimiter(log logrus.FieldLogger, cfg RateLimiterConfig) *RateLimiter

NewRateLimiter creates a new rate limiter.

func (*RateLimiter) Allow

func (rl *RateLimiter) Allow(userID string) bool

Allow checks if a request is allowed for the given user ID.

func (*RateLimiter) Middleware

func (rl *RateLimiter) Middleware() func(http.Handler) http.Handler

Middleware returns an HTTP middleware that enforces rate limiting.

func (*RateLimiter) Stop

func (rl *RateLimiter) Stop()

Stop stops the rate limiter cleanup goroutine.

type RateLimiterConfig

type RateLimiterConfig struct {
	// RequestsPerMinute is the maximum requests per minute per user.
	RequestsPerMinute int

	// BurstSize is the maximum burst size.
	BurstSize int
}

RateLimiterConfig configures the rate limiter.

type Server

type Server interface {
	// Start starts the proxy server.
	Start(ctx context.Context) error

	// Stop stops the proxy server.
	Stop(ctx context.Context) error

	// URL returns the proxy URL.
	URL() string

	// ClickHouseDatasources returns the list of ClickHouse datasource names.
	ClickHouseDatasources() []string

	// PrometheusDatasources returns the list of Prometheus datasource names.
	PrometheusDatasources() []string

	// LokiDatasources returns the list of Loki datasource names.
	LokiDatasources() []string
}

Server is the credential proxy server interface. This is the standalone proxy server that runs separately from the MCP server.

func NewServer

func NewServer(log logrus.FieldLogger, cfg ServerConfig) (Server, error)

NewServer creates a new proxy server.

type ServerConfig

type ServerConfig struct {
	// Server holds HTTP server configuration.
	Server HTTPServerConfig `yaml:"server"`

	// Auth holds authentication configuration.
	Auth AuthConfig `yaml:"auth"`

	// ClickHouse holds ClickHouse cluster configurations.
	ClickHouse []ClickHouseClusterConfig `yaml:"clickhouse,omitempty"`

	// Prometheus holds Prometheus instance configurations.
	Prometheus []PrometheusInstanceConfig `yaml:"prometheus,omitempty"`

	// Loki holds Loki instance configurations.
	Loki []LokiInstanceConfig `yaml:"loki,omitempty"`

	// EthNode holds Ethereum node API access configuration.
	EthNode *EthNodeInstanceConfig `yaml:"ethnode,omitempty"`

	// RateLimiting holds rate limiting configuration.
	RateLimiting RateLimitConfig `yaml:"rate_limiting"`

	// Audit holds audit logging configuration.
	Audit AuditConfig `yaml:"audit"`

	// Metrics holds Prometheus metrics configuration.
	Metrics MetricsConfig `yaml:"metrics"`
}

ServerConfig is the configuration for the proxy server. This is the single configuration schema used for both local and K8s deployments.

func LoadServerConfig

func LoadServerConfig(path string) (*ServerConfig, error)

LoadServerConfig loads a proxy server config from a YAML file.

func (*ServerConfig) ApplyDefaults

func (c *ServerConfig) ApplyDefaults()

ApplyDefaults sets default values for the server config.

func (*ServerConfig) ToHandlerConfigs

ToHandlerConfigs converts the server config to handler configs.

func (*ServerConfig) Validate

func (c *ServerConfig) Validate() error

Validate validates the server config.

type Service

type Service interface {
	// Start starts the service.
	Start(ctx context.Context) error

	// Stop stops the service.
	Stop(ctx context.Context) error

	// URL returns the proxy URL.
	URL() string

	// RegisterToken returns the current access token for server-to-proxy requests.
	RegisterToken(executionID string) string

	// RevokeToken is a no-op for client-managed bearer tokens.
	RevokeToken(executionID string)

	// ClickHouseDatasources returns the list of ClickHouse datasource names.
	ClickHouseDatasources() []string
	// ClickHouseDatasourceInfo returns detailed ClickHouse datasource info.
	ClickHouseDatasourceInfo() []types.DatasourceInfo

	// PrometheusDatasources returns the list of Prometheus datasource names.
	PrometheusDatasources() []string
	// PrometheusDatasourceInfo returns detailed Prometheus datasource info.
	PrometheusDatasourceInfo() []types.DatasourceInfo

	// LokiDatasources returns the list of Loki datasource names.
	LokiDatasources() []string
	// LokiDatasourceInfo returns detailed Loki datasource info.
	LokiDatasourceInfo() []types.DatasourceInfo

	// EthNodeAvailable returns true if ethnode proxy access is configured.
	EthNodeAvailable() bool
}

Service is the credential proxy service interface. This is implemented by both Client (for connecting to a proxy) and directly by the proxy Server.

Directories

Path Synopsis
Package handlers provides reverse proxy handlers for each datasource type.
Package handlers provides reverse proxy handlers for each datasource type.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL