Skip to content

feat(config): declarative custom-paths boundary checking via --config#26

Draft
sublimino wants to merge 4 commits into
mainfrom
feat/custom-path-config
Draft

feat(config): declarative custom-paths boundary checking via --config#26
sublimino wants to merge 4 commits into
mainfrom
feat/custom-path-config

Conversation

@sublimino

@sublimino sublimino commented May 24, 2026

Copy link
Copy Markdown
Member

Summary

Adds a --config <yaml> flag to sandbox-probe scan for declarative filesystem boundary checking. Users define expected access rules in a YAML file; the scanner reports violations as structured findings.

What's new

--config <path> flag (global, persistent)

sandbox-probe scan --config tests/example/alice-sandbox.yaml --output_path report.json

Config schema (pkg/config/)

Four path categories:

  • must_block — readdir + open must be denied (Landlock/DAC enforcement check)
  • must_read — readdir must succeed (system tooling reachable)
  • must_readwrite — readdir + write must succeed (active workspace)
  • audit — all four ops probed, no pass/fail (informational)

Per-entry fields: path, label, severity (critical/error/warn), reason, check_files (per-file open=denied inside a dir), check_ops (override which ops are tested), stat_may_fail, note.

Findings

  • custom_path_violation — a must_* expectation was not met
  • custom_path_audit — audit-only observation (stat/readdir/open/write state)

Each finding includes path, label, op, severity, expected, got, and message.

Example config

tests/example/alice-sandbox.yaml — a complete boundary spec for an AI agent user, declaring which host paths must be blocked (SSH keys, AWS creds, kubeconfig, host source tree) and which must be accessible (system tooling, /tmp, agent workspace).

Testing

go test ./...   # 11 new config unit tests + all existing green
sandbox-probe scan --config tests/example/alice-sandbox.yaml --fast

Validated end-to-end with nono + Landlock active:

  • must_block credential paths: readdir + open correctly denied under sandbox
  • /tmp grant working after explicit path in nono profile patch
  • Viper isolation: --config YAML parsed only by config.LoadConfig(), not fed to viper

Files changed

File Purpose
pkg/config/config.go Schema + LoadConfig() with validation
pkg/config/config_test.go 11 unit tests incl. real alice-sandbox.yaml
pkg/tasks/baseline/custom_paths.go CheckCustomPaths() runner
pkg/tasks/custom_paths_task.go Task interface wrapper
cmd/cmd.go --config persistent flag; viper isolation fix
cmd/scan.go Config load + task append
tests/example/ Boundary spec, test harness, example Dockerfile

Windows support

Removed the Windows early-return stub from scanTargetedPathsForHome(). Sensitive paths and system write paths are now split into platform functions (filesystem_unix.go / filesystem_windows.go), so the scanner runs real credential detection on all three platforms.

@sublimino
sublimino marked this pull request as draft May 26, 2026 11:04
@sublimino
sublimino force-pushed the feat/bwrap-detection branch 2 times, most recently from 07a45a4 to 6734b1d Compare May 27, 2026 14:34
Base automatically changed from feat/bwrap-detection to main May 27, 2026 15:01
@sublimino
sublimino force-pushed the feat/custom-path-config branch 2 times, most recently from 68edc6a to dfdb865 Compare June 16, 2026 09:39
- Use filepath.Join for home-relative paths in scanTargetedPathsForHome
  so Windows drive-letter separators are handled correctly
- Remove incorrect early-return guards that skipped all checks on Windows
- Update path assertions in tests to use filepath.Join
- Skip chmod-based permission test on Windows (chmod is a no-op there)
Adds a --config flag that accepts a YAML file declaring expected filesystem
access boundaries for a sandboxed AI agent. The probe evaluates must_block,
must_read, must_readwrite, and audit path categories and reports pass/fail
findings per path.

- pkg/config/config.go: load and validate YAML config (identity + custom_paths)
- pkg/tasks/baseline/custom_paths.go: probe logic for each path category
- pkg/tasks/custom_paths_task.go: task wiring into the probe report
- cmd/scan.go: --config flag plumbed into scan command
- cmd/cmd.go: viper config separated from --config flag to avoid collision
- go.mod: add viper dependency
- tests/example/: Docker-based alice/bob demo; generic two-user config,
  Dockerfile with synthetic credential files, coloured run.sh driver
- Makefile: add 'make install' and 'make docker-test' targets
- .gitignore: exclude personal tests/cpai-*/ configs from repo
@sublimino
sublimino force-pushed the feat/custom-path-config branch from dfdb865 to 5d9c067 Compare June 17, 2026 11:58
…th lists

Remove the Windows early-return stub from scanTargetedPathsForHome().
Split sensitive paths and system write paths into platform functions
(platformSensitivePaths, platformSystemWritePaths, platformDefaultHome)
defined in filesystem_unix.go and filesystem_windows.go respectively.

Unix-only absolute paths (/etc/passwd, /proc/self/cgroup, /.dockerenv
etc.) move to filesystem_unix.go. Windows gets its own credential
locations (Credential Manager, %APPDATA%/gcloud, 1Password local data,
Windows system dirs). Cross-platform home-relative paths stay in
filesystem.go and resolve correctly on both OSes via filepath.Join.

Fixes 10 Windows unit test failures introduced by the filepath.Join
migration in the previous commit.
On Windows, Unix absolute paths (/etc/passwd, /var/run/docker.sock etc.)
are correctly absent from buildSensitivePathsForHome — the test was
asserting they must be present unconditionally. Split the assertion by
platform: Unix asserts the full set of Unix absolute paths; Windows
asserts Unix paths are absent and accepts Windows-specific entries.
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