package runnerbootstrap import ( "context" "fmt" "net/http" "net/http/httputil" "net/url" "github.com/spiffe/go-spiffe/v2/spiffeid" "github.com/spiffe/go-spiffe/v2/spiffetls/tlsconfig" "github.com/spiffe/go-spiffe/v2/workloadapi" ) type Proxy struct { Handler http.Handler source *workloadapi.X509Source } // NewProxy obtains rotating X509-SVIDs from the Workload API and authorizes // one exact controller identity. The official Runner talks plain HTTP only to // this executor-local handler. func NewProxy(ctx context.Context, facadeURL, facadeSPIFFEID, workloadAPIAddr string) (*Proxy, error) { target, err := url.Parse(facadeURL) if err != nil || target.Scheme != "https" || target.Host == "" { return nil, fmt.Errorf("runner facade URL must be an absolute https URL") } serverID, err := spiffeid.FromString(facadeSPIFFEID) if err != nil { return nil, fmt.Errorf("parse runner facade SPIFFE ID: %w", err) } options := []workloadapi.X509SourceOption{} if workloadAPIAddr != "" { options = append(options, workloadapi.WithClientOptions(workloadapi.WithAddr(workloadAPIAddr))) } source, err := workloadapi.NewX509Source(ctx, options...) if err != nil { return nil, fmt.Errorf("open SPIFFE Workload API X509 source: %w", err) } transport := http.DefaultTransport.(*http.Transport).Clone() transport.TLSClientConfig = tlsconfig.MTLSClientConfig(source, source, tlsconfig.AuthorizeID(serverID)) return &Proxy{Handler: NewProxyHandler(target, transport), source: source}, nil } func NewProxyHandler(target *url.URL, transport http.RoundTripper) http.Handler { proxy := httputil.NewSingleHostReverseProxy(target) proxy.Transport = transport return proxy } func (p *Proxy) Close() error { if p == nil || p.source == nil { return nil } return p.source.Close() }