Documentation
¶
Overview ¶
Package proxy provides a TLS-intercepting HTTP proxy for credential injection.
Security Model ¶
The proxy intercepts HTTPS traffic via CONNECT tunneling with dynamic certificate generation. It injects credentials (Authorization headers, etc.) for configured hosts without exposing raw tokens to the container.
Firewall Integration ¶
Container firewall rules (iptables) work in conjunction with the proxy:
Docker: Proxy binds to 127.0.0.1 (localhost only). Containers reach it via host.docker.internal or host network mode. Firewall allows proxy port only.
Apple containers: Proxy binds to 0.0.0.0 with per-run token authentication. Security is maintained via cryptographic tokens in HTTP_PROXY URL, not IP filtering.
The firewall rules intentionally do NOT filter by destination IP for the proxy port. This is because host.docker.internal resolves to different IPs across environments. The security boundaries are:
- Random high port assignment (reduces collision with other services)
- Token authentication for Apple containers
- Container isolation (other containers can't reach host ports by default)
This trade-off prioritizes reliability over defense-in-depth. The proxy validates credentials are only injected for explicitly configured hosts.
Index ¶
- Constants
- func FilterHeaders(headers http.Header, authInjected bool, injectedHeaderName string) map[string]string
- func GetHostsForGrant(grant string) []string
- type AWSCredentialHandler
- type AWSCredentialProvider
- func (p *AWSCredentialProvider) GetCredentials(ctx context.Context) (*AWSCredentials, error)
- func (p *AWSCredentialProvider) Handler() http.Handler
- func (p *AWSCredentialProvider) Region() string
- func (p *AWSCredentialProvider) RoleARN() string
- func (p *AWSCredentialProvider) SetAuthToken(token string)
- type AWSCredentials
- type CA
- type Proxy
- func (p *Proxy) AddExtraHeader(host, headerName, headerValue string)
- func (p *Proxy) AddResponseTransformer(host string, transformer credential.ResponseTransformer)
- func (p *Proxy) RemoveRequestHeader(host, headerName string)
- func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (p *Proxy) SetAWSHandler(h http.Handler)
- func (p *Proxy) SetAuthToken(token string)
- func (p *Proxy) SetCA(ca *CA)
- func (p *Proxy) SetCredential(host, authHeader string)
- func (p *Proxy) SetCredentialHeader(host, headerName, headerValue string)
- func (p *Proxy) SetCredentialStore(store credential.Store)
- func (p *Proxy) SetCredentialWithGrant(host, headerName, headerValue, grant string)
- func (p *Proxy) SetLogger(logger RequestLogger)
- func (p *Proxy) SetMCPServers(servers []config.MCPServerConfig)
- func (p *Proxy) SetNetworkPolicy(policy string, allows []string, grants []string)
- func (p *Proxy) SetTokenSubstitution(host, placeholder, realToken string)
- type RequestLogData
- type RequestLogger
- type STSAssumeRoler
- type Server
Constants ¶
const MaxBodySize = 8 * 1024
MaxBodySize is the maximum size of request/response bodies to capture (8KB). Only this much is buffered for logging; the full body is always forwarded.
Variables ¶
This section is empty.
Functions ¶
func FilterHeaders ¶
func FilterHeaders(headers http.Header, authInjected bool, injectedHeaderName string) map[string]string
FilterHeaders creates a copy of headers with sensitive values filtered. If authInjected is true, the specified header name is redacted.
func GetHostsForGrant ¶
GetHostsForGrant returns the host patterns for a given grant name. Supports scoped grants like "github:repo" by extracting the provider name. Returns an empty slice if the grant is unknown.
Types ¶
type AWSCredentialHandler ¶
type AWSCredentialHandler struct {
// contains filtered or unexported fields
}
AWSCredentialHandler serves AWS credentials via HTTP in ECS container format.
func (*AWSCredentialHandler) ServeHTTP ¶
func (h *AWSCredentialHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP implements http.Handler, returning credentials in ECS format.
type AWSCredentialProvider ¶
type AWSCredentialProvider struct {
// contains filtered or unexported fields
}
AWSCredentialProvider manages AWS credential fetching and caching.
func NewAWSCredentialProvider ¶
func NewAWSCredentialProvider(ctx context.Context, roleARN, region string, sessionDuration time.Duration, externalID, sessionName string) (*AWSCredentialProvider, error)
NewAWSCredentialProvider creates a new AWS credential provider.
func (*AWSCredentialProvider) GetCredentials ¶
func (p *AWSCredentialProvider) GetCredentials(ctx context.Context) (*AWSCredentials, error)
GetCredentials returns cached credentials or fetches new ones.
func (*AWSCredentialProvider) Handler ¶
func (p *AWSCredentialProvider) Handler() http.Handler
Handler returns an HTTP handler for serving credentials.
func (*AWSCredentialProvider) Region ¶
func (p *AWSCredentialProvider) Region() string
Region returns the configured AWS region.
func (*AWSCredentialProvider) RoleARN ¶
func (p *AWSCredentialProvider) RoleARN() string
RoleARN returns the configured IAM role ARN.
func (*AWSCredentialProvider) SetAuthToken ¶
func (p *AWSCredentialProvider) SetAuthToken(token string)
SetAuthToken sets the required auth token for the credential endpoint.
type AWSCredentials ¶
type AWSCredentials struct {
AccessKeyID string
SecretAccessKey string
SessionToken string
Expiration time.Time
}
AWSCredentials holds temporary AWS credentials.
type CA ¶
type CA struct {
// contains filtered or unexported fields
}
CA represents a certificate authority for TLS interception.
func NewCA ¶
NewCA creates or loads a CA certificate. If the CA files exist at the given path, they are loaded. Otherwise, a new CA is generated and saved.
func (*CA) GenerateCert ¶
func (ca *CA) GenerateCert(host string) (*tls.Certificate, error)
GenerateCert creates a certificate for the given host signed by the CA.
type Proxy ¶
type Proxy struct {
// contains filtered or unexported fields
}
Proxy is an HTTP proxy that injects credentials into outgoing requests.
Security Model ¶
The proxy handles two distinct security concerns:
Credential injection: The proxy injects credential headers for configured hosts (e.g., api.github.com, api.anthropic.com). When CA is set, it performs TLS interception (MITM) to inject headers into HTTPS requests. Supports custom header names (Authorization, x-api-key, etc).
Proxy authentication: When authToken is set, clients must authenticate to the proxy itself via Proxy-Authorization header. This prevents unauthorized access when the proxy binds to all interfaces (0.0.0.0), which is required for Apple containers that access the host via gateway IP rather than localhost.
For Docker containers, the proxy binds to localhost (127.0.0.1) and authentication is not required. For Apple containers, the proxy binds to all interfaces with a cryptographically secure token for authentication.
func (*Proxy) AddExtraHeader ¶
AddExtraHeader adds an additional header to inject for a host. This is used for headers beyond the main credential header, such as beta feature flags or API version headers. The host must be a valid hostname (not empty, no path components).
func (*Proxy) AddResponseTransformer ¶
func (p *Proxy) AddResponseTransformer(host string, transformer credential.ResponseTransformer)
AddResponseTransformer registers a response transformer for a host. Transformers are called in registration order after receiving the upstream response. Each transformer can inspect and optionally modify the response. The host must be a valid hostname (not empty, no path components).
func (*Proxy) RemoveRequestHeader ¶
RemoveRequestHeader removes a client-sent header before forwarding.
func (*Proxy) ServeHTTP ¶
func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP handles proxy requests.
func (*Proxy) SetAWSHandler ¶
SetAWSHandler sets the handler for AWS credential requests.
func (*Proxy) SetAuthToken ¶
SetAuthToken sets the required authentication token for proxy access.
func (*Proxy) SetCredential ¶
SetCredential sets the credential for a host using the Authorization header.
func (*Proxy) SetCredentialHeader ¶
SetCredentialHeader sets a custom credential header for a host. Use this for APIs that use non-standard header names like "x-api-key". The host must be a valid hostname (not empty, no path components).
func (*Proxy) SetCredentialStore ¶
func (p *Proxy) SetCredentialStore(store credential.Store)
SetCredentialStore sets the credential store for MCP credential retrieval.
func (*Proxy) SetCredentialWithGrant ¶
SetCredentialWithGrant sets a credential header with grant info for logging. Grant is used for structured logging to identify the credential source.
func (*Proxy) SetLogger ¶
func (p *Proxy) SetLogger(logger RequestLogger)
SetLogger sets the request logger.
func (*Proxy) SetMCPServers ¶
func (p *Proxy) SetMCPServers(servers []config.MCPServerConfig)
SetMCPServers configures MCP servers for credential injection.
func (*Proxy) SetNetworkPolicy ¶
SetNetworkPolicy sets the network policy and allowed hosts. policy should be "permissive" or "strict". allows is a list of host patterns like "api.example.com" or "*.example.com". grants is a list of grant names like "github" that will be expanded to host patterns.
func (*Proxy) SetTokenSubstitution ¶
SetTokenSubstitution replaces placeholder tokens with real tokens in both Authorization headers and request bodies for a specific host.
type RequestLogData ¶
type RequestLogData struct {
Method string
URL string
StatusCode int
Duration time.Duration
Err error
RequestHeaders http.Header
ResponseHeaders http.Header
RequestBody []byte
ResponseBody []byte
AuthInjected bool // True if credential header was injected for this host
InjectedHeaderName string // Name of the injected header (for filtering)
}
RequestLogData contains all data for a logged request.
type RequestLogger ¶
type RequestLogger func(data RequestLogData)
RequestLogger is called for each proxied request.
type STSAssumeRoler ¶
type STSAssumeRoler interface {
AssumeRole(ctx context.Context, params *sts.AssumeRoleInput, optFns ...func(*sts.Options)) (*sts.AssumeRoleOutput, error)
}
STSAssumeRoler interface for STS AssumeRole operation (enables testing).
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server wraps a Proxy in an HTTP server.
func (*Server) SetBindAddr ¶
SetBindAddr sets the address to bind to. Use "0.0.0.0" to bind to all interfaces (needed for Apple containers which access host via gateway IP). Must be called before Start().