proxy

package
v0.33.0-rc.4 Latest Latest
Warning

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

Go to latest
Published: Jun 13, 2026 License: MIT Imports: 32 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

View Source
const AuthModeClientCredentials = "client_credentials"

AuthModeClientCredentials is the ClientConfig.AuthMode value for the OAuth2 client_credentials grant (Authentik service-account form).

View Source
const NoAuthToken = "none"

NoAuthToken is the sentinel RegisterToken returns when the proxy needs no bearer token (e.g. auth.mode=none). Callers must not send it as a credential.

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 (
	// EmbeddingRequestsTotal counts OpenRouter embedding API calls.
	EmbeddingRequestsTotal = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Namespace: proxyMetricsNamespace,
			Subsystem: proxyMetricsSubsystem,
			Name:      "embedding_requests_total",
			Help:      "Total number of embedding API calls to the upstream provider",
		},
		[]string{"status"},
	)

	// EmbeddingRequestDurationSeconds measures OpenRouter API call duration.
	EmbeddingRequestDurationSeconds = prometheus.NewHistogram(
		prometheus.HistogramOpts{
			Namespace: proxyMetricsNamespace,
			Subsystem: proxyMetricsSubsystem,
			Name:      "embedding_request_duration_seconds",
			Help:      "Duration of embedding API calls in seconds",
			Buckets:   []float64{0.1, 0.25, 0.5, 1, 2.5, 5, 10, 30, 60, 120},
		},
	)

	// EmbeddingTokensTotal tracks token consumption from the embedding API.
	EmbeddingTokensTotal = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Namespace: proxyMetricsNamespace,
			Subsystem: proxyMetricsSubsystem,
			Name:      "embedding_tokens_total",
			Help:      "Total number of tokens consumed by the embedding API",
		},
		[]string{"type"},
	)

	// EmbeddingCostUSD tracks estimated cost in USD from the embedding API.
	EmbeddingCostUSD = prometheus.NewCounter(
		prometheus.CounterOpts{
			Namespace: proxyMetricsNamespace,
			Subsystem: proxyMetricsSubsystem,
			Name:      "embedding_cost_usd",
			Help:      "Estimated cumulative cost in USD for embedding API calls",
		},
	)

	// EmbeddingItemsTotal counts embedding items by resolution source.
	EmbeddingItemsTotal = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Namespace: proxyMetricsNamespace,
			Subsystem: proxyMetricsSubsystem,
			Name:      "embedding_items_total",
			Help:      "Total embedding items processed, by source",
		},
		[]string{"source"},
	)
)

Embedding 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"`
	// LogRequestBody captures the upstream request payload (e.g. the ClickHouse
	// SQL or other POST body) in the audit entry. The full body is always
	// forwarded upstream; only the audited copy is truncated to MaxBodyBytes.
	// Defaults to true when unset.
	LogRequestBody *bool `yaml:"log_request_body"`
	// LogResponseBody captures the upstream response payload in the audit entry.
	// Response bodies can be large (full result sets), so this is off by default;
	// the audited copy is truncated to MaxBodyBytes.
	LogResponseBody bool `yaml:"log_response_body"`
	// MaxBodyBytes caps how many bytes of each captured body are stored in the
	// audit entry. Zero falls back to defaultMaxAuditBodyBytes.
	MaxBodyBytes int `yaml:"max_body_bytes"`
}

AuditConfig holds audit logging configuration.

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 AuditConfig) *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 AuthConfig

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

	// IssuerURL is the proxy's own issuer URL (mode 'oauth'), advertised to
	// clients for login discovery.
	IssuerURL string `yaml:"issuer_url,omitempty"`

	// ClientID is the client identifier advertised to clients (mode 'oauth').
	ClientID string `yaml:"client_id,omitempty"`

	// Issuers are the trusted external OIDC issuers (mode 'oidc'). A bearer token
	// is accepted if it verifies against ANY of them, letting the proxy trust
	// e.g. humans on one IdP and CI service accounts on another. The first issuer
	// is advertised to clients for interactive login.
	Issuers []OIDCIssuerConfig `yaml:"issuers,omitempty"`

	// GitHub configures the GitHub OAuth app used for user authentication.
	GitHub *auth.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 auth.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 *auth.SuccessPageConfig `yaml:"success_page,omitempty"`
}

AuthConfig holds authentication configuration for the proxy.

