Skip to content

[PROF-14068] Remove privileges for host-profiler#2953

Merged
gh-worker-dd-mergequeue-cf854d[bot] merged 9 commits into
mainfrom
theomagellan/unprivileged-host-profiler
May 19, 2026
Merged

[PROF-14068] Remove privileges for host-profiler#2953
gh-worker-dd-mergequeue-cf854d[bot] merged 9 commits into
mainfrom
theomagellan/unprivileged-host-profiler

Conversation

@theomagellan

@theomagellan theomagellan commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

This PR mirrors DataDog/helm-charts#2586 for datadog-operator:

  • removes privileges: true and replaces by list of capabilities
  • adds support for apparmor profiles
  • embeds seccomp profile
  • adds host-profiler related FQDN to Agent's Cilium allow-list
    • intake.profile.%s: profiling intake
    • sourcemap-intake.%s: symbol intake
    • otlp.%s: OTLP metrics intake

Motivation

https://datadoghq.atlassian.net/browse/REVIEW-85?focusedCommentId=3201542

Additional Notes

Anything else we should know when reviewing?

Minimum Agent Versions

Are there minimum versions of the Datadog Agent and/or Cluster Agent required?

  • Agent: vX.Y.Z
  • Cluster Agent: vX.Y.Z

Describe your test plan

Tested on a cluster with the host-profiler feature enabled via agent.datadoghq.com/host-profiler-enabled: "true" annotation on the DDA.

Profiles for both supported architectures can be found here

Checklist

  • PR has at least one valid label: bug, enhancement, refactoring, documentation, tooling, and/or dependencies
  • PR has a milestone or the qa/skip-qa label
  • All commits are signed (see: signing commits)

@theomagellan
theomagellan force-pushed the theomagellan/unprivileged-host-profiler branch from 5504b59 to be37a57 Compare April 28, 2026 08:54
@theomagellan theomagellan added the enhancement New feature or request label Apr 28, 2026
@codecov-commenter

codecov-commenter commented Apr 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.85981% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 42.20%. Comparing base (20ecb9e) to head (1720d02).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
...ntroller/datadogagent/component/objects/network.go 0.00% 6 Missing ⚠️
...oller/datadogagent/feature/hostprofiler/feature.go 92.00% 2 Missing and 2 partials ⚠️
internal/controller/datadogagent/feature/types.go 0.00% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #2953      +/-   ##
==========================================
+ Coverage   41.50%   42.20%   +0.69%     
==========================================
  Files         335      337       +2     
  Lines       28714    29290     +576     
