diff --git a/config/http_config.go b/config/http_config.go index 4e5ff92a2..8ec9ef65f 100644 --- a/config/http_config.go +++ b/config/http_config.go @@ -32,6 +32,11 @@ import ( "time" conntrack "github.com/mwitkow/go-conntrack" + spiffebundle "github.com/spiffe/go-spiffe/v2/bundle/x509bundle" + "github.com/spiffe/go-spiffe/v2/spiffeid" + "github.com/spiffe/go-spiffe/v2/spiffetls" + spiffetlsconfig "github.com/spiffe/go-spiffe/v2/spiffetls/tlsconfig" + spiffesvid "github.com/spiffe/go-spiffe/v2/svid/x509svid" "go.yaml.in/yaml/v2" "golang.org/x/net/http/httpproxy" "golang.org/x/net/http2" @@ -456,6 +461,11 @@ type DialContextFunc func(context.Context, string, string) (net.Conn, error) // NewTLSConfigFunc returns tls.Config. type NewTLSConfigFunc func(context.Context, *TLSConfig, ...TLSConfigOption) (*tls.Config, error) +type SpiffeSvidAndBundleSource interface { + spiffesvid.Source + spiffebundle.Source +} + type httpClientOptions struct { dialContextFunc DialContextFunc newTLSConfigFunc NewTLSConfigFunc @@ -465,6 +475,7 @@ type httpClientOptions struct { userAgent string host string secretManager SecretManager + spiffeSourceFn func() (SpiffeSvidAndBundleSource, error) } // HTTPClientOption defines an option that can be applied to the HTTP client. @@ -530,6 +541,20 @@ func WithHost(host string) HTTPClientOption { }) } +// WithSpiffeSourceFactory allows SPIFFE to be used with this HTTP client. +// The provided function should return the same X509Source on every call +// since all clients can share the same source. The source may either +// already exist (in which case the function can just return a fixed value) +// or be created on demand (in which case no X509Source will be created unless +// SPIFFE is configured and used). The returned X509Source will not be closed +// during the lifetime of the HTTPClient. The default is that there is no +// factory function and SPIFFE is not available. +func WithSpiffeSourceFactory(fn func() (SpiffeSvidAndBundleSource, error)) HTTPClientOption { + return httpClientOptionFunc(func(opts *httpClientOptions) { + opts.spiffeSourceFn = fn + }) +} + type secretManagerOption struct { secretManager SecretManager } @@ -584,6 +609,28 @@ func NewRoundTripperFromConfig(cfg HTTPClientConfig, name string, optFuncs ...HT return NewRoundTripperFromConfigWithContext(context.Background(), cfg, name, optFuncs...) } +func makeSpiffeDialer(configuredSpiffeID string, getSource func() (SpiffeSvidAndBundleSource, error)) func(ctx context.Context, network, addr string) (net.Conn, error) { + return func(ctx context.Context, network, addr string) (net.Conn, error) { + ids := configuredSpiffeID + if idc := ctx.Value(SpiffeIDContextValue); idc != nil { + ids = idc.(string) + } + peer, err := spiffeid.FromString(ids) + if err != nil { + return nil, fmt.Errorf("unparsable SPIFFE ID %q: %w", ids, err) + } + if getSource == nil { + return nil, errors.New("SPIFFE requested but not configured") + } + source, err := getSource() + if err != nil { + return nil, err + } + mode := spiffetls.MTLSClientWithRawConfig(spiffetlsconfig.AuthorizeID(peer), source, source) + return spiffetls.DialWithMode(ctx, network, addr, mode) + } +} + // NewRoundTripperFromConfigWithContext returns a new HTTP RoundTripper configured for the // given config.HTTPClientConfig and config.HTTPClientOption. // The name is used as go-conntrack metric label. @@ -607,6 +654,11 @@ func NewRoundTripperFromConfigWithContext(ctx context.Context, cfg HTTPClientCon } newRT := func(tlsConfig *tls.Config) (http.RoundTripper, error) { + var dialTLS func(ctx context.Context, network, addr string) (net.Conn, error) + if tlsConfig == nil { + // Use SPIFFE + dialTLS = makeSpiffeDialer(cfg.TLSConfig.SpiffeID, opts.spiffeSourceFn) + } // The only timeout we care about is the configured scrape timeout. // It is applied on request. So we leave out any timings here. var rt http.RoundTripper = &http.Transport{ @@ -621,6 +673,7 @@ func NewRoundTripperFromConfigWithContext(ctx context.Context, cfg HTTPClientCon TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, DialContext: dialContext, + DialTLSContext: dialTLS, } if opts.http2Enabled && cfg.EnableHTTP2 { // HTTP/2 support is golang had many problematic cornercases where @@ -691,6 +744,10 @@ func NewRoundTripperFromConfigWithContext(ctx context.Context, cfg HTTPClientCon return rt, nil } + if cfg.TLSConfig.SpiffeID != "" || cfg.TLSConfig.UseSpiffe { + return newRT(nil) + } + tlsConfig, err := opts.newTLSConfigFunc(ctx, &cfg.TLSConfig, WithSecretManager(opts.secretManager)) if err != nil { return nil, err @@ -1140,6 +1197,13 @@ type TLSConfig struct { MinVersion TLSVersion `yaml:"min_version,omitempty" json:"min_version,omitempty"` // Maximum TLS version. MaxVersion TLSVersion `yaml:"max_version,omitempty" json:"max_version,omitempty"` + // Use SPIFFE to configure TLS. The special label `__spiffe_id__` on the + // scrape target configures the SPIFFE ID that must be presented. + UseSpiffe bool `yaml:"use_spiffe,omitempty" json:"use_spiffe,omitempty"` + // Use SPIFFE to configure TLS. The special label `__spiffe_id__` on the + // scrape target (first) or the value of this parameter (otherwise) + // configures the SPIFFE ID that must be presented. + SpiffeID string `yaml:"spiffe_id,omitempty" json:"spiffe_id,omitempty"` } // SetDirectory joins any relative file paths with dir. @@ -1181,6 +1245,10 @@ func (c *TLSConfig) Validate() error { return errors.New("exactly one of cert or cert_file must be configured when a client key is configured") } + if (len(c.CA) > 0 || len(c.CAFile) > 0 || len(c.CARef) > 0 || len(c.Cert) > 0 || len(c.CertFile) > 0 || len(c.CertRef) > 0 || len(c.Key) > 0 || len(c.KeyFile) > 0 || len(c.KeyRef) > 0 || len(c.ServerName) > 0 || c.InsecureSkipVerify) && (len(c.SpiffeID) > 0 || c.UseSpiffe) { + return errors.New("either SPIFFE settings or other TLSConfig settings may be set but not both") + } + return nil } @@ -1536,3 +1604,7 @@ func (c *ProxyConfig) Proxy() (fn func(*http.Request) (*url.URL, error)) { func (c *ProxyConfig) GetProxyConnectHeader() http.Header { return c.ProxyConnectHeader.HTTPHeader() } + +type spiffeIDContextValue bool + +const SpiffeIDContextValue = spiffeIDContextValue(false) diff --git a/config/http_config_test.go b/config/http_config_test.go index c8853592e..795d2b3e9 100644 --- a/config/http_config_test.go +++ b/config/http_config_test.go @@ -15,9 +15,11 @@ package config import ( "context" + "crypto" "crypto/tls" "crypto/x509" "encoding/json" + "encoding/pem" "errors" "fmt" "io" @@ -35,6 +37,9 @@ import ( "testing" "time" + spiffebundle "github.com/spiffe/go-spiffe/v2/bundle/x509bundle" + "github.com/spiffe/go-spiffe/v2/spiffeid" + spiffesvid "github.com/spiffe/go-spiffe/v2/svid/x509svid" "github.com/stretchr/testify/require" "go.yaml.in/yaml/v2" ) @@ -53,6 +58,12 @@ const ( MissingCert = "missing/cert.crt" MissingKey = "missing/secret.key" + SpiffeWorkload1Cert = "testdata/spiffe.workload1.cert.pem" + SpiffeWorkload1Key = "testdata/spiffe.workload1.key.pem" + SpiffeWorkload2Cert = "testdata/spiffe.workload2.cert.pem" + SpiffeWorkload2Key = "testdata/spiffe.workload2.key.pem" + SpiffeBundle = "testdata/spiffe.bundle.pem" + ExpectedMessage = "I'm here to serve you!!!" ExpectedError = "expected error" AuthorizationCredentials = "theanswertothegreatquestionoflifetheuniverseandeverythingisfortytwo" @@ -166,6 +177,37 @@ func newTestServer(handler func(w http.ResponseWriter, r *http.Request)) (*httpt return testServer, nil } +func newSpiffeTestServer() (*httptest.Server, error) { + handler := func(w http.ResponseWriter, _ *http.Request) { + fmt.Fprint(w, ExpectedMessage) + } + testServer := httptest.NewUnstartedServer(http.HandlerFunc(handler)) + + tlsCAChain, err := os.ReadFile(SpiffeBundle) + if err != nil { + return nil, fmt.Errorf("Can't read %s", SpiffeBundle) + } + serverCertificate, err := tls.LoadX509KeyPair(SpiffeWorkload1Cert, SpiffeWorkload1Key) + if err != nil { + return nil, fmt.Errorf("Can't load X509 key pair %s - %s", SpiffeWorkload1Cert, SpiffeWorkload1Key) + } + + rootCAs := x509.NewCertPool() + rootCAs.AppendCertsFromPEM(tlsCAChain) + + testServer.TLS = &tls.Config{ + Certificates: make([]tls.Certificate, 1), + RootCAs: rootCAs, + ClientAuth: tls.RequireAndVerifyClientCert, + ClientCAs: rootCAs, + } + testServer.TLS.Certificates[0] = serverCertificate + + testServer.StartTLS() + + return testServer, nil +} + func TestNewClientFromConfig(t *testing.T) { newClientValidConfig := []struct { clientConfig HTTPClientConfig @@ -1275,6 +1317,131 @@ func TestTLSRoundTripper_Inline(t *testing.T) { } } +type testSpiffeSource struct{} + +func (*testSpiffeSource) GetX509SVID() (*spiffesvid.SVID, error) { + cert, err := tls.LoadX509KeyPair(SpiffeWorkload2Cert, SpiffeWorkload2Key) + if err != nil { + return nil, fmt.Errorf("Can't load X509 key pair %s - %s", SpiffeWorkload2Cert, SpiffeWorkload2Key) + } + if signer, ok := cert.PrivateKey.(crypto.Signer); ok { + return &spiffesvid.SVID{ + ID: spiffeid.RequireFromString("spiffe://example.org/workload2"), + Certificates: []*x509.Certificate{cert.Leaf}, + PrivateKey: signer, + }, nil + } + return nil, errors.New("private key is not crypto.Signer") +} + +func (*testSpiffeSource) GetX509BundleForTrustDomain(trustDomain spiffeid.TrustDomain) (*spiffebundle.Bundle, error) { + if trustDomain.Name() == "example.org" { + bundlePem, err := os.ReadFile(SpiffeBundle) + if err != nil { + return nil, fmt.Errorf("Can't read %s", SpiffeBundle) + } + var bundle []*x509.Certificate + for len(bundlePem) > 0 { + b, more := pem.Decode(bundlePem) + c, err := x509.ParseCertificate(b.Bytes) + if err != nil { + return nil, fmt.Errorf("Can't parse %s as a certificate", SpiffeBundle) + } + bundlePem = more + bundle = append(bundle, c) + } + return spiffebundle.FromX509Authorities(trustDomain, bundle), nil + } + return nil, fmt.Errorf("No bundle for trust domain %v", trustDomain) +} + +func spiffeMaker() (SpiffeSvidAndBundleSource, error) { + return &testSpiffeSource{}, nil +} + +func TestTLSRoundTripper_SPIFFE(t *testing.T) { + testServer, err := newSpiffeTestServer() + require.NoError(t, err) + defer testServer.Close() + + testCases := []struct { + disabled bool + useSpiffe bool + confID string + ctxID string + + errMsg string + }{ + { + disabled: true, + confID: "spiffe://trust.domain/foo", + errMsg: "SPIFFE requested but not configured", + }, + { + confID: "spiffe://example.org/workload1", + }, + { + confID: "spiffe://example.org/wrong", + errMsg: "unexpected ID", + }, + { + confID: "unparsable", + errMsg: "unparsable", + }, + { + useSpiffe: true, + ctxID: "spiffe://example.org/workload1", + }, + { + confID: "spiffe://overridden/ignored", + ctxID: "spiffe://example.org/workload1", + }, + } + + for i, tc := range testCases { + tc := tc + t.Run(strconv.Itoa(i), func(t *testing.T) { + cfg := HTTPClientConfig{ + TLSConfig: TLSConfig{ + UseSpiffe: tc.useSpiffe, + SpiffeID: tc.confID, + }, + } + + var opts []HTTPClientOption + if !tc.disabled { + opts = append(opts, WithSpiffeSourceFactory(spiffeMaker)) + } + c, err := NewClientFromConfig(cfg, "test", opts...) + require.NoErrorf(t, err, "Error creating HTTP client: %v", err) + req, err := http.NewRequest(http.MethodGet, testServer.URL, nil) + require.NoErrorf(t, err, "Error creating HTTP request: %v", err) + ctx := context.Background() + if tc.ctxID != "" { + ctx = context.WithValue(ctx, SpiffeIDContextValue, tc.ctxID) + } + r, err := c.Do(req.WithContext(ctx)) + if tc.errMsg != "" { + require.ErrorContainsf(t, err, tc.errMsg, "Expected error message to contain %q, got %q", tc.errMsg, err) + return + } else if err != nil { + t.Fatalf("Error executing HTTP request: %v", err) + } + + b, err := io.ReadAll(r.Body) + r.Body.Close() + if err != nil { + t.Errorf("Can't read the server response body") + } + + got := strings.TrimSpace(string(b)) + if ExpectedMessage != got { + t.Errorf("The expected message %q differs from the obtained message %q", ExpectedMessage, got) + } + }) + } +} + func TestTLSRoundTripperRaces(t *testing.T) { bs := getCertificateBlobs(t) diff --git a/config/testdata/spiffe.bundle.pem b/config/testdata/spiffe.bundle.pem new file mode 100644 index 000000000..6153481cd --- /dev/null +++ b/config/testdata/spiffe.bundle.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIICBDCCAaqgAwIBAgIRAP6xM1DuTb3X0lAhRTLmNhMwCgYIKoZIzj0EAwIwUDEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBlNQSUZGRTEwMC4GA1UEBRMnMzM4NTQzOTg4 +Mjg4MjIzNDk5NzE4MjE1ODYwMjk1NDUyNDcyODUxMCAXDTI1MDkwNzA5MjQzMVoY +DzIyMjUwNzIxMDkyNDQxWjBQMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGU1BJRkZF +MTAwLgYDVQQFEyczMzg1NDM5ODgyODgyMjM0OTk3MTgyMTU4NjAyOTU0NTI0NzI4 +NTEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQtQEBKDICx1ywQOjIiYGOO6DI8 +edAy3MxMQrWs737AgD45ixo1fNIGHfpD9v0WH3kq5C9ycB5YNpIaSdfXJiiJo2Mw +YTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUZ5LV +HKgEZ5Kvs50NaJboDBt+U/owHwYDVR0RBBgwFoYUc3BpZmZlOi8vZXhhbXBsZS5v +cmcwCgYIKoZIzj0EAwIDSAAwRQIgOvUg85SrI2hmeCStTkCF9or0Vgcuzdifwfq5 +qQBJ9W8CIQD13tnaExaopel4BbweByAnXHqYEwomLlMbLs6ldz7a7w== +-----END CERTIFICATE----- diff --git a/config/testdata/spiffe.workload1.cert.pem b/config/testdata/spiffe.workload1.cert.pem new file mode 100644 index 000000000..d4ff780c2 --- /dev/null +++ b/config/testdata/spiffe.workload1.cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICGjCCAb+gAwIBAgIQS8qrtPjeVHsY0SXsfT8B/zAKBggqhkjOPQQDAjBQMQsw +CQYDVQQGEwJVUzEPMA0GA1UEChMGU1BJRkZFMTAwLgYDVQQFEyczMzg1NDM5ODgy +ODgyMjM0OTk3MTgyMTU4NjAyOTU0NTI0NzI4NTEwIBcNMjUwOTA3MDkyNjUzWhgP +MjEwMDA4MjAwOTI3MDNaMB0xCzAJBgNVBAYTAlVTMQ4wDAYDVQQKEwVTUElSRTBZ +MBMGByqGSM49AgEGCCqGSM49AwEHA0IABO+FhNA7IYyFNA/BDOovyNVlwZVesbfj +knv/alVHrJ8Z5PPLv5RC4EqxDUCIdYH8IcfpXbRUsxV3Y8oIRkQFWpOjgaswgagw +DgYDVR0PAQH/BAQDAgOoMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAM +BgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQJ/hirbRAZC32OWIHWBdVfOF67gzAfBgNV +HSMEGDAWgBRnktUcqARnkq+znQ1olugMG35T+jApBgNVHREEIjAghh5zcGlmZmU6 +Ly9leGFtcGxlLm9yZy93b3JrbG9hZDEwCgYIKoZIzj0EAwIDSQAwRgIhAPIkKNdq +SBb9ROIe2eo5ed1/0ay89UMjd+dxlkuyX8jAAiEAx1P1bBnzAVhuQx0YbzG2lJnK +QBCtPcGZ/amdWZt9G0A= +-----END CERTIFICATE----- diff --git a/config/testdata/spiffe.workload1.key.pem b/config/testdata/spiffe.workload1.key.pem new file mode 100644 index 000000000..983c5a6aa --- /dev/null +++ b/config/testdata/spiffe.workload1.key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgorRBVyov8trytD8G +v094aUhNkeOlBfV6mdZfC7rm66+hRANCAATvhYTQOyGMhTQPwQzqL8jVZcGVXrG3 +45J7/2pVR6yfGeTzy7+UQuBKsQ1AiHWB/CHH6V20VLMVd2PKCEZEBVqT +-----END PRIVATE KEY----- diff --git a/config/testdata/spiffe.workload2.cert.pem b/config/testdata/spiffe.workload2.cert.pem new file mode 100644 index 000000000..cf7a628c6 --- /dev/null +++ b/config/testdata/spiffe.workload2.cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICGTCCAb+gAwIBAgIQLObm0tancKOMatNi8ON8VTAKBggqhkjOPQQDAjBQMQsw +CQYDVQQGEwJVUzEPMA0GA1UEChMGU1BJRkZFMTAwLgYDVQQFEyczMzg1NDM5ODgy +ODgyMjM0OTk3MTgyMTU4NjAyOTU0NTI0NzI4NTEwIBcNMjUwOTA3MDkyNzAzWhgP +MjEwMDA4MjAwOTI3MTNaMB0xCzAJBgNVBAYTAlVTMQ4wDAYDVQQKEwVTUElSRTBZ +MBMGByqGSM49AgEGCCqGSM49AwEHA0IABO+KKXV+1AeZpCarfpIWbjDePmzPdB8s +t5vd256f0t3qsvZ9edVAVBsW69gf49813V8KysVJSbDDM1bipiwx6T2jgaswgagw +DgYDVR0PAQH/BAQDAgOoMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAM +BgNVHRMBAf8EAjAAMB0GA1UdDgQWBBSdcdhiF8avWCJsGmHHoU71DtYwrjAfBgNV +HSMEGDAWgBRnktUcqARnkq+znQ1olugMG35T+jApBgNVHREEIjAghh5zcGlmZmU6 +Ly9leGFtcGxlLm9yZy93b3JrbG9hZDIwCgYIKoZIzj0EAwIDSAAwRQIgGeWI3yvG +pXMQr6BRlmH1zv7uhO07aBhX86iKbp1JYCcCIQDuNzook5Y+okja2nepHjoqxNj3 +xLjI46t6wCxLvmWV/Q== +-----END CERTIFICATE----- diff --git a/config/testdata/spiffe.workload2.key.pem b/config/testdata/spiffe.workload2.key.pem new file mode 100644 index 000000000..458c1a6c4 --- /dev/null +++ b/config/testdata/spiffe.workload2.key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg9wQQ4VluDQR9MC99 +EfPcZ33IC99bY80M/UiKcM/P8WKhRANCAATviil1ftQHmaQmq36SFm4w3j5sz3Qf +LLeb3duen9Ld6rL2fXnVQFQbFuvYH+PfNd1fCsrFSUmwwzNW4qYsMek9 +-----END PRIVATE KEY----- diff --git a/config/testdata/tls_config.spiffe_and_other.bad.json b/config/testdata/tls_config.spiffe_and_other.bad.json new file mode 100644 index 000000000..32806f4b2 --- /dev/null +++ b/config/testdata/tls_config.spiffe_and_other.bad.json @@ -0,0 +1,2 @@ +{"ca_file": "something", +"spiffe_id": "spiffe://trust.domain/expected/peer"} diff --git a/config/tls_config_test.go b/config/tls_config_test.go index f02c87fdd..69fda84d8 100644 --- a/config/tls_config_test.go +++ b/config/tls_config_test.go @@ -117,6 +117,10 @@ var invalidTLSConfigs = []struct { filename: "tls_config.max_and_min_version.bad.yml", errMsg: "tls_config.max_version must be greater than or equal to tls_config.min_version if both are specified", }, + { + filename: "tls_config.spiffe_and_other.bad.json", + errMsg: "either SPIFFE settings or other TLSConfig settings may be set but not both", + }, } func TestInvalidTLSConfig(t *testing.T) { diff --git a/go.mod b/go.mod index a91acac50..6d71ef2ed 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/prometheus/common -go 1.23.0 +go 1.24.0 toolchain go1.24.1 @@ -11,6 +11,7 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f github.com/prometheus/client_model v0.6.2 + github.com/spiffe/go-spiffe/v2 v2.6.0 github.com/stretchr/testify v1.11.1 go.yaml.in/yaml/v2 v2.4.2 golang.org/x/net v0.43.0 @@ -19,18 +20,23 @@ require ( ) require ( + github.com/Microsoft/go-winio v0.6.2 // indirect github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/go-jose/go-jose/v4 v4.1.2 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect + golang.org/x/crypto v0.41.0 // indirect golang.org/x/sys v0.35.0 // indirect golang.org/x/text v0.28.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 // indirect + google.golang.org/grpc v1.75.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 654a30102..1abfc55d3 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjHpqDjYY= github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= @@ -9,8 +11,18 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-jose/go-jose/v4 v4.1.2 h1:TK/7NqRQZfgAh+Td8AlsrvtPoUyiHh0LqVvokh+1vHI= +github.com/go-jose/go-jose/v4 v4.1.2/go.mod h1:22cg9HWM1pOlnRiY+9cQYJ9XHmya1bYW8OeDM6Ku6Oo= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= @@ -37,14 +49,30 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/spiffe/go-spiffe/v2 v2.6.0 h1:l+DolpxNWYgruGQVV0xsfeya3CsC7m8iBzDnMpsbLuo= +github.com/spiffe/go-spiffe/v2 v2.6.0/go.mod h1:gm2SeUoMZEtpnzPNs2Csc0D/gX33k1xIx7lEzqblHEs= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= +go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= +go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= +go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= +go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= +go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= +golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= @@ -53,6 +81,12 @@ golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 h1:pFyd6EwwL2TqFf8emdthzeX+gZE1ElRq3iM8pui4KBY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= +google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/model/labels.go b/model/labels.go index dfeb34be5..682106cf8 100644 --- a/model/labels.go +++ b/model/labels.go @@ -59,6 +59,10 @@ const ( // timeout used to scrape a target. ScrapeTimeoutLabel = "__scrape_timeout__" + // SPIFFE ID that must be presented by the scrape target if scraping over + // https and SPIFFE is enabled. + SpiffeIDLabel = "__spiffe_id__" + // ReservedLabelPrefix is a prefix which is not legal in user-supplied // label names. ReservedLabelPrefix = "__"