type AuthMetadataResponse added in v0.12.0

type AuthMetadataResponse struct {
	Enabled   bool   `json:"enabled"`
	Mode      string `json:"mode"`
	IssuerURL string `json:"issuer_url,omitempty"`
	ClientID  string `json:"client_id,omitempty"`
}

AuthMetadataResponse describes the proxy's auth configuration for client discovery.

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 NewAuthServerAuthenticator added in v0.30.0

func NewAuthServerAuthenticator(svc auth.AuthorizationServer) Authenticator

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)

type Authorizer added in v0.12.0

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

Authorizer enforces per-datasource access control based on GitHub org membership. Rules are built from datasource configs at startup and checked on every request.

func NewAuthorizer added in v0.12.0

func NewAuthorizer(log logrus.FieldLogger, cfg ServerConfig) *Authorizer

NewAuthorizer creates an Authorizer from the server config.

func (*Authorizer) FilterDatasources added in v0.12.0

func (a *Authorizer) FilterDatasources(ctx context.Context, resp DatasourcesResponse) DatasourcesResponse

FilterDatasources returns a copy of the response with only the datasources the authenticated user is allowed to access.

func (*Authorizer) Middleware added in v0.12.0

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

Middleware returns an HTTP middleware that checks datasource access.

type BaseDatasourceConfig added in v0.12.0

type BaseDatasourceConfig struct {
	Name        string   `yaml:"name"`
	Description string   `yaml:"description,omitempty"`
	AllowedOrgs []string `yaml:"allowed_orgs,omitempty"`
}

BaseDatasourceConfig holds fields common to all datasource configurations. Embed this in every datasource config struct to get compile-time enforcement of authorization support via the DatasourceConfig interface.

func (BaseDatasourceConfig) DatasourceAllowedOrgs added in v0.12.0

func (b BaseDatasourceConfig) DatasourceAllowedOrgs() []string

DatasourceAllowedOrgs returns the list of GitHub orgs allowed to access this datasource.

func (BaseDatasourceConfig) DatasourceDescription added in v0.12.0

func (b BaseDatasourceConfig) DatasourceDescription() string

DatasourceDescription returns the datasource description.

func (BaseDatasourceConfig) DatasourceName added in v0.12.0

func (b BaseDatasourceConfig) DatasourceName() string

DatasourceName returns the datasource name.

type BenchmarkoorInstanceConfig

type BenchmarkoorInstanceConfig struct {
	BaseDatasourceConfig `yaml:",inline"`
	URL                  string `yaml:"url"`
	APIKey               string `yaml:"api_key,omitempty"`
	// UIURL is the public benchmarkoor web UI, used to build deep links to
	// runs and suites. The UI host is not derivable from the API URL.
	UIURL string `yaml:"ui_url,omitempty"`
}

BenchmarkoorInstanceConfig holds benchmarkoor API instance configuration. Benchmarkoor is the execution-client benchmarking service; APIKey is a read-only benchmarkoor API key (bmk_...) injected as a Bearer token.

type ClickHouseClusterConfig

type ClickHouseClusterConfig struct {
	BaseDatasourceConfig `yaml:",inline"`
	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"`
	Autodiscover         bool                             `yaml:"autodiscover,omitempty"`
	AutodiscoverInterval time.Duration                    `yaml:"autodiscover_interval,omitempty"`
	Variants             []ClickHouseClusterVariantConfig `yaml:"variants,omitempty"`
	// Contains declares the datasets stored in this cluster. Passed through to
	// discovery verbatim; the proxy never interprets Params or Notes.
	Contains []DatasetBindingConfig `yaml:"contains,omitempty"`
}

ClickHouseClusterConfig holds ClickHouse cluster configuration.

type ClickHouseClusterVariantConfig added in v0.25.0

type ClickHouseClusterVariantConfig struct {
	AllowedOrgs []string `yaml:"allowed_orgs,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"`
}

ClickHouseClusterVariantConfig holds one selectable ClickHouse backend.

type Client

