Skip to content

feat(allowedpaths): prepend /host to symlink targets in containers#170

Merged
matt-dz merged 14 commits intomainfrom
matt-dz/container-symlink-host-prefix
Apr 3, 2026
Merged

feat(allowedpaths): prepend /host to symlink targets in containers#170
matt-dz merged 14 commits intomainfrom
matt-dz/container-symlink-host-prefix

Conversation

@matt-dz
Copy link
Copy Markdown
Collaborator

@matt-dz matt-dz commented Apr 2, 2026

Summary

In containerized Kubernetes environments, host symlinks use host-absolute paths (e.g. /var/log/pods/...) that don't include the /host mount prefix. The Private Action Runner in the Datadog agent mounts host volumes exclusively under /host, so these symlinks fail to resolve.

This PR adds container-aware symlink resolution:

  • HostPrefix public RunnerOption enables the feature and sets the mount prefix (defaults to /host)
  • When set, symlink targets resolved during cross-root fallback are prepended with the prefix (unless they already start with it, e.g. relative symlinks)
  • Fully user-configurable — no auto-detection via environment variables
  • containerized field in scenario YAML for end-to-end testing
  • SetHostPrefix / HostPrefix getter/setter on Sandbox for direct access

Closes #166

Test plan

  • Unit tests: Open/Stat/Access through container symlinks, non-containerized no-op, escape blocking, relative symlinks
  • Scenario tests: cat, ls, grep, multiple reads, all file commands, relative symlinks, blocked paths
  • HostPrefix ordering tests: before/after AllowedPaths, without AllowedPaths, default value
  • Full test suite passes (allowedpaths, interp, tests, analysis)
  • Windows tests skipped (container feature is not supported on Windows)
  • CI passes

🤖 Generated with Claude Code

matt-dz and others added 4 commits April 2, 2026 16:14
In containerized environments (DOCKER_DD_AGENT set), host symlinks use
host-absolute paths (e.g. /var/log/pods/...) that don't include the
/host mount prefix. When resolving cross-root symlinks, prepend /host
to the target path so it matches the container's allowed roots.

Refs #166

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ontainers

In containerized environments (DOCKER_DD_AGENT set), host symlinks use
host-absolute paths (e.g. /var/log/pods/...) that don't include the
/host mount prefix. When resolving cross-root symlinks, prepend the
host prefix so the path matches the container's allowed roots.

The host prefix is stored as a field on Sandbox (defaulting to /host)
so tests can override it with temp dirs.

Refs #166

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…iner symlinks

- Add SetHostPrefix on Sandbox and public HostPrefix RunnerOption
- Add containerized field to scenario YAML that sets DOCKER_DD_AGENT
  and host prefix to testdir/host automatically
- Groups with containerized scenarios skip t.Parallel (t.Setenv)
- Add container_host_prefix_symlink.yaml end-to-end scenario test

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
8 scenarios covering:
- cat through container symlink (host/var/log as single allowed root)
- ls directory listing through container symlink
- grep through container symlink
- multiple sequential reads
- cat/head/tail/wc/grep all through same container symlink
- blocked: symlink to /etc/secret outside allowed root
- blocked: symlink to /opt/data outside allowed root
- blocked: symlink using parent traversal to escape

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@matt-dz
Copy link
Copy Markdown
Collaborator Author

matt-dz commented Apr 2, 2026

@codex conduct a comprehensive security and code review

Copy link
Copy Markdown

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

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: abd098f351

ℹ️ 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 allowedpaths/sandbox.go Outdated
Comment thread allowedpaths/sandbox.go Outdated
matt-dz and others added 4 commits April 2, 2026 17:07
Remove the conditional check that skipped prepending when the path
already started with the host prefix. In containerized environments,
the host prefix is always prepended blindly to symlink targets.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The container host prefix feature is Linux-only (host mounts under
/host). Skip containerized scenarios on Windows where symlinks work
differently and the /host prefix concept doesn't apply.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Clean trailing slashes and other path artifacts via filepath.Clean
to prevent malformed prefix comparisons.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Explain that the Private Action Runner in the Datadog agent mounts
host volumes exclusively under /host, so the blind prepend is correct
for our deployment. Note the HostPrefix option for future changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@matt-dz
Copy link
Copy Markdown
Collaborator Author

matt-dz commented Apr 3, 2026

@codex conduct a comprehensive security and code review. note that we always prepend the host prefix when encountering a symlink in a containerized environment, that is the whole reason for this PR so you should not consider that a concern.

Copy link
Copy Markdown

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

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: 05e1891151

ℹ️ 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 interp/api.go Outdated
matt-dz and others added 2 commits April 3, 2026 09:16
Store the host prefix on the runner and apply it to the sandbox in
New() after all options are processed. HostPrefix can now be applied
before or after AllowedPaths without silently dropping the value.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add tests for:
- HostPrefix after AllowedPaths
- HostPrefix before AllowedPaths
- HostPrefix without AllowedPaths (silently ignored)
- Default prefix when HostPrefix is not called

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@matt-dz
Copy link
Copy Markdown
Collaborator Author

matt-dz commented Apr 3, 2026

@codex conduct a comprehensive security and code review. note that we always prepend the host prefix when encountering a symlink in a containerized environment, that is the whole reason for this PR so you should not consider that a concern.

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

ℹ️ 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".

…enarios

- Rename GetHostPrefix() to HostPrefix() per Effective Go naming (no
  Get prefix on getters)
- Load scenarios once per group and reuse, avoiding double loadScenario
  calls in the containerized check loop
- Fix skip message: containerized tests are unsupported on Windows,
  not Linux-only

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@matt-dz
Copy link
Copy Markdown
Collaborator Author

matt-dz commented Apr 3, 2026

@codex conduct a comprehensive security and code review. note that we always prepend the host prefix when encountering a symlink in a containerized environment, that is the whole reason for this PR so you should not consider that a concern.

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Swish!

ℹ️ 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".

Container host prefix is not supported on Windows. Skip the three
HostPrefix ordering tests that fail due to filepath.Clean converting
forward slashes to backslashes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment thread allowedpaths/sandbox.go Outdated
@matt-dz matt-dz marked this pull request as ready for review April 3, 2026 13:45
@matt-dz matt-dz enabled auto-merge April 3, 2026 13:50
Comment thread allowedpaths/sandbox.go
Comment thread allowedpaths/sandbox_unix_test.go
matt-dz and others added 2 commits April 3, 2026 10:05
Remove auto-detection via DOCKER_DD_AGENT env var. Container symlink
resolution is now enabled by calling HostPrefix — a non-empty prefix
activates the feature. This removes:
- containerized bool from Sandbox
- os.Getenv("DOCKER_DD_AGENT") from New()
- defaultHostMountPrefix const
- t.Setenv and parallel restrictions from test harness

The scenario harness sets HostPrefix directly via the RunnerOption.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…er prefix

Relative symlinks (e.g. ../pods/app.log) resolve to paths that already
include the host prefix. Skip prepending to avoid double-prefixing.
Added unit test and scenario test for relative symlinks in container mode.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@matt-dz matt-dz requested a review from thieman April 3, 2026 14:12
@matt-dz matt-dz added this pull request to the merge queue Apr 3, 2026
Merged via the queue into main with commit 743e9fb Apr 3, 2026
34 checks passed
@matt-dz matt-dz deleted the matt-dz/container-symlink-host-prefix branch April 3, 2026 14:24
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.

bug(allowedpaths): cannot read /var/log/containers logs in Kubernetes/container environments due to symlinks

3 participants