==========================================
+ Hits        11919    12363     +444     
- Misses      16001    16113     +112     
- Partials      794      814      +20     
Flag Coverage Δ
unittests 42.20% <94.85%> (+0.69%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...controller/datadogagent/component/agent/default.go 47.17% <100.00%> (+3.01%) ⬆️
...oller/datadogagent/feature/hostprofiler/seccomp.go 100.00% <100.00%> (ø)
internal/controller/datadogagent/feature/types.go 22.10% <0.00%> (ø)
...oller/datadogagent/feature/hostprofiler/feature.go 82.00% <92.00%> (+4.22%) ⬆️
...ntroller/datadogagent/component/objects/network.go 0.00% <0.00%> (ø)

... and 5 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 20ecb9e...1720d02. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@datadog-prod-us1-5

datadog-prod-us1-5 Bot commented Apr 28, 2026

Copy link
Copy Markdown

Code Coverage

🎯 Code Coverage (details)
Patch Coverage: 94.86%
Overall Coverage: 42.52% (+0.45%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 1720d02 | Docs | Datadog PR Page | Give us feedback!

@theomagellan
theomagellan force-pushed the theomagellan/unprivileged-host-profiler branch 2 times, most recently from b23d2c1 to 87b1df2 Compare May 6, 2026 09:51
@theomagellan

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 87b1df2f66

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/controller/datadogagent/feature/hostprofiler/feature.go
@theomagellan
theomagellan marked this pull request as ready for review May 6, 2026 14:50
@theomagellan
theomagellan requested a review from a team May 6, 2026 14:50
@theomagellan
theomagellan requested a review from a team as a code owner May 6, 2026 14:50

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7847cf22fa

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/controller/datadogagent/feature/hostprofiler/feature.go
managers.SecurityContext().AddCapabilitiesToContainer(agent.DefaultCapabilitiesForHostProfiler(), apicommon.HostProfiler)

// AppArmor annotation
managers.Annotation().AddAnnotation(common.AppArmorAnnotationKey+"/"+string(apicommon.HostProfiler), "unconfined")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

AppArmor: Do we want to expose a setting to override the "unconfined" ? I'm not familiar with how someone would override this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

You can change it by changing the datadog agent's manifest and override the container.apparmor.security.beta.kubernetes.io/host-profiler annotation

As discussed on Thursday though, the profile provisioning is left to the user; neither the helm chart or the operator allow us to provision one automatically, that's why it's unconfined by default

@@ -76,7 +76,7 @@ func (rc *RequiredComponent) IsConfigured() bool {
// IsPrivileged checks whether component requires privileged access.
func (rc *RequiredComponent) IsPrivileged() bool {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

NIT, we are no longer privileged, so this could be slightly confusing 😄

@theomagellan theomagellan May 11, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

What do we consider as "privileged?" afaik system-probe is also not privileged but runs with elevated capabilities so I was mirroring that. This was done in response to #2953 (comment) but I can revert if you feel strongly about it :)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Your change is good, I was just mentioning the name of the function
This is really minor.

SecurityContext: &corev1.SecurityContext{
ReadOnlyRootFilesystem: ptr.To(true),
ReadOnlyRootFilesystem: ptr.To(true),
AllowPrivilegeEscalation: ptr.To(false),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@r1viollet regarding DataDog/helm-charts#2586 (comment) and why we the seccomp allowed for GID/UID operations among other unnecessary syscalls:

It turns out that leaving AllowPrivilegeEscalation empty was in effect setting it to true, and this would cause runc to apply the seccomp profile before totally finishing its setup, including switching users from root to unprivileged! Those syscalls then got through my first syscall audit and got added to the seccomp profile 😁

helm-charts also has this issue, I will have to do a follow-up PR to both tighten seccomp allowlist and fix this.

I'm including the fix in this PR but will update the seccomp in a follow-up PR to keep the seccomp profile consistent between both operator and helm.

  - favor a list of capabilities
  - seccomp profile
  - support for custom apparmor profile
  Without it, seccomp restrictions are in place too soon, meaning runc's own
  `setuid/setgid/setgroups/capset` calls during container setup are subject to our
  filter and would need to be allowlisted.
@theomagellan
theomagellan force-pushed the theomagellan/unprivileged-host-profiler branch from 2bed0b9 to 26e28a5 Compare May 18, 2026 08:50

@r1viollet r1viollet left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM

@tbavelier tbavelier left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not sure how feasible it is, but would it be possible to make all these changes solely inside the feature/hostprofiler code path instead of inside common + default ? I believe/understand you followed the pattern from system-probe but system-probe is in a slightly different position where it is used by multiple features while host-profiler is self-contained, so would be ideal if it's fully managed by the feature code path. It might not be technically possible however, would need to be investigated

@tbavelier tbavelier added this to the v1.28.0 milestone May 18, 2026
@theomagellan
theomagellan force-pushed the theomagellan/unprivileged-host-profiler branch from b9c29ec to c57fb7e Compare May 18, 2026 17:50
@theomagellan

theomagellan commented May 18, 2026

Copy link
Copy Markdown
Contributor Author

Not sure how feasible it is, but would it be possible to make all these changes solely inside the feature/hostprofiler code path instead of inside common + default ? I believe/understand you followed the pattern from system-probe but system-probe is in a slightly different position where it is used by multiple features while host-profiler is self-contained, so would be ideal if it's fully managed by the feature code path. It might not be technically possible however, would need to be investigated

That's correct, I followed system-probe as a guide for the host-profiler 😅
I took a shot at it in b03042c and deploying it on my test cluster tells me that everything seems right.
Thank you for your input! Re-requesting a review as soon as CI passes 🙇

@theomagellan
theomagellan force-pushed the theomagellan/unprivileged-host-profiler branch from c57fb7e to b03042c Compare May 19, 2026 08:15
@theomagellan
theomagellan requested a review from tbavelier May 19, 2026 09:29
@tbavelier

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@tbavelier tbavelier left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

slices comment not important, but the one about the init-container image is thus requesting changes

@tbavelier tbavelier May 19, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit but slices can probably be used here to simplify/rewrite some helpers/assertions. Does not matter tho

func buildSeccompSetupInitContainer() corev1.Container {
return corev1.Container{
Name: "host-profiler-seccomp-setup",
Image: images.GetLatestAgentImage(),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

See #3030 but tl;dr, make sure to use the same image as the other containers to avoid pulling it twice. Can be reproduced in current state with spec.global.registry: public.ecr.aws (or something different from the default gcr.io), and init-container will still pull from gcr.io

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thank you so much for the draft PR! Took the liberty to cherry-pick the commit directly :)

@gh-worker-dd-mergequeue-cf854d
gh-worker-dd-mergequeue-cf854d Bot merged commit f636740 into main May 19, 2026
57 checks passed
@gh-worker-dd-mergequeue-cf854d
gh-worker-dd-mergequeue-cf854d Bot deleted the theomagellan/unprivileged-host-profiler branch May 19, 2026 17:47
tbavelier added a commit that referenced this pull request May 20, 2026
remove privileges for the host profiler:
  - favor a list of capabilities
  - seccomp profile
  - support for custom apparmor profile

add host profiler related FQDN to agent cilium egress allow list

remove cap_sys_admin to favor stricter caps

add tests

hostProfiler should be considered as privileged

drop all caps before adding necessary ones

explicitly set AllowPrivilegeEscalation to false:
  Without it, seccomp restrictions are in place too soon, meaning runc's own
  `setuid/setgid/setgroups/capset` calls during container setup are subject to our
  filter and would need to be allowlisted.

migrate everything to inside hostprofiler feature

Use resolved image for host-profiler seccomp init

Co-authored-by: tbavelier <[email protected]>
Co-authored-by: theo.demagalhaes <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants