Documentation
¶
Overview ¶
Package teleport provides a Teleport Client Provider for accessing MCP servers on private installations that are only reachable via Teleport Application Access.
Overview ¶
Private installations are deployed in networks without public endpoints and can only be accessed through Teleport Application Access. This package provides the HTTP client infrastructure that uses Teleport Machine ID certificates (tbot) to authenticate and connect to these private MCP servers.
The core principle is: OAuth for identity, Teleport for access. User identity remains managed through OAuth/Dex, while Teleport provides the network-level access to private endpoints.
Architecture ¶
The package follows the API service locator pattern used throughout muster. It provides:
- ClientProvider: Creates HTTP clients configured with Teleport TLS certificates
- CertWatcher: Monitors certificate files for changes and triggers reload
- API Adapter: Integrates with the muster API service locator
Certificate Management ¶
Teleport Machine ID (tbot) outputs identity files that are used to authenticate:
- tls.crt: Client certificate
- tls.key: Client private key
- ca.crt: Teleport CA certificate for trust
In Kubernetes mode, these files are mounted from a Secret. In filesystem mode, they can be read directly from the tbot output directory.
The CertWatcher component monitors these files for changes (when tbot renews certificates) and gracefully refreshes the HTTP client without connection interruption.
Usage ¶
MCPServers can be configured to use Teleport authentication:
apiVersion: muster.giantswarm.io/v1alpha1
kind: MCPServer
metadata:
name: remote-mcp-kubernetes
spec:
type: streamable-http
url: https://mcp-kubernetes.teleport.example.com/mcp
auth:
type: teleport
teleport:
identitySecretName: tbot-identity-output
appName: mcp-kubernetes
Integration Points ¶
- MCPServer Controller: Detects auth.type: teleport and configures the HTTP client
- API Package: TeleportClientProvider registered as a handler
- Aggregator: Uses Teleport-configured HTTP client for protected servers
Security Considerations ¶
- Teleport identity files contain sensitive private keys
- In Kubernetes, files are mounted from Secrets with appropriate RBAC
- Certificate rotation is managed by tbot; this package only reloads
- OAuth tokens continue to provide user identity for authorization
Index ¶
- Constants
- Variables
- func ValidateAppName(appName string) error
- func ValidateIdentityDir(identityDir string) (string, error)
- func ValidateNamespace(namespace string) error
- func ValidateSecretName(name string) error
- type Adapter
- func (a *Adapter) Close() error
- func (a *Adapter) GetClientProvider(identityDir string) (*ClientProvider, error)
- func (a *Adapter) GetHTTPClientForConfig(ctx context.Context, config api.TeleportClientConfig) (*http.Client, error)
- func (a *Adapter) GetHTTPClientForIdentity(identityDir string) (*http.Client, error)
- func (a *Adapter) GetHTTPTransportForIdentity(identityDir string) (*http.Transport, error)
- func (a *Adapter) GetProviderStatus(identityDir string) (*CertStatus, error)
- func (a *Adapter) ListProviders() []string
- func (a *Adapter) Register()
- func (a *Adapter) ReloadProvider(identityDir string) error
- func (a *Adapter) RemoveProvider(identityDir string) error
- type CertReloadCallback
- type CertStatus
- type CertWatcher
- type CertWatcherConfig
- type CertificateData
- type ClientProvider
- func (p *ClientProvider) Close() error
- func (p *ClientProvider) GetHTTPClient() (*http.Client, error)
- func (p *ClientProvider) GetHTTPTransport() (*http.Transport, error)
- func (p *ClientProvider) GetStatus() CertStatus
- func (p *ClientProvider) GetTLSConfig() (*tls.Config, error)
- func (p *ClientProvider) IsExpiringSoon(threshold time.Duration) bool
- func (p *ClientProvider) IsLoaded() bool
- func (p *ClientProvider) OnReload(callback CertReloadCallback)
- func (p *ClientProvider) Reload() error
- func (p *ClientProvider) StartWatching() error
- func (p *ClientProvider) StopWatching() error
- type HTTPClientProvider
- type TeleportConfig
Constants ¶
const DefaultCAFile = "teleport-application-ca.pem"
DefaultCAFile is the default filename for the CA certificate. This matches tbot's application output type which produces "teleport-application-ca.pem".
const DefaultCertFile = "tlscert"
DefaultCertFile is the default filename for the client certificate. This matches tbot's application output type which produces "tlscert".
const DefaultDebounceInterval = 500 * time.Millisecond
DefaultDebounceInterval is the time to wait before triggering a reload after the last file change is detected.
const DefaultKeyFile = "key"
DefaultKeyFile is the default filename for the client private key. This matches tbot's application output type which produces "key".
const DefaultWatchInterval = 30 * time.Second
DefaultWatchInterval is the default interval for checking certificate changes.
const MaxAppNameLength = 253 // DNS subdomain max length
MaxAppNameLength is the maximum allowed length for app names.
const MaxSecretNameLength = 253
MaxSecretNameLength is the maximum length for Kubernetes resource names.
Variables ¶
var AllowedNamespaces = []string{
"teleport-system",
"muster-system",
}
AllowedNamespaces defines the namespaces from which Teleport identity secrets can be loaded. This provides defense-in-depth against misconfiguration. An empty list means all namespaces are allowed (default for backward compatibility).
Functions ¶
func ValidateAppName ¶
ValidateAppName validates a Teleport application name to ensure it's safe for use in HTTP Host headers.
Valid app names:
- Start with alphanumeric character
- Contain only alphanumeric, hyphens, underscores, and dots
- Maximum 253 characters (DNS subdomain limit)
Returns an error if the app name is invalid.
func ValidateIdentityDir ¶
ValidateIdentityDir validates and sanitizes an identity directory path.
Security checks:
- Must be an absolute path
- Cannot contain path traversal sequences (..)
- Cleaned and normalized
Returns the cleaned path or an error if validation fails.
func ValidateNamespace ¶
ValidateNamespace validates a Kubernetes namespace for secret access.
If AllowedNamespaces is empty, all namespaces are allowed. Otherwise, the namespace must be in the allowed list.
Special case: if the namespace matches the MCPServer's own namespace, it's always allowed (use ValidateNamespaceWithOwner for this).
func ValidateSecretName ¶
ValidateSecretName validates a Kubernetes secret name.
Types ¶
type Adapter ¶
type Adapter struct {
// contains filtered or unexported fields
}
Adapter implements api.TeleportClientHandler to provide Teleport HTTP client functionality through the API service locator pattern.
The adapter manages a registry of ClientProviders, one per identity configuration, allowing multiple MCP servers to use different Teleport identities if needed.
func NewAdapterWithClient ¶
NewAdapterWithClient creates a new adapter with a Kubernetes client. This enables loading certificates from Kubernetes secrets.
func (*Adapter) Close ¶
Close stops all providers and releases resources. If multiple errors occur during cleanup, they are aggregated using errors.Join.
func (*Adapter) GetClientProvider ¶
func (a *Adapter) GetClientProvider(identityDir string) (*ClientProvider, error)
GetClientProvider returns the ClientProvider for an identity directory. This allows direct access to the provider for advanced use cases.
func (*Adapter) GetHTTPClientForConfig ¶
func (a *Adapter) GetHTTPClientForConfig(ctx context.Context, config api.TeleportClientConfig) (*http.Client, error)
GetHTTPClientForConfig returns an HTTP client based on TeleportClientConfig. This method supports both filesystem identity directories and Kubernetes secrets.
When IdentitySecretName is specified, certificates are loaded from the Kubernetes secret. Otherwise, certificates are loaded from IdentityDir.
If AppName is specified, the returned client will have a custom transport that sets the appropriate Host header for Teleport application routing.
Security validations performed:
- AppName is validated to prevent header injection
- IdentityDir is validated to prevent path traversal
- Secret namespace is validated against allowed list
func (*Adapter) GetHTTPClientForIdentity ¶
GetHTTPClientForIdentity returns an HTTP client configured with Teleport certificates for the specified identity directory.
This method is thread-safe and will create a new ClientProvider if one doesn't already exist for the given identity directory.
func (*Adapter) GetHTTPTransportForIdentity ¶
GetHTTPTransportForIdentity returns an HTTP transport configured with Teleport certificates.
func (*Adapter) GetProviderStatus ¶
func (a *Adapter) GetProviderStatus(identityDir string) (*CertStatus, error)
GetProviderStatus returns the certificate status for an identity directory.
func (*Adapter) ListProviders ¶
ListProviders returns a list of all registered identity directories.
func (*Adapter) Register ¶
func (a *Adapter) Register()
Register registers the adapter with the API service locator.
func (*Adapter) ReloadProvider ¶
ReloadProvider forces a certificate reload for the specified identity.
func (*Adapter) RemoveProvider ¶
RemoveProvider stops and removes a provider for the specified identity.
type CertReloadCallback ¶
CertReloadCallback is a function called when certificates are reloaded. It receives the new TLS config and any error that occurred during reload.
type CertStatus ¶
type CertStatus struct {
// Loaded indicates whether certificates are successfully loaded.
Loaded bool
// CertPath is the full path to the client certificate file.
CertPath string
// KeyPath is the full path to the client private key file.
KeyPath string
// CAPath is the full path to the CA certificate file.
CAPath string
// LastLoaded is when the certificates were last successfully loaded.
LastLoaded time.Time
// LastError is the most recent error, if any.
LastError error
// ExpiresAt is when the client certificate expires (if parseable).
ExpiresAt *time.Time
}
CertStatus represents the current status of the Teleport certificates.
type CertWatcher ¶
type CertWatcher struct {
// contains filtered or unexported fields
}
CertWatcher monitors certificate files for changes and triggers reloads. It uses fsnotify for efficient file system monitoring with a fallback to polling for environments where fsnotify is not available or reliable.
func NewCertWatcher ¶
func NewCertWatcher(config CertWatcherConfig) (*CertWatcher, error)
NewCertWatcher creates a new certificate watcher.
func (*CertWatcher) IsRunning ¶
func (w *CertWatcher) IsRunning() bool
IsRunning returns whether the watcher is currently active.
func (*CertWatcher) Start ¶
func (w *CertWatcher) Start() error
Start begins watching for certificate changes.
func (*CertWatcher) Stop ¶
func (w *CertWatcher) Stop() error
Stop gracefully stops the certificate watcher.
type CertWatcherConfig ¶
type CertWatcherConfig struct {
// IdentityDir is the directory containing certificate files.
IdentityDir string
// CertFile is the certificate file name.
CertFile string
// KeyFile is the private key file name.
KeyFile string
// CAFile is the CA certificate file name.
CAFile string
// WatchInterval is the fallback polling interval when fsnotify is not available.
WatchInterval time.Duration
// OnChange is called when certificate files change.
OnChange func()
}
CertWatcherConfig holds configuration for the certificate watcher.
type CertificateData ¶
type CertificateData struct {
// CertPEM is the client certificate in PEM format.
CertPEM []byte
// KeyPEM is the client private key in PEM format.
KeyPEM []byte
// CAPEM is the CA certificate in PEM format.
CAPEM []byte
}
CertificateData holds certificate data loaded from memory. This is used for in-memory certificate loading from Kubernetes secrets, avoiding the need to write sensitive data to temporary files.
type ClientProvider ¶
type ClientProvider struct {
// contains filtered or unexported fields
}
ClientProvider implements HTTPClientProvider and provides HTTP clients configured with Teleport Machine ID certificates for accessing private installations via Teleport Application Access.
func NewClientProvider ¶
func NewClientProvider(config TeleportConfig) (*ClientProvider, error)
NewClientProvider creates a new Teleport client provider with the given configuration. It loads the initial certificates and optionally starts watching for changes.
The config.IdentityDir must contain the certificate files (or config.IdentitySecretName must be set for Kubernetes mode). If certificate files are not immediately available, the provider will be created in an unloaded state and will attempt to load certificates when GetHTTPClient is called.
func NewClientProviderFromMemory ¶
func NewClientProviderFromMemory(certData CertificateData) (*ClientProvider, error)
NewClientProviderFromMemory creates a new Teleport client provider with certificates loaded directly from memory. This avoids writing sensitive private key data to disk.
This is the preferred method for loading certificates from Kubernetes secrets, as it eliminates the security risk of temporary files containing private keys.
func NewClientProviderWithWatching ¶
func NewClientProviderWithWatching(config TeleportConfig) (*ClientProvider, error)
NewClientProviderWithWatching creates a new Teleport client provider that watches for certificate changes and automatically reloads them.
func (*ClientProvider) Close ¶
func (p *ClientProvider) Close() error
Close releases resources and stops any background watchers.
func (*ClientProvider) GetHTTPClient ¶
func (p *ClientProvider) GetHTTPClient() (*http.Client, error)
GetHTTPClient returns an HTTP client configured with Teleport certificates. The client uses mutual TLS with the Teleport CA for trust.
func (*ClientProvider) GetHTTPTransport ¶
func (p *ClientProvider) GetHTTPTransport() (*http.Transport, error)
GetHTTPTransport returns an HTTP transport configured with Teleport certificates. This is useful when you need to customize the client further.
func (*ClientProvider) GetStatus ¶
func (p *ClientProvider) GetStatus() CertStatus
GetStatus returns the current certificate status.
func (*ClientProvider) GetTLSConfig ¶
func (p *ClientProvider) GetTLSConfig() (*tls.Config, error)
GetTLSConfig returns the current TLS configuration.
func (*ClientProvider) IsExpiringSoon ¶
func (p *ClientProvider) IsExpiringSoon(threshold time.Duration) bool
IsExpiringSoon returns whether the certificate will expire within the given duration.
func (*ClientProvider) IsLoaded ¶
func (p *ClientProvider) IsLoaded() bool
IsLoaded returns whether certificates are currently loaded and valid.
func (*ClientProvider) OnReload ¶
func (p *ClientProvider) OnReload(callback CertReloadCallback)
OnReload registers a callback that is invoked when certificates are reloaded.
func (*ClientProvider) Reload ¶
func (p *ClientProvider) Reload() error
Reload forces a reload of the certificates from disk.
func (*ClientProvider) StartWatching ¶
func (p *ClientProvider) StartWatching() error
StartWatching starts watching for certificate file changes. When changes are detected, certificates are automatically reloaded.
func (*ClientProvider) StopWatching ¶
func (p *ClientProvider) StopWatching() error
StopWatching stops the certificate file watcher.
type HTTPClientProvider ¶
type HTTPClientProvider interface {
// GetHTTPClient returns an HTTP client configured with Teleport certificates.
// The client uses mutual TLS with the Teleport CA for trust.
GetHTTPClient() (*http.Client, error)
// GetHTTPTransport returns an HTTP transport configured with Teleport certificates.
// This is useful when you need to customize the client further.
GetHTTPTransport() (*http.Transport, error)
// GetTLSConfig returns the current TLS configuration.
// This can be used to verify certificate status or for custom integrations.
GetTLSConfig() (*tls.Config, error)
// Close releases resources and stops any background watchers.
Close() error
}
HTTPClientProvider defines the interface for providing HTTP clients configured with Teleport authentication.
type TeleportConfig ¶
type TeleportConfig struct {
// IdentityDir is the directory containing Teleport identity files.
// In filesystem mode, this is the tbot output directory.
// In Kubernetes mode, this is where the identity secret is mounted.
IdentityDir string
// IdentitySecretName is the name of the Kubernetes Secret containing
// tbot identity files. Used when running in Kubernetes mode.
IdentitySecretName string
// Namespace is the Kubernetes namespace where the identity secret is located.
// Defaults to "default" if not specified.
Namespace string
// AppName is the Teleport application name for routing.
// This is used to identify which application the client is connecting to.
AppName string
// WatchInterval is how often to check for certificate changes.
// Defaults to 30 seconds if not specified.
WatchInterval time.Duration
// CertFile is the path to the client certificate file (relative to IdentityDir).
// Defaults to "tlscert" if not specified (matching tbot's application output).
CertFile string
// KeyFile is the path to the client private key file (relative to IdentityDir).
// Defaults to "key" if not specified (matching tbot's application output).
KeyFile string
// CAFile is the path to the CA certificate file (relative to IdentityDir).
// Defaults to "teleport-application-ca.pem" if not specified (matching tbot's application output).
CAFile string
}
TeleportConfig holds configuration for Teleport authentication. This configuration is typically populated from MCPServer auth.teleport settings.