Skip to content

fix: constrain DAG resolution to configured directories - #2424

Merged
yohamta0 merged 3 commits into
mainfrom
agent/contain-dag-paths
Jul 25, 2026
Merged

yohamta0 merged 3 commits into
mainfrom
agent/contain-dag-paths

Conversation

@yohamta0

@yohamta0 yohamta0 commented Jul 25, 2026 •

Copy link
Copy Markdown
Member

Summary

  • constrain DAG file resolution to the configured DAG directory and explicit alternate/runtime search directories
  • allow nested DAG paths when they remain beneath an approved directory
  • reject absolute, parent-traversal, and symlink paths that escape those directories
  • make CLI-local YAML lookup opt in to its containing directory explicitly

Root cause

locateDAG returned separator-containing paths directly and implicitly searched the process working directory. Callers that invoke the API service in process do not pass through the REST filename-validation middleware, so an untrusted path could reach the filesystem resolver.

Resolution is now enforced at the shared storage boundary with lexical and symlink-aware containment. This covers REST, MCP, and other callers consistently while preserving explicitly configured search directories needed by local and distributed execution.

Behavior

Existing DAG files can be resolved through paths such as team/jobs/report.yaml when they are beneath the configured DAG directory. Resolution outside approved roots returns DAG-not-found. DAG listing and creation behavior remain unchanged; this PR makes nested paths safe to resolve without expanding the broader DAG identity model.

Testing

  • make fmt
  • complete tests for internal/persis/file/dag, internal/cmd, internal/service/mcp, and internal/service/frontend/api/v1
  • race-enabled tests for internal/persis/file/dag and internal/cmd

Summary by cubic

Constrain DAG resolution to configured directories and explicit search paths to prevent escapes, while allowing nested paths under approved roots. Normalize stored SourceFile to the symlink-resolved file path.

  • Bug Fixes
    • Enforce lexical and symlink-aware containment with fileutil.ResolveExistingPathWithinBase in internal/persis/file/dag; handle YAML extensions inside the containment check.
    • Drop "." from default search paths; search base dir first, then SearchPaths.
    • Make CLI YAML lookup opt-in by scoping to the file’s directory and resolving absolute/relative nested paths (internal/cmd).
    • Add/adjust tests to allow nested paths and explicit search dirs, reject outside and symlink escapes, expect SourceFile to match EvalSymlinks, and make the relative nested-path start case portable.

Written for commit bd0d2e9. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Bug Fixes
    • Improved DAG file discovery for YAML files provided by path.
    • Added support for nested DAG paths within configured directories.
    • Prevented access to files outside configured directories, including through path traversal and symlinks.
    • Improved handling of explicitly configured search paths.

Copilot AI review requested due to automatic review settings July 25, 2026 02:34

Copilot AI left a comment

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Jul 25, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

DAG storage now searches deterministic configured directories, constrains candidate resolution within those directories, and rejects traversal or symlink escapes. YAML DAG name extraction supplies the input file’s directory as the search path.

Changes

DAG path resolution

Layer / File(s) Summary
Bounded DAG storage lookup
internal/persis/file/dag/store.go, internal/persis/file/dag/store_test.go
Search paths are built from baseDir and configured search paths, while DAG candidates are resolved only within those directories. Tests cover nested paths, external paths, symlink escapes, and explicit search paths.
Command file-context lookup
internal/cmd/helper.go
extractDAGName initializes the DAG store using the directory of the provided YAML file path.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant extractDAGName
  participant Storage.GetSpec
  participant Storage.locateDAG
  participant Filesystem
  extractDAGName->>Storage.GetSpec: provide file directory as SearchPaths
  Storage.GetSpec->>Storage.locateDAG: resolve DAG name or path
  Storage.locateDAG->>Filesystem: validate candidate within search directory
  Filesystem-->>Storage.locateDAG: existing path or rejection
  Storage.locateDAG-->>Storage.GetSpec: DAG path or ErrDAGNotFound
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title is concise and accurately summarizes the main change: constraining DAG resolution to configured directories.
Description check ✅ Passed The PR description covers summary, root cause, behavior, and testing, but omits the template's Changes, Related Issues, and Checklist sections.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/contain-dag-paths

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@yohamta0
yohamta0 marked this pull request as ready for review July 25, 2026 02:36
@yohamta0
yohamta0 marked this pull request as ready for review July 25, 2026 02:36
@yohamta0
yohamta0 marked this pull request as ready for review July 25, 2026 02:36

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/cmd/helper.go`:
- Around line 192-194: Resolve name to an absolute path before constructing
dagStoreConfig, then use that resolved value consistently for SearchPaths and
the subsequent GetMetadata call. Update the surrounding helper flow so locateDAG
no longer combines filepath.Dir with a relative multi-segment name, while
preserving existing behavior for absolute inputs.

In `@internal/persis/file/dag/store.go`:
- Around line 1040-1066: The locateDAG method currently discards the resolved
path returned by ResolveExistingPathWithinBase and reconstructs it from
candidatePath. Capture and return that first resolved-path value directly when
resolution succeeds, preserving the existing search and error behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5ae1dc4b-f410-4a03-aec2-7bf104b8311e

📥 Commits

Reviewing files that changed from the base of the PR and between 8b7a898 and 6b7b174.

📒 Files selected for processing (3)
  • internal/cmd/helper.go
  • internal/persis/file/dag/store.go
  • internal/persis/file/dag/store_test.go

Comment thread internal/cmd/helper.go
Comment thread internal/persis/file/dag/store.go
Copilot AI review requested due to automatic review settings July 25, 2026 03:10

Copilot AI left a comment

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings July 25, 2026 03:27

Copilot AI left a comment

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@yohamta0
yohamta0 merged commit c15c540 into main Jul 25, 2026
11 checks passed
@yohamta0
yohamta0 deleted the agent/contain-dag-paths branch July 25, 2026 03:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants