Skip to content

Commit 99313dd

Browse files
committed
[extension/opamp] Redact values in effective config
1 parent 88eba8f commit 99313dd

File tree

5 files changed

+125
-2
lines changed

5 files changed

+125
-2
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: breaking
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: extension/opamp
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Redact all values in the effective config
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [33267]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext: |
19+
All values will be treated as if they are a `configopaque.String` type. This will
20+
be changed once the Collector APIs are updated to unmarshal the config while
21+
only redacting actual `configopaque.String`-typed values.
22+
23+
The exception to redaction is the `service::pipelines` section, which is useful
24+
for debugging and does not contain any `configopaque.String` values.
25+
26+
# If your change doesn't affect end users or the exported elements of any package,
27+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
28+
# Optional: The change log or logs in which this entry should be included.
29+
# e.g. '[user]' or '[user, api]'
30+
# Include 'user' if the change is relevant to end users.
31+
# Include 'api' if there is a change to a library API.
32+
# Default: '[user]'
33+
change_logs: []

extension/opampextension/opamp_agent.go

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ import (
2828
"github.com/open-telemetry/opentelemetry-collector-contrib/extension/opampcustommessages"
2929
)
3030

31+
const redactedVal = "[REDACTED]"
32+
33+
// Paths that will not have values redacted when reporting the effective config.
34+
var unredactedPaths = []string{
35+
"service::pipelines",
36+
}
37+
3138
type opampAgent struct {
3239
cfg *Config
3340
logger *zap.Logger
@@ -261,6 +268,46 @@ func (o *opampAgent) updateAgentIdentity(instanceID ulid.ULID) {
261268
o.instanceID = instanceID
262269
}
263270

271+
func redactConfig(cfg any, parentPath string) {
272+
switch val := cfg.(type) {
273+
case map[string]any:
274+
for k, v := range val {
275+
path := parentPath
276+
if path == "" {
277+
path = k
278+
} else {
279+
path += "::" + k
280+
}
281+
// We don't want to redact certain parts of the config
282+
// that are known not to contain secrets, e.g. pipelines.
283+
for _, p := range unredactedPaths {
284+
if p == path {
285+
return
286+
}
287+
}
288+
switch x := v.(type) {
289+
case map[string]any:
290+
redactConfig(x, path)
291+
case []any:
292+
redactConfig(x, path)
293+
default:
294+
val[k] = redactedVal
295+
}
296+
}
297+
case []any:
298+
for i, v := range val {
299+
switch x := v.(type) {
300+
case map[string]any:
301+
redactConfig(x, parentPath)
302+
case []any:
303+
redactConfig(x, parentPath)
304+
default:
305+
val[i] = redactedVal
306+
}
307+
}
308+
}
309+
}
310+
264311
func (o *opampAgent) composeEffectiveConfig() *protobufs.EffectiveConfig {
265312
o.eclk.RLock()
266313
defer o.eclk.RUnlock()
@@ -269,7 +316,9 @@ func (o *opampAgent) composeEffectiveConfig() *protobufs.EffectiveConfig {
269316
return nil
270317
}
271318

272-
conf, err := yaml.Marshal(o.effectiveConfig.ToStringMap())
319+
m := o.effectiveConfig.ToStringMap()
320+
redactConfig(m, "")
321+
conf, err := yaml.Marshal(m)
273322
if err != nil {
274323
o.logger.Error("cannot unmarshal effectiveConfig", zap.Any("conf", o.effectiveConfig), zap.Error(err))
275324
return nil

extension/opampextension/opamp_agent_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,8 @@ func TestComposeEffectiveConfig(t *testing.T) {
176176
ecFileName := filepath.Join("testdata", "effective.yaml")
177177
cm, err := confmaptest.LoadConf(ecFileName)
178178
assert.NoError(t, err)
179-
expected, err := os.ReadFile(ecFileName)
179+
redactedFileName := filepath.Join("testdata", "effective-redacted.yaml")
180+
expected, err := os.ReadFile(redactedFileName)
180181
assert.NoError(t, err)
181182

182183
o.updateEffectiveConfig(cm)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
exporters:
2+
otlp:
3+
endpoint: "[REDACTED]"
4+
receivers:
5+
otlp:
6+
protocols:
7+
grpc: {}
8+
http: {}
9+
processors:
10+
transform:
11+
error_mode: "[REDACTED]"
12+
metric_statements:
13+
- context: "[REDACTED]"
14+
conditions:
15+
- "[REDACTED]"
16+
statements:
17+
- "[REDACTED]"
18+
service:
19+
pipelines:
20+
traces:
21+
receivers: [otlp]
22+
processors: []
23+
exporters: [otlp]
24+
metrics:
25+
receivers: [otlp]
26+
processors: [transform]
27+
exporters: [otlp]

extension/opampextension/testdata/effective.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,22 @@ receivers:
66
protocols:
77
grpc: {}
88
http: {}
9+
processors:
10+
transform:
11+
error_mode: ignore
12+
metric_statements:
13+
- context: metric
14+
conditions:
15+
- type == METRIC_DATA_TYPE_SUM
16+
statements:
17+
- set(description, "Sum")
918
service:
1019
pipelines:
1120
traces:
1221
receivers: [otlp]
1322
processors: []
1423
exporters: [otlp]
24+
metrics:
25+
receivers: [otlp]
26+
processors: [transform]
27+
exporters: [otlp]

0 commit comments

Comments
 (0)