Repository navigation
Conversation
Adds an optional auth setting on both components, supporting the bearer, basic, and custom strategies via a new VectorAuthConfig type that reuses the existing HTTP auth header logic. The sink sends the credentials on every request, including the health check. The source validates incoming requests with a tonic interceptor using a constant time comparison, and rejects mismatches with an Unauthenticated status. The standard gRPC health service stays open so liveness probes do not need credentials. The token is a normal config value, so it can come from a secrets backend with SECRET[...]. Closes vectordotdev#2017
|
@pront 👋 Any timelines on potentially getting this one merged given it's a somewhat smaller change? mTLS auth is unrealistic for larger platforms, and hence being able to use http/2 across our Vector fleet would be a big win. |
| /// value, in which case the underlying error is logged by [`Auth::apply_headers_map`]. | ||
| pub fn authorization_header(&self) -> Option<HeaderValue> { | ||
| let mut map = HeaderMap::new(); | ||
| self.as_auth().apply_headers_map(&mut map); |
There was a problem hiding this comment.
Could we ensure custom credentials are redacted throughout this path? Auth::apply_headers_map() logs the complete custom value when header parsing fails. For example, a secret containing a trailing newline gets written to the error log before the source or sink fails to build. This also affects credentials resolved through SECRET[...].
I reproduced this with a dummy credential:
ERROR ... Invalid custom auth header value. value=SSWS dummy-custom-secret
Valid custom headers also have is_sensitive() == false, whereas basic and bearer headers are marked sensitive. Could we use SensitiveString for the custom value, avoid logging its contents on validation errors, and mark the resulting header sensitive?
There was a problem hiding this comment.
Fixed in bcf7d04. custom is now a SensitiveString, the header is marked sensitive for all three strategies, and an invalid value now fails the build with an error that names auth.value without logging its contents. Your trailing newline example is covered by authorization_header_error_omits_credentials.
Master moved the vector sink onto ValidatedSink with multiple endpoints, so the auth header now reaches every endpoint's service and the healthcheck helper. The plaintext warning checks each endpoint's scheme because TLS now follows the URL rather than the `tls` block, and `auth_roundtrip` addresses the sink with `http://` for the same reason.
A `custom` auth value that failed header validation was logged in full, and the resulting header was not marked sensitive, unlike basic and bearer. The value is now a `SensitiveString`, every strategy's header is marked sensitive, and encoding errors name the option without echoing it.
Reloading with a new credential leaves a window where the source and its sinks disagree, and the sink treats `Unauthenticated` as final, so the docs no longer present a reload as a safe rotation. The sink also stops emitting `auth: null` in serialized configs.
|
Hey @pront, sorry for the slow reply on this one, and thanks for taking a look! I've merged master in and sorted the conflicts. The sink moved over to Good catch on the redaction! The The shared Should be ready for another look whenever you get a chance 🙂 |
Master's Tonic 0.12 upgrade replaced `HyperSvc` with `GrpcTransport`, so the sink now inserts the auth header there, and `authorization_header` returns an `http_1::HeaderValue` built with headers 0.4.
Summary
Adds an optional auth setting on both components, supporting the bearer, basic, and custom strategies via a new VectorAuthConfig type that reuses the existing HTTP auth header logic.
The sink sends the credentials on every request, including the health check. The source validates incoming requests with a tonic interceptor using a constant time comparison, and rejects mismatches with an Unauthenticated status. The standard gRPC health service stays open so liveness probes do not need credentials. The token is a normal config value, so it can come from a secrets backend with SECRET[...].
Vector configuration
How did you test this PR?
The bearer-token auth was verified at two levels. Automated: unit tests for the source covering a matching token
auth_roundtrip, a missing token, and a wrong token, both rejected withUnauthenticated, plus a constant-time-compare test and anhttptest confirmingVectorAuthConfigproduces the rightAuthorizationheader forbearer/basic/custom.End-to-end: a single live
vectorprocess wired asdemo_logs → vector sink → vector source → console, where matching tokens delivered all 5 events to the console, and a mismatched token produced zero delivered events with the source returningUnauthenticated: "Valid authorization token required.", a failed healthcheck, and the request correctly dropped as non-retriable.Change Type
Is this a breaking change?
Does this PR include user facing changes?
no-changeloglabel to this PR.References
Closes #2017