type Client interface {
	Service

	// 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 {
	// Name is the configured proxy identifier used to tag datasource ownership.
	Name string

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

	// AuthMode selects the proxy auth flow. Empty/"oauth"/"oidc" use the
	// interactive flows backed by the on-disk credential store;
	// "client_credentials" mints access tokens on demand with Username and
	// Password (Authentik service-account form) and keeps them in memory only.
	AuthMode string

	// Username is the service-account username for AuthMode "client_credentials".
	Username string

	// Password is the service-account app password for AuthMode "client_credentials".
	Password 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: 60 seconds).
	// Set to 0 to disable background refresh.
	DiscoveryInterval time.Duration

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

	// OnDiscover is invoked after every successful Discover (initial and background).
	// It runs synchronously on the discovery goroutine — keep work short and panic-free.
	// Typical use: re-initialize ProxyDiscoverable modules so newly added datasources
	// surface without a server restart.
	OnDiscover func()
}

ClientConfig configures the proxy client.

func (*ClientConfig) ApplyDefaults

func (c *ClientConfig) ApplyDefaults()

ApplyDefaults sets default values for the client config.

type ClientRoute added in v0.26.0

type ClientRoute struct {
	// Name is the configured proxy identifier.
	Name string
	// Client is the underlying proxy client.
	Client Client
	// Local marks an in-process/local proxy. Local routes are never primary.
	Local bool
}

ClientRoute is one proxy client in a router.

type DatasetBindingConfig added in v0.32.0

type DatasetBindingConfig struct {
	Dataset string            `yaml:"dataset"`
	Params  map[string]string `yaml:"params,omitempty"`
	Notes   string            `yaml:"notes,omitempty"`
}

DatasetBindingConfig declares a dataset stored in a datasource. The dataset name matches a knowledge pack in the release; Params are opaque placement hints interpreted by that pack (e.g. database: default); Notes says what distinguishes this copy from the dataset's other copies — universal query knowledge belongs in the dataset pack, cluster-wide behavior in the datasource description.

type DatasourceConfig added in v0.12.0

type DatasourceConfig interface {
	DatasourceName() string
	DatasourceDescription() string
	DatasourceAllowedOrgs() []string
}

DatasourceConfig is the interface every datasource config must satisfy. The Authorizer uses this to build access rules generically, ensuring that any new datasource type added to the proxy must include authorization support.

type DatasourceOwner added in v0.26.0

type DatasourceOwner struct {
	ProxyName string
	URL       string
}

DatasourceOwner identifies the proxy that owns a datasource.

type DatasourcesResponse

type DatasourcesResponse struct {
	ClickHouseInfo     []types.DatasourceInfo `json:"clickhouse_info,omitempty"`
	PrometheusInfo     []types.DatasourceInfo `json:"prometheus_info,omitempty"`
	LokiInfo           []types.DatasourceInfo `json:"loki_info,omitempty"`
	BenchmarkoorInfo   []types.DatasourceInfo `json:"benchmarkoor_info,omitempty"`
	EthNodeAvailable   bool                   `json:"ethnode_available,omitempty"`
	EmbeddingAvailable bool                   `json:"embedding_available,omitempty"`
	EmbeddingModel     string                 `json:"embedding_model,omitempty"`
}

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

Datasource identity is carried solely by the *Info fields. The wire format additionally emits and accepts a parallel name-only list per type (clickhouse/prometheus/loki) for compatibility with older peers; that list is derived from the *Info fields and never stored separately.

func (DatasourcesResponse) MarshalJSON added in v0.30.0

func (d DatasourcesResponse) MarshalJSON() ([]byte, error)

MarshalJSON emits both the detailed *Info lists and the derived name-only lists so older peers that only read the name lists continue to work.

func (*DatasourcesResponse) UnmarshalJSON added in v0.30.0

func (d *DatasourcesResponse) UnmarshalJSON(data []byte) error

UnmarshalJSON reads the detailed *Info lists when present and otherwise reconstructs them from the name-only lists emitted by older peers.

type EmbedCheckRequest added in v0.14.0

type EmbedCheckRequest struct {
	Model  string   `json:"model"`
	Hashes []string `json:"hashes"`
}

EmbedCheckRequest is the request payload for the /embed/check endpoint.

type EmbedCheckResponse added in v0.14.0

type EmbedCheckResponse struct {
	Cached []EmbedResult `json:"cached"`
}

EmbedCheckResponse is the response from /embed/check.

type EmbedItem added in v0.14.0

type EmbedItem struct {
	Hash string `json:"hash"`
	Text string `json:"text"`
}

EmbedItem is a single item to embed.

type EmbedRequest added in v0.14.0

type EmbedRequest struct {
	Items []EmbedItem `json:"items"`
}

