Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
8781812
Add privileged rshell execution path
astuyve Jul 21, 2026
28fa069
Bootstrap Agent build tooling on Linux targets
astuyve Jul 22, 2026
5e8d9af
Add native target triples to helper build script
astuyve Jul 22, 2026
38b5bfd
fix script to use gh release download
astuyve Jul 23, 2026
f3edfc7
forward verified signing keys to rshell helper
astuyve Jul 23, 2026
9576321
Update rshell for helper authorization diagnostics
astuyve Jul 27, 2026
b8de5aa
Update rshell path policy intersection
astuyve Jul 27, 2026
bb78c08
feat(par): package sandboxed rshell helper
astuyve Aug 28, 2026
523135a
feat(privateactionrunner): validate rshell keys with TUF Director
astuyve Aug 31, 2026
8cfd18e
feat: make privileged rshell policy optional
astuyve Aug 31, 2026
6ac4eb6
Merge remote-tracking branch 'origin/main' into rfc/privileged-rshell…
astuyve Sep 1, 2026
81c51de
feat(installer): install privileged rshell helper
astuyve Sep 2, 2026
b69d01e
Bump rshell privileged helper revision
astuyve Sep 2, 2026
a00f4d1
fix(installer): shorten generated systemd fixture paths
astuyve Sep 2, 2026
95a6ba0
fix(installer): scope rshell fixture path shortening
astuyve Sep 2, 2026
f63d19f
chore: update rshell helper revision
astuyve Sep 2, 2026
4b62c83
Fix: Enforce root ownership for the systemd service definition so the…
astuyve Sep 2, 2026
7691a1e
bzl
astuyve Sep 2, 2026
cc0391e
chore: update rshell helper revision
astuyve Sep 2, 2026
9af1c1e
fix(par): allow privileged read-only rshell actions
astuyve Sep 2, 2026
8444d22
refactor(remote-config): split TUF proof provider interface
astuyve Sep 2, 2026
33c29e1
fix(par): harden privileged rshell lifecycle
astuyve Sep 2, 2026
adf2e32
fix(fleet): preserve agent ownership during rshell setup
astuyve Sep 3, 2026
46d8c3b
Merge remote-tracking branch 'origin/main' into rfc/privileged-rshell…
astuyve Sep 3, 2026
c553a1b
remove plan and custom build script
astuyve Sep 3, 2026
53b511c
remove plan and custom build script
astuyve Sep 3, 2026
1806704
Bump static quality gates
astuyve Sep 3, 2026
227ad0c
Use rshell v0.0.26 and combine quality gate bumps
astuyve Sep 3, 2026
56565d7
Merge remote-tracking branch 'origin/main' into rfc/privileged-rshell…
astuyve Sep 3, 2026
a4a4f07
Build rshell with Bazel
astuyve Sep 3, 2026
5c66aab
Move rshell dependency anchor under product
astuyve Sep 3, 2026
196069a
Bump static quality gates
astuyve Sep 3, 2026
1f31c02
release note
astuyve Sep 3, 2026
d86178c
fix(installer): decouple rshell units from action runner
astuyve Sep 3, 2026
ecbf20f
fix: Revert stupid claude suggestion, disable privileged helper servi…
astuyve Sep 3, 2026
54e8a66
Merge remote-tracking branch 'origin/main' into rfc/privileged-rshell…
astuyve Sep 4, 2026
c5ee00e
Merge branch 'main' into rfc/privileged-rshell-helper
astuyve Sep 4, 2026
1199dcf
Merge branch 'main' into rfc/privileged-rshell-helper
astuyve Sep 4, 2026
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
1 change: 1 addition & 0 deletions .copyright-overrides.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ golang.org/x/*: "Copyright (c) 2009 The Go Authors. All rights reserved"
gopkg.in/DataDog/*: Copyright 2016-Present Datadog, Inc.
gopkg.in/yaml.v2: "Copyright 2011-2016 Canonical Ltd"
k8s.io/*: Copyright 2014 The Kubernetes Authors.
kernel.org/pub/linux/libs/security/libcap/psx: Copyright (c) 2019,20,24 Andrew G. Morgan <morgan@kernel.org>
sigs.k8s.io/*: Copyright 2017 The Kubernetes Authors.
contrib.go.opencensus.io/exporter/prometheus: Copyright 2020, OpenCensus Authors
go.opencensus.io: Copyright 2018, OpenCensus Authors
Expand Down
3 changes: 3 additions & 0 deletions .wwhrd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ allowlist:
- FreeBSD

overrides:
# libcap/psx is dual-licensed under BSD-3-Clause OR GPL-2.0-only. Select the
# permissive option; automatic detection otherwise prefers the GPL text.
"kernel.org/pub/linux/libs/security/libcap/psx": BSD-3-Clause
# https://github.com/bmizerany/pat/blob/master/LICENSE
"github.com/bmizerany/pat": MIT
# https://github.com/xi2/xz/blob/master/LICENSE
Expand Down
5 changes: 5 additions & 0 deletions LICENSE-3rdparty.csv
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ core,github.com/DataDog/rshell/allowedpaths,Apache-2.0,"Copyright 2026-present D
core,github.com/DataDog/rshell/allowedpaths/internal/fsstat,Apache-2.0,"Copyright 2026-present Datadog, Inc"
core,github.com/DataDog/rshell/allowedpaths/internal/writeopen,Apache-2.0,"Copyright 2026-present Datadog, Inc"
core,github.com/DataDog/rshell/builtins,Apache-2.0,"Copyright 2026-present Datadog, Inc"
core,github.com/DataDog/rshell/builtins/awk,Apache-2.0,"Copyright 2026-present Datadog, Inc"
core,github.com/DataDog/rshell/builtins/break,Apache-2.0,"Copyright 2026-present Datadog, Inc"
core,github.com/DataDog/rshell/builtins/cat,Apache-2.0,"Copyright 2026-present Datadog, Inc"
core,github.com/DataDog/rshell/builtins/cd,Apache-2.0,"Copyright 2026-present Datadog, Inc"
Expand Down Expand Up @@ -330,6 +331,7 @@ core,github.com/DataDog/rshell/builtins/pwd,Apache-2.0,"Copyright 2026-present D
core,github.com/DataDog/rshell/builtins/read,Apache-2.0,"Copyright 2026-present Datadog, Inc"
core,github.com/DataDog/rshell/builtins/rm,Apache-2.0,"Copyright 2026-present Datadog, Inc"
core,github.com/DataDog/rshell/builtins/sed,Apache-2.0,"Copyright 2026-present Datadog, Inc"
core,github.com/DataDog/rshell/builtins/sha256sum,Apache-2.0,"Copyright 2026-present Datadog, Inc"
core,github.com/DataDog/rshell/builtins/sort,Apache-2.0,"Copyright 2026-present Datadog, Inc"
core,github.com/DataDog/rshell/builtins/ss,Apache-2.0,"Copyright 2026-present Datadog, Inc"
core,github.com/DataDog/rshell/builtins/stat,Apache-2.0,"Copyright 2026-present Datadog, Inc"
Expand All @@ -350,6 +352,7 @@ core,github.com/DataDog/rshell/internal/interpoption,Apache-2.0,"Copyright 2026-
core,github.com/DataDog/rshell/internal/systemd,Apache-2.0,"Copyright 2026-present Datadog, Inc"
core,github.com/DataDog/rshell/internal/version,Apache-2.0,"Copyright 2026-present Datadog, Inc"
core,github.com/DataDog/rshell/interp,Apache-2.0,"Copyright 2026-present Datadog, Inc"
core,github.com/DataDog/rshell/privilegedhelper,Apache-2.0,"Copyright 2026-present Datadog, Inc"
core,github.com/DataDog/sketches-go/ddsketch,Apache-2.0,"Copyright 2021 Datadog, Inc"
core,github.com/DataDog/sketches-go/ddsketch/encoding,Apache-2.0,"Copyright 2021 Datadog, Inc"
core,github.com/DataDog/sketches-go/ddsketch/mapping,Apache-2.0,"Copyright 2021 Datadog, Inc"
Expand Down Expand Up @@ -1564,6 +1567,7 @@ core,github.com/kr/pretty,MIT,Copyright 2012 Keith Rarick
core,github.com/kr/text,MIT,Copyright 2012 Keith Rarick
core,github.com/kylelemons/godebug/diff,Apache-2.0,Copyright (c) 2013-2020 Kyle Lemons
core,github.com/kylelemons/godebug/pretty,Apache-2.0,Copyright (c) 2013-2020 Kyle Lemons
core,github.com/landlock-lsm/go-landlock/landlock/syscall,MIT,Copyright (c) 2021 Günther Noack
core,github.com/leodido/go-syslog/v4,MIT,"Copyright (c) 2018, Leonardo Di Donato"
core,github.com/leodido/go-syslog/v4/auto,MIT,"Copyright (c) 2018, Leonardo Di Donato"
core,github.com/leodido/go-syslog/v4/ciscoios,MIT,"Copyright (c) 2018, Leonardo Di Donato"
Expand Down Expand Up @@ -4498,6 +4502,7 @@ core,k8s.io/utils/path,Apache-2.0,Copyright 2014 The Kubernetes Authors.
core,k8s.io/utils/ptr,Apache-2.0,Copyright 2014 The Kubernetes Authors.
core,k8s.io/utils/strings/slices,Apache-2.0,Copyright 2014 The Kubernetes Authors.
core,k8s.io/utils/trace,Apache-2.0,Copyright 2014 The Kubernetes Authors.
core,kernel.org/pub/linux/libs/security/libcap/psx,BSD-3-Clause,"Copyright (c) 2019,20,24 Andrew G. Morgan <morgan@kernel.org>"
core,mellium.im/sasl,BSD-2-Clause,Copyright © 2014 The Mellium Contributors
core,mvdan.cc/sh/v3/expand,BSD-3-Clause,"Copyright (c) 2016, Daniel Martí. All rights reserved"
core,mvdan.cc/sh/v3/fileutil,BSD-3-Clause,"Copyright (c) 2016, Daniel Martí. All rights reserved"
Expand Down
6 changes: 6 additions & 0 deletions comp/remote-config/rcclient/def/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ type Component interface {
Subscribe(product data.Product, fn func(update map[string]state.RawConfig, applyStateCallback func(string, state.ApplyStatus)))
}

// TUFProofProvider exposes the Director proof for a Remote Config target.
type TUFProofProvider interface {
// GetConfigTUFProof returns the Director proof for one Remote Config target.
GetConfigTUFProof(targetPath string) (state.ConfigTUFProof, bool)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Update all RC client implementations

Affected test packages fail to compile and block CI.

Assertion details
  • Input: Compile a test package that assigns an existing mock to rcclient.Component.
  • Expected: Update all RC client implementations, or use a smaller interface for proof access.
  • Actual: Existing mock RC clients do not implement GetConfigTUFProof. Packages that use these mocks do not compile.

Was this helpful? React 👍 or 👎
🤖 Datadog Autotest · What is Autotest? · @DataDog review to ask questions · Any feedback? Reach out in #autotest · Open Bits AI session

@astuyve astuyve Sep 2, 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.

Addressed: the production RC component and adapter implement GetConfigTUFProof, and all five test doubles implementing rcclient.Component now provide the method as well. Focused tests for rcclient, queryactions, datasecurity, datastreams, SNMP check config, eBPF, and private action runner all pass.

}

// Params is the input parameter struct for the RC client Component.
type Params struct {
AgentName string
Expand Down
10 changes: 10 additions & 0 deletions comp/remote-config/rcclient/impl/rcclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ type rcClient struct {
IPC ipc.Component
}

var _ rcclient.TUFProofProvider = (*rcClient)(nil)

// Dependencies defines the dependencies for the rcclient component.
type Dependencies struct {
compdef.In
Expand Down Expand Up @@ -366,6 +368,14 @@ func (rc *rcClient) Subscribe(product data.Product, fn func(update map[string]st
rc.client.Subscribe(string(product), fn)
}

// GetConfigTUFProof returns the current Director proof for a Remote Config target.
func (rc *rcClient) GetConfigTUFProof(targetPath string) (state.ConfigTUFProof, bool) {
if rc.client == nil {
return state.ConfigTUFProof{}, false
}
return rc.client.GetConfigTUFProof(targetPath)
}

func (rc *rcClient) agentConfigUpdateCallback(updates map[string]state.RawConfig, applyStateCallback func(string, state.ApplyStatus)) {
mergedConfig, err := state.MergeRCAgentConfig(rc.client.UpdateApplyStatus, updates)
if err != nil {
Expand Down
9 changes: 9 additions & 0 deletions deps/go.MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ go_deps.gazelle_override(
build_extra_args = ["-build_tags=trivy_no_javadb"],
path = "github.com/aquasecurity/trivy",
)
go_deps.gazelle_override(
directives = [
"gazelle:go_visibility @@//pkg/privateactionrunner/rshell:__pkg__",
"gazelle:resolve go github.com/DataDog/datadog-agent/pkg/fleet/installer/telemetry @@//pkg/fleet/installer/telemetry:telemetry",
"gazelle:resolve go github.com/DataDog/datadog-agent/pkg/remoteconfig/state @@//pkg/remoteconfig/state:state",
],
path = "github.com/DataDog/rshell",
)
use_repo(
go_deps,
"cat_dario_mergo",
Expand Down Expand Up @@ -209,6 +217,7 @@ use_repo(
"com_github_kouhin_envflag",
"com_github_kr_pretty",
"com_github_kraken_hpc_go_fork",
"com_github_landlock_lsm_go_landlock",
"com_github_lightstep_go_expohisto",
"com_github_lorenzosaino_go_sysctl",
"com_github_lxn_walk",
Expand Down
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ require (
github.com/DataDog/go-acl v1.0.1
github.com/DataDog/go-sqllexer v0.2.4
github.com/DataDog/jsonapi v0.13.0
github.com/DataDog/rshell v0.0.25
github.com/DataDog/rshell v0.0.26
github.com/DataDog/sketches-go v1.4.8
github.com/DataDog/watermarkpodautoscaler/apis v0.0.0-20250108152814-82e58d0231d1
github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571
Expand Down Expand Up @@ -325,6 +325,7 @@ require (
github.com/kouhin/envflag v0.0.0-20150818174321-0e9a86061649
github.com/kr/pretty v0.3.1
github.com/kraken-hpc/go-fork v0.1.1
github.com/landlock-lsm/go-landlock v0.10.0
github.com/lorenzosaino/go-sysctl v0.3.1
github.com/lxn/walk v0.0.0-20210112085537-c389da54e794
github.com/lxn/win v0.0.0-20210218163916-a377121e959e
Expand Down Expand Up @@ -1165,6 +1166,7 @@ require (
k8s.io/kms v0.35.5 // indirect
k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad // indirect
k8s.io/sample-controller v0.35.3 // indirect
kernel.org/pub/linux/libs/security/libcap/psx v1.2.77 // indirect
mellium.im/sasl v0.3.2 // indirect
modernc.org/sqlite v1.53.0 // indirect
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 // indirect
Expand Down
8 changes: 6 additions & 2 deletions go.sum

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

1 change: 1 addition & 0 deletions omnibus/config/software/datadog-agent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@
end

if linux_target?
command "bazel run #{omnibazel_flags} //pkg/privateactionrunner/rshell:install -- --destdir=#{install_dir}", :env => env, :live_stream => Omnibus.logger.live_stream(:info)
command "bazel run #{omnibazel_flags} //pkg/privateactionrunner/par-control:install -- --destdir=#{install_dir}", :env => env, :live_stream => Omnibus.logger.live_stream(:info)
end
end
Expand Down
1 change: 1 addition & 0 deletions packages/agent/product/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ pkg_filegroup(
"//packages/agent:linux_default": [
"//pkg/discovery/module/rust:all_files",
"//pkg/privateactionrunner/par-control:all_files_linux",
"//pkg/privateactionrunner/rshell:all_files_linux",
"//pkg/procmgr/rust:all_files_linux",
],
"//packages/agent:linux_fips": [
Expand Down
15 changes: 15 additions & 0 deletions pkg/config/example/datadog-agent_windows.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -4761,6 +4761,21 @@ api_key:
#
# agent_secret_management_enabled: true

# # @param restricted_shell - custom object - optional
# # Local restrictions for remote rshell actions. Privileged execution has
# # an additional administrator-controlled opt-in and requires the systemd
# # socket. On Linux, a root-owned /etc/datadog-agent-rshell/policy.json
# # can optionally narrow the backend-provided command and path policy.
#
# restricted_shell:
# allowed_commands:
# - rshell:*
# allowed_paths:
# - /
# privileged:
# enabled: false
# socket: /run/datadog/rshell-privileged.sock

# # @param http_timeout_seconds - integer - optional - default: 30
# # @env DD_PRIVATE_ACTION_RUNNER_HTTP_TIMEOUT_SECONDS - integer - optional - default: 30
# # Maximum time in seconds for HTTP actions before timing out. Must be > 1.
Expand Down
17 changes: 16 additions & 1 deletion pkg/config/remote/client/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
load("@rules_go//go:def.bzl", "go_library")
load("//bazel/rules/go:dd_agent_go_test.bzl", "dd_agent_go_test")

go_library(
name = "client",
srcs = ["client.go"],
srcs = [
"client.go",
"tuf_proof.go",
],
importpath = "github.com/DataDog/datadog-agent/pkg/config/remote/client",
visibility = ["//visibility:public"],
deps = [
Expand All @@ -19,3 +23,14 @@ go_library(
"@org_uber_go_atomic//:atomic",
],
)

dd_agent_go_test(
name = "client_test",
srcs = ["tuf_proof_test.go"],
embed = [":client"],
deps = [
"//pkg/proto/pbgo/core",
"@com_github_stretchr_testify//assert",
"@com_github_stretchr_testify//require",
],
)
35 changes: 23 additions & 12 deletions pkg/config/remote/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ type Client struct {

state *state.Repository

proofMu sync.RWMutex
proofRoots [][]byte
proofTargets []byte
proofTargetFiles map[string][]byte

listeners map[string][]Listener

// Elements that can be changed during the execution of listeners
Expand Down Expand Up @@ -321,17 +326,18 @@ func newClient(cf ConfigFetcher, opts ...func(opts *Options)) (*Client, error) {
installerState.Store(&pbgo.ClientUpdater{})

return &Client{
Options: options,
ID: generateID(),
startupSync: sync.Once{},
ctx: ctx,
closeFn: cloneFn,
cwsWorkloads: cwsWorkloads,
installerState: installerState,
state: repository,
backoffPolicy: backoffPolicy,
listeners: make(map[string][]Listener),
configFetcher: cf,
Options: options,
ID: generateID(),
startupSync: sync.Once{},
ctx: ctx,
closeFn: cloneFn,
cwsWorkloads: cwsWorkloads,
installerState: installerState,
state: repository,
proofTargetFiles: make(map[string][]byte),
backoffPolicy: backoffPolicy,
listeners: make(map[string][]Listener),
configFetcher: cf,
}, nil
}

Expand Down Expand Up @@ -563,7 +569,12 @@ func (c *Client) applyUpdate(pbUpdate *pbgo.ClientGetConfigsResponse) ([]string,
ClientConfigs: pbUpdate.ClientConfigs,
}

return c.state.Update(update)
changedProducts, err := c.state.Update(update)
if err != nil {
return nil, err
}
c.storeConfigTUFProof(pbUpdate)
return changedProducts, nil
}

// newUpdateRequests builds a new request for the agent based on the current state of the
Expand Down
70 changes: 70 additions & 0 deletions pkg/config/remote/client/tuf_proof.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2026-present Datadog, Inc.

package client

import (
"slices"

pbgo "github.com/DataDog/datadog-agent/pkg/proto/pbgo/core"
"github.com/DataDog/datadog-agent/pkg/remoteconfig/state"
)

// GetConfigTUFProof returns a defensive copy of the current Director proof for
// targetPath. It returns false until the target and signed Targets metadata have
// both been received from the Core Agent.
func (c *Client) GetConfigTUFProof(targetPath string) (state.ConfigTUFProof, bool) {
c.proofMu.RLock()
defer c.proofMu.RUnlock()

targetFile, ok := c.proofTargetFiles[targetPath]
if !ok || len(c.proofTargets) == 0 {
return state.ConfigTUFProof{}, false
}
return state.ConfigTUFProof{
Roots: cloneByteSlices(c.proofRoots),
Targets: slices.Clone(c.proofTargets),
TargetPath: targetPath,
TargetFile: slices.Clone(targetFile),
}, true
}

// storeConfigTUFProof retains the complete proof chain from the bootstrap root
// reported by this downstream client. It is called only after the corresponding
// repository update has been accepted.
func (c *Client) storeConfigTUFProof(update *pbgo.ClientGetConfigsResponse) {
if len(update.Targets) == 0 {
return
}

c.proofMu.Lock()
defer c.proofMu.Unlock()

for _, root := range update.Roots {
c.proofRoots = append(c.proofRoots, slices.Clone(root))
}
c.proofTargets = slices.Clone(update.Targets)

currentTargets := make(map[string]struct{}, len(update.ClientConfigs))
for _, targetPath := range update.ClientConfigs {
currentTargets[targetPath] = struct{}{}
}
for targetPath := range c.proofTargetFiles {
if _, ok := currentTargets[targetPath]; !ok {
delete(c.proofTargetFiles, targetPath)
}
}
for _, targetFile := range update.TargetFiles {
c.proofTargetFiles[targetFile.Path] = slices.Clone(targetFile.Raw)
}
}

func cloneByteSlices(values [][]byte) [][]byte {
cloned := make([][]byte, len(values))
for i, value := range values {
cloned[i] = slices.Clone(value)
}
return cloned
}
Loading
Loading