Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions api/datadoghq/v2alpha1/datadogagent_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,13 @@ type CWSSecurityProfilesConfig struct {
// Default: true
// +optional
Enabled *bool `json:"enabled,omitempty"`

// V2 enables Activity Dump v2 Security Profiles collection for Cloud Workload Security.
// Requires Agent version >= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned
// or custom tags) this is disabled to avoid unbounded memory usage.
// Default: true
// +optional
V2 *bool `json:"v2,omitempty"`
}

type CWSRemoteConfigurationConfig struct {
Expand Down
5 changes: 5 additions & 0 deletions api/datadoghq/v2alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions config/crd/bases/v1/datadoghq.com_datadogagentinternals.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1407,6 +1407,13 @@ spec:
Enabled enables Security Profiles collection for Cloud Workload Security.
Default: true
type: boolean
v2:
description: |-
V2 enables Activity Dump v2 Security Profiles collection for Cloud Workload Security.
Requires Agent version >= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned
or custom tags) this is disabled to avoid unbounded memory usage.
Default: true
type: boolean
type: object
syscallMonitorEnabled:
description: |-
Expand Down Expand Up @@ -10114,6 +10121,13 @@ spec:
Enabled enables Security Profiles collection for Cloud Workload Security.
Default: true
type: boolean
v2:
description: |-
V2 enables Activity Dump v2 Security Profiles collection for Cloud Workload Security.
Requires Agent version >= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned
or custom tags) this is disabled to avoid unbounded memory usage.
Default: true
type: boolean
type: object
syscallMonitorEnabled:
description: |-
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1397,6 +1397,10 @@
"enabled": {
"description": "Enabled enables Security Profiles collection for Cloud Workload Security.\nDefault: true",
"type": "boolean"
},
"v2": {
"description": "V2 enables Activity Dump v2 Security Profiles collection for Cloud Workload Security.\nRequires Agent version \u003e= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned\nor custom tags) this is disabled to avoid unbounded memory usage.\nDefault: true",
"type": "boolean"
}
},
"type": "object"
Expand Down Expand Up @@ -9823,6 +9827,10 @@
"enabled": {
"description": "Enabled enables Security Profiles collection for Cloud Workload Security.\nDefault: true",
"type": "boolean"
},
"v2": {
"description": "V2 enables Activity Dump v2 Security Profiles collection for Cloud Workload Security.\nRequires Agent version \u003e= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned\nor custom tags) this is disabled to avoid unbounded memory usage.\nDefault: true",
"type": "boolean"
}
},
"type": "object"
Expand Down
7 changes: 7 additions & 0 deletions config/crd/bases/v1/datadoghq.com_datadogagentprofiles.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1407,6 +1407,13 @@ spec:
Enabled enables Security Profiles collection for Cloud Workload Security.
Default: true
type: boolean
v2:
description: |-
V2 enables Activity Dump v2 Security Profiles collection for Cloud Workload Security.
Requires Agent version >= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned
or custom tags) this is disabled to avoid unbounded memory usage.
Default: true
type: boolean
type: object
syscallMonitorEnabled:
description: |-
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1401,6 +1401,10 @@
"enabled": {
"description": "Enabled enables Security Profiles collection for Cloud Workload Security.\nDefault: true",
"type": "boolean"
},
"v2": {
"description": "V2 enables Activity Dump v2 Security Profiles collection for Cloud Workload Security.\nRequires Agent version \u003e= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned\nor custom tags) this is disabled to avoid unbounded memory usage.\nDefault: true",
"type": "boolean"
}
},
"type": "object"
Expand Down
14 changes: 14 additions & 0 deletions config/crd/bases/v1/datadoghq.com_datadogagents.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1411,6 +1411,13 @@ spec:
Enabled enables Security Profiles collection for Cloud Workload Security.
Default: true
type: boolean
v2:
description: |-
V2 enables Activity Dump v2 Security Profiles collection for Cloud Workload Security.
Requires Agent version >= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned
or custom tags) this is disabled to avoid unbounded memory usage.
Default: true
type: boolean
type: object
syscallMonitorEnabled:
description: |-
Expand Down Expand Up @@ -10207,6 +10214,13 @@ spec:
Enabled enables Security Profiles collection for Cloud Workload Security.
Default: true
type: boolean
v2:
description: |-
V2 enables Activity Dump v2 Security Profiles collection for Cloud Workload Security.
Requires Agent version >= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned
or custom tags) this is disabled to avoid unbounded memory usage.
Default: true
type: boolean
type: object
syscallMonitorEnabled:
description: |-
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1397,6 +1397,10 @@
"enabled": {
"description": "Enabled enables Security Profiles collection for Cloud Workload Security.\nDefault: true",
"type": "boolean"
},
"v2": {
"description": "V2 enables Activity Dump v2 Security Profiles collection for Cloud Workload Security.\nRequires Agent version \u003e= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned\nor custom tags) this is disabled to avoid unbounded memory usage.\nDefault: true",
"type": "boolean"
}
},
"type": "object"
Expand Down Expand Up @@ -9922,6 +9926,10 @@
"enabled": {
"description": "Enabled enables Security Profiles collection for Cloud Workload Security.\nDefault: true",
"type": "boolean"
},
"v2": {
"description": "V2 enables Activity Dump v2 Security Profiles collection for Cloud Workload Security.\nRequires Agent version \u003e= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned\nor custom tags) this is disabled to avoid unbounded memory usage.\nDefault: true",
"type": "boolean"
}
},
"type": "object"
Expand Down
1 change: 1 addition & 0 deletions docs/configuration.v2alpha1.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ spec:
| features.cws.network.enabled | Enables Cloud Workload Security Network detections. Default: true |
| features.cws.remoteConfiguration.enabled | Enables Remote Configuration for Cloud Workload Security. Default: true |
| features.cws.securityProfiles.enabled | Enables Security Profiles collection for Cloud Workload Security. Default: true |
| features.cws.securityProfiles.v2 | Enables Activity Dump v2 Security Profiles collection for Cloud Workload Security. Requires Agent version >= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned or custom tags) this is disabled to avoid unbounded memory usage. Default: true |
| features.cws.syscallMonitorEnabled | SyscallMonitorEnabled enables Syscall Monitoring (recommended for troubleshooting only). Default: false |
| features.dataPlane.dogstatsd.enabled | Configures the Data Plane to handle DogStatsD traffic. When set to false, DogStatsD is handled by the Core Agent instead. Default: true |
| features.dataPlane.enabled | Enables the Data Plane. Default: false |
Expand Down
3 changes: 3 additions & 0 deletions docs/configuration_public.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@ spec:
`features.cws.securityProfiles.enabled`
: Enables Security Profiles collection for Cloud Workload Security. Default: true

`features.cws.securityProfiles.v2`
: Enables Activity Dump v2 Security Profiles collection for Cloud Workload Security. Requires Agent version >= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned or custom tags) this is disabled to avoid unbounded memory usage. Default: true

`features.cws.syscallMonitorEnabled`
: SyscallMonitorEnabled enables Syscall Monitoring (recommended for troubleshooting only). Default: false

Expand Down
1 change: 1 addition & 0 deletions internal/controller/datadogagent/feature/cws/envvar.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ const (
DDRuntimeSecurityConfigRemoteConfigurationEnabled = "DD_RUNTIME_SECURITY_CONFIG_REMOTE_CONFIGURATION_ENABLED"
DDRuntimeSecurityConfigDirectSendFromSystemProbe = "DD_RUNTIME_SECURITY_CONFIG_DIRECT_SEND_FROM_SYSTEM_PROBE"
DDRuntimeSecurityConfigEventGRPCServer = "DD_RUNTIME_SECURITY_CONFIG_EVENT_GRPC_SERVER"
DDRuntimeConfigActivityDumpV2 = "DD_RUNTIME_SECURITY_CONFIG_ACTIVITY_DUMP_V2"
)
31 changes: 31 additions & 0 deletions internal/controller/datadogagent/feature/cws/feature.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@ import (
"github.com/DataDog/datadog-operator/internal/controller/datadogagent/object/volume"
"github.com/DataDog/datadog-operator/pkg/constants"
"github.com/DataDog/datadog-operator/pkg/controller/utils/comparison"
"github.com/DataDog/datadog-operator/pkg/images"
"github.com/DataDog/datadog-operator/pkg/kubernetes"
"github.com/DataDog/datadog-operator/pkg/utils"
)

const ActivityDumpV2MinVersion = "7.81.0-0"

func init() {
err := feature.Register(feature.CWSIDType, buildCWSFeature)
if err != nil {
Expand All @@ -52,6 +56,7 @@ type cwsFeature struct {
directSendFromSystemProbe bool
enforcementEnabled bool
useVSock bool
activityDumpV2 bool

owner metav1.Object
logger logr.Logger
Expand All @@ -62,6 +67,19 @@ type cwsFeature struct {
customConfigAnnotationValue string
}

// activityDumpV2Supported reports whether the configured Agent image is known to be >=
// ActivityDumpV2MinVersion. The default value passed to IsAboveMinVersion is intentionally false:
// Activity Dump v2 lacks guards against unbounded memory allocation on older Agents, so when the
// version cannot be parsed (e.g. custom or digest-pinned tags) we must fail closed rather than risk
// an OOM. Do not flip this to true without adding such guards.
func activityDumpV2Supported(ddaSpec *v2alpha1.DatadogAgentSpec) bool {
defaultValue := false
if nodeAgent, ok := ddaSpec.Override[v2alpha1.NodeAgentComponentName]; ok && nodeAgent.Image != nil {
return utils.IsAboveMinVersion(common.GetAgentVersionFromImage(*nodeAgent.Image), ActivityDumpV2MinVersion, &defaultValue)
}
return utils.IsAboveMinVersion(images.AgentLatestVersion, ActivityDumpV2MinVersion, &defaultValue)
}

// ID returns the ID of the Feature
func (f *cwsFeature) ID() feature.IDType {
return feature.CWSIDType
Expand Down Expand Up @@ -104,6 +122,19 @@ func (f *cwsFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent
}
if cwsConfig.SecurityProfiles != nil {
f.activityDumpEnabled = apiutils.BoolValue(cwsConfig.SecurityProfiles.Enabled)

if apiutils.BoolValue(cwsConfig.SecurityProfiles.V2) {
if activityDumpV2Supported(ddaSpec) {
f.activityDumpV2 = true

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Emit Activity Dump v2 into the pod template

When a user sets features.cws.securityProfiles.v2: true with an Agent tag >= 7.81.0, this branch only sets f.activityDumpV2. That field is never consumed in ManageNodeAgent to add DD_RUNTIME_SECURITY_CONFIG_ACTIVITY_DUMP_V2 to the generated DaemonSet, so Activity Dump v2 remains disabled despite the supported opt-in.

Useful? React with 👍 / 👎.

} else {
// Surface the silent gate: the user explicitly opted into v2 but we are disabling
// it because the Agent version can't be confirmed to support it. Logged at the
// default Info level so it is visible without raising log verbosity.
f.logger.Info("CWS Activity Dump v2 was requested but is disabled: the Agent image version could not be confirmed to be >= "+
ActivityDumpV2MinVersion+" (custom or digest-pinned tags parse as unknown). Enabling it on older Agents risks unbounded memory usage.",
"minVersion", ActivityDumpV2MinVersion)
}
}
}

if ddaSpec.Features != nil && ddaSpec.Features.RemoteConfiguration != nil {
Expand Down
121 changes: 121 additions & 0 deletions internal/controller/datadogagent/feature/cws/feature_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,127 @@ func Test_cwsFeature_Configure(t *testing.T) {
tests.Run(t, buildCWSFeature)
}

func Test_activityDumpV2Supported(t *testing.T) {
nodeAgentWithTag := func(tag string) map[v2alpha1.ComponentName]*v2alpha1.DatadogAgentComponentOverride {
return map[v2alpha1.ComponentName]*v2alpha1.DatadogAgentComponentOverride{
v2alpha1.NodeAgentComponentName: {
Image: &v2alpha1.AgentImageConfig{Tag: tag},
},
}
}

tests := []struct {
name string
override map[v2alpha1.ComponentName]*v2alpha1.DatadogAgentComponentOverride
want bool
}{
{
name: "agent tag at minimum version",
override: nodeAgentWithTag("7.81.0"),
want: true,
},
{
name: "agent tag above minimum version",
override: nodeAgentWithTag("7.82.0"),
want: true,
},
{
name: "agent tag below minimum version",
override: nodeAgentWithTag("7.80.0"),
want: false,
},
{
// Fails closed: an unparseable tag (custom build, digest-pinned, etc.) must not enable v2
// because older Agents have no guard against unbounded memory allocation.
name: "unparseable custom tag fails closed",
override: nodeAgentWithTag("custom-internal-build"),
want: false,
},
{
// No image override resolves to images.AgentLatestVersion, which is currently below the
// minimum, so v2 stays off until the operator default Agent version is bumped.
name: "no image override uses latest default",
override: nil,
want: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ddaSpec := &v2alpha1.DatadogAgentSpec{Override: tt.override}
assert.Equal(t, tt.want, activityDumpV2Supported(ddaSpec))
})
}
}

func Test_cwsFeature_ConfigureActivityDumpV2(t *testing.T) {
newDDASpec := func(v2 *bool, tag string) *v2alpha1.DatadogAgentSpec {
spec := &v2alpha1.DatadogAgentSpec{
Features: &v2alpha1.DatadogFeatures{
CWS: &v2alpha1.CWSFeatureConfig{
Enabled: ptr.To(true),
SecurityProfiles: &v2alpha1.CWSSecurityProfilesConfig{
Enabled: ptr.To(true),
V2: v2,
},
},
},
}
if tag != "" {
spec.Override = map[v2alpha1.ComponentName]*v2alpha1.DatadogAgentComponentOverride{
v2alpha1.NodeAgentComponentName: {Image: &v2alpha1.AgentImageConfig{Tag: tag}},
}
}
return spec
}

tests := []struct {
name string
v2 *bool
tag string
want bool
}{
{
name: "v2 requested on supported agent is enabled",
v2: ptr.To(true),
tag: "7.81.0",
want: true,
},
{
name: "v2 requested on old agent is gated off",
v2: ptr.To(true),
tag: "7.80.0",
want: false,
},
{
name: "v2 requested on unparseable tag is gated off",
v2: ptr.To(true),
tag: "custom-internal-build",
want: false,
},
{
name: "v2 not requested stays off even on supported agent",
v2: ptr.To(false),
tag: "7.81.0",
want: false,
},
{
name: "v2 unset stays off",
v2: nil,
tag: "7.81.0",
want: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
f := &cwsFeature{}
f.Configure(&v2alpha1.DatadogAgent{}, newDDASpec(tt.v2, tt.tag), nil)
assert.Equal(t, tt.want, f.activityDumpV2)
})
}
}

func cwsAgentNodeWantFunc(withSubFeatures bool, directSendFromSysProbe bool, enforcementEnabled bool) *test.ComponentTest {
return test.NewDefaultComponentTest().WithWantFunc(
func(t testing.TB, mgrInterface feature.PodTemplateManagers) {
Expand Down
Loading