proxy

package
v0.10.0 Latest Latest
Warning

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

Go to latest
Published: Mar 13, 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 user, org, datasource, method, and status.
	ProxyRequestsTotal = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Namespace: proxyMetricsNamespace,
			Subsystem: proxyMetricsSubsystem,
			Name:      "requests_total",
			Help:      "Total number of proxy requests",
		},
		[]string{"user", "org", "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{"user", "org", "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{"user", "org", "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{"user", "org", "datasource_type"},
	)

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

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"`

	// LogQueries controls whether to log query content.
	LogQueries bool `yaml:"log_queries,omitempty"`

	// MaxQueryLength is the maximum length of query to log.
	MaxQueryLength int `yaml:"max_query_length,omitempty"`
}

AuditConfig holds audit logging configuration.

type AuditEntry

type AuditEntry struct {
	GitHubLogin    string   `json:"github_login"`
	GitHubID       int64    `json:"github_id"`
	Orgs           []string `json:"orgs,omitempty"`
	Method         string   `json:"method"`
	Path           string   `json:"path"`
	DatasourceType string   `json:"datasource_type"`
	DatasourceName string   `json:"datasource_name,omitempty"`
	Query          string   `json:"query,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 {
	// LogQueries controls whether to log query content.
	LogQueries bool

	// MaxQueryLength is the maximum length of query to log.
	MaxQueryLength int
}

AuditorConfig configures the auditor.

type AuthConfig

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

	// 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"`

	// 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 GitHub-backed OAuth on the proxy control plane and
	// validates proxy-issued bearer tokens on data-plane routes.
	AuthModeOAuth AuthMode = "oauth"
)

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 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

	// S3Bucket returns the discovered S3 bucket name.
	S3Bucket() string

	// S3PublicURLPrefix returns the discovered S3 public URL prefix.
	S3PublicURLPrefix() string

	// 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.
	// Defaults to URL when omitted.
	Resource string

	// 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"`
	S3Bucket          string                 `json:"s3_bucket,omitempty"`
	S3PublicURLPrefix string                 `json:"s3_public_url_prefix,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"`

	// 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 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 S3Config

type S3Config struct {
	Endpoint        string `yaml:"endpoint"`
	AccessKey       string `yaml:"access_key"`
	SecretKey       string `yaml:"secret_key"`
	Bucket          string `yaml:"bucket"`
	Region          string `yaml:"region,omitempty"`
	PublicURLPrefix string `yaml:"public_url_prefix,omitempty"`
}

S3Config holds S3 storage configuration.

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

	// S3Bucket returns the configured S3 bucket name.
	S3Bucket() 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"`

	// S3 holds S3 storage configuration.
	S3 *S3Config `yaml:"s3,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

	// S3Bucket returns the configured S3 bucket name.
	S3Bucket() string

	// S3PublicURLPrefix returns the public URL prefix for S3 objects.
	S3PublicURLPrefix() string

	// 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