EmbedRequest is the request payload for the /embed endpoint.

type EmbedResponse added in v0.14.0

type EmbedResponse struct {
	Results []EmbedResult `json:"results"`
	Model   string        `json:"model"`
}

EmbedResponse is the response payload from the /embed endpoint.

type EmbedResult added in v0.14.0

type EmbedResult struct {
	Hash   string    `json:"hash"`
	Vector []float32 `json:"vector"`
}

EmbedResult is a single embedding result.

type EmbeddingCacheConfig added in v0.14.0

type EmbeddingCacheConfig struct {
	// Backend is the cache backend: "memory" (default) or "redis".
	Backend string `yaml:"backend,omitempty"`

	// RedisURL is the Redis connection URL (required when backend is "redis").
	RedisURL string `yaml:"redis_url,omitempty"`
}

EmbeddingCacheConfig holds cache configuration for embeddings.

type EmbeddingConfig added in v0.14.0

type EmbeddingConfig struct {
	// APIKey is the API key for the embedding provider (e.g., OpenRouter).
	APIKey string `yaml:"api_key"`

	// Model is the embedding model name (default: "openai/text-embedding-3-small").
	Model string `yaml:"model,omitempty"`

	// APIURL is the base URL of the embedding API (default: "https://openrouter.ai/api/v1").
	APIURL string `yaml:"api_url,omitempty"`

	// Cache holds embedding cache configuration.
	Cache EmbeddingCacheConfig `yaml:"cache"`
}

EmbeddingConfig holds configuration for the remote embedding API.

type EmbeddingService added in v0.14.0

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

EmbeddingService handles embedding requests using a remote API with caching.

func NewEmbeddingService added in v0.14.0

func NewEmbeddingService(
	log logrus.FieldLogger,
	c cache.Cache,
	apiKey, model, apiURL string,
	costPerToken float64,
) *EmbeddingService

NewEmbeddingService creates a new EmbeddingService. If costPerToken is 0, the service fetches pricing from the API's /models endpoint.

func (*EmbeddingService) CheckCached added in v0.14.0

func (s *EmbeddingService) CheckCached(ctx context.Context, hashes []string) ([]EmbedResult, error)

CheckCached returns cached vectors for the given hashes. Only hashes that exist in the cache are returned.

func (*EmbeddingService) Close added in v0.14.0

func (s *EmbeddingService) Close() error

Close releases resources held by the embedding service.

func (*EmbeddingService) Embed added in v0.14.0

func (s *EmbeddingService) Embed(ctx context.Context, items []EmbedItem) (*EmbedResponse, error)

Embed computes embeddings for the given items, using the cache where possible. Uncached items are sent to the upstream API in sub-batches of maxEmbedBatchSize.

func (*EmbeddingService) Model added in v0.14.0

func (s *EmbeddingService) Model() string

Model returns the configured embedding model name.

type EthNodeInstanceConfig

type EthNodeInstanceConfig struct {
	BaseDatasourceConfig `yaml:",inline"`
	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 GitHubAPIConfig added in v0.22.0

type GitHubAPIConfig struct {
	// Token is a GitHub personal access token or app token with actions:write permission.
	Token string `yaml:"token"`
}

GitHubAPIConfig holds GitHub API configuration for the proxy.

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 {
	BaseDatasourceConfig `yaml:",inline"`
	URL                  string                      `yaml:"url"`
	Username             string                      `yaml:"username,omitempty"`
	Password             string                      `yaml:"password,omitempty"`
	Variants             []LokiInstanceVariantConfig `yaml:"variants,omitempty"`
}

LokiInstanceConfig holds Loki instance configuration.

type LokiInstanceVariantConfig added in v0.25.0

type LokiInstanceVariantConfig struct {
	AllowedOrgs []string `yaml:"allowed_orgs,omitempty"`
	URL         string   `yaml:"url"`
	Username    string   `yaml:"username,omitempty"`
	Password    string   `yaml:"password,omitempty"`
}

LokiInstanceVariantConfig holds one selectable Loki backend.

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 {
	Issuers []OIDCIssuerConfig
}

OIDCAuthenticatorConfig configures the external OIDC authenticator. A token is accepted if it verifies against ANY configured issuer, which lets the proxy trust (for example) humans on one IdP and machine identities on another simultaneously. At least one issuer is required.

type OIDCIssuerConfig added in v0.28.0

type OIDCIssuerConfig struct {
	IssuerURL string `yaml:"issuer_url"`
	ClientID  string `yaml:"client_id"`
}

OIDCIssuerConfig identifies a trusted OIDC issuer and the audience (client ID) expected in the tokens it issues.

type PrometheusInstanceConfig

type PrometheusInstanceConfig struct {
	BaseDatasourceConfig `yaml:",inline"`
	URL                  string                            `yaml:"url"`
	Username             string                            `yaml:"username,omitempty"`
	Password             string                            `yaml:"password,omitempty"`
	Variants             []PrometheusInstanceVariantConfig `yaml:"variants,omitempty"`
}

PrometheusInstanceConfig holds Prometheus instance configuration.

type PrometheusInstanceVariantConfig added in v0.25.0

type PrometheusInstanceVariantConfig struct {
	AllowedOrgs []string `yaml:"allowed_orgs,omitempty"`
	URL         string   `yaml:"url"`
	Username    string   `yaml:"username,omitempty"`
	Password    string   `yaml:"password,omitempty"`
}

PrometheusInstanceVariantConfig holds one selectable Prometheus backend.

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 Router added in v0.26.0

type Router interface {
	Client

	// Primary returns the first external proxy client. It is nil when only
	// local clients are configured.
	Primary() Client

	// OwnerForDatasource returns the proxy that owns a datasource by type/name.
	OwnerForDatasource(datasourceType, datasourceName string) (DatasourceOwner, bool)

	// ClientForDatasource returns the proxy client that owns a datasource by type/name.
	ClientForDatasource(datasourceType, datasourceName string) (Client, bool)
}

Router is a proxy client that can resolve datasource ownership across multiple underlying proxy clients.

func NewRouter added in v0.26.0

func NewRouter(log logrus.FieldLogger, routes []ClientRoute) Router

NewRouter creates a multi-proxy router.

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

	// Benchmarkoor holds benchmarkoor API instance configurations.
	Benchmarkoor []BenchmarkoorInstanceConfig `yaml:"benchmarkoor,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"`

	// Embedding holds optional embedding API configuration.
	Embedding *EmbeddingConfig `yaml:"embedding,omitempty"`

	// GitHub holds optional GitHub API configuration for triggering workflows.
	GitHub *GitHubAPIConfig `yaml:"github,omitempty"`
}

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

func (c *ServerConfig) ToBenchmarkoorHandlerConfigs() []handlers.BenchmarkoorConfig

ToBenchmarkoorHandlerConfigs converts the benchmarkoor instance configs to handler configs.

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, or NoAuthToken when no bearer token is required.
	RegisterToken() string

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

	// ClickHouseDatasources returns the list of ClickHouse datasource names.
	ClickHouseDatasources() []string
	// ClickHouseDatasourceInfo returns detailed ClickHouse datasource info.
	ClickHouseDatasourceInfo() []types.DatasourceInfo
	// ClickHouseQuery runs a ClickHouse SQL query against the named datasource
	// through the proxy and returns the raw response body. The params are
	// appended to the query string (e.g. default_format, param_* bindings).
	// A non-2xx response from the proxy is returned as an error containing the
	// status code and the response body.
	ClickHouseQuery(ctx context.Context, datasource, sql string, params url.Values) ([]byte, error)

	// PrometheusDatasourceInfo returns detailed Prometheus datasource info.
	PrometheusDatasourceInfo() []types.DatasourceInfo

	// LokiDatasourceInfo returns detailed Loki datasource info.
	LokiDatasourceInfo() []types.DatasourceInfo

	// BenchmarkoorDatasourceInfo returns detailed benchmarkoor datasource info.
	BenchmarkoorDatasourceInfo() []types.DatasourceInfo

	// EthNodeAvailable returns true if ethnode proxy access is configured.
	EthNodeAvailable() bool
	// EthNodeDatasourceInfo returns the ethnode datasource info when ethnode
	// access is configured, or nil otherwise. Ethnode is exposed as a single
	// type-level datasource rather than a discoverable list.
	EthNodeDatasourceInfo() []types.DatasourceInfo

	// EmbeddingAvailable returns true if the proxy has embedding configured.
	EmbeddingAvailable() bool
	// EmbeddingModel returns the configured embedding model name.
	EmbeddingModel() string
}

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