Feat/env filtering#140
Conversation
Users can now control which environment variables get passed to sandboxed processes via configuration. This adds a new `environment` section to fence.json with `allowedVars` and `deniedVars` using glob patterns. - Add Environment config to fence.json with allow/deny patterns - Implement glob pattern matching (*_TOKEN, AWS_*, etc.) - Add FilterEnvironmentVars and GetHardenedEnvWithConfig functions - Deny patterns are checked first (security-first approach) - Maintain backward compatibility with GetHardenedEnv() - Full test coverage with 15+ test cases Signed-off-by: Dominik Tomasi <dominik.tomasi@gmail.com>
During testing, we found the linting setup was broken in multiple ways. The Makefile said v1, shell.nix had v2, .golangci.yml was written for v1, and things just wouldn't install properly. This commit fixes all of that by picking v2.11.4 as our version, updating all configs to match, and making Makefile the single source of truth. Problems we found: - Makefile documented v1 but was trying to use v2 import path - shell.nix installed v2, conflicting with Makefile's old command - .golangci.yml was v1 syntax, incompatible with v2 - Different versions in local dev vs CI made things unreproducible What we fixed: - Pinned golangci-lint to v2.11.4 in Makefile - Rewrote .golangci.yml for v2 format - Removed tools from shell.nix (rely on Makefile instead) - Updated GitHub Actions to use make install-lint-tools Signed-off-by: Dominik Tomasi <dominik.tomasi@gmail.com>
Now that the linter is working, v2 has stricter rules than v1. This commit applies those rules across the codebase. Main changes: - Add #nosec annotations where we've validated inputs (network ops, file I/O) - Fix import formatting (blank lines between stdlib and internal imports) - Lowercase some error message strings for consistency This is all mechanical/policy stuff - no logic changes. Signed-off-by: Dominik Tomasi <dominik.tomasi@gmail.com>
0cdd203 to
d9f9122
Compare
There was a problem hiding this comment.
3 issues found across 25 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="cmd/fence/hooks_runtime.go">
<violation number="1" location="cmd/fence/hooks_runtime.go:208">
P1: `isPureCDCommand` no longer matches standard `cd <path>` commands, so plain directory changes are misclassified and may be wrapped instead of skipped.</violation>
</file>
<file name="Makefile">
<violation number="1" location="Makefile:78">
P2: `lint-fix` was added as a command target but not declared phony, so `make lint-fix` can be skipped if a file/directory named `lint-fix` exists.</violation>
</file>
<file name="docs/schema/fence.schema.json">
<violation number="1" location="docs/schema/fence.schema.json:83">
P2: Schema documentation for `environment.allowedVars` is incorrect: empty `allowedVars` does not block all vars at runtime, causing misleading config semantics.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
Linting changes in d9f9122 broke cd command detection logic. Commands like 'cd ../repo' were incorrectly rejected.
The description incorrectly stated that empty allowedVars blocks all environment variables. The actual implementation allows all variables by default when allowedVars is empty.
Targets that don't produce files with their name should be declared as .PHONY to prevent make from skipping them if files with those names exist.
|
@dtomasi happy to hear that Fence has been helpful, and thanks for the contribution! Before we dig into the code, I want to be really clear on the "why", because the goal isn't quite clear to me yet and I think it changes whether this belongs in Fence at all. Fence already strips This PR points the other direction: protecting the caller's secrets from the sandboxed process. That's a real concern, especially for coding agents, but I'm not yet convinced Fence is the right layer for it, for two reasons:
Could you spell out what Fence is meant to guarantee here? Concretely: what does it guarantee that A few notes for later:
|
|
@jy-tan Thanks for the detailed feedback! My intention was to address what I've observed - many developers don't separate secrets in their shell configurations and keep everything together in their bash/ZSH setup. The idea was to enable sharing a configuration file that ensures dangerous environment variables are filtered out by default when working with agents, rather than relying on each developer to remember proper filtering. However, I understand your points about layer responsibility and Fence's design philosophy. I can see this doesn't align well with the project's scope and architecture. I'd recommend closing this PR. Happy to extract the linter fixes to a separate PR if that would be helpful. Please find #144 Thanks for the clear explanation! |
|
Closing for now, thanks nonetheless! |
Add environment variable filtering support
I've been using Fence for my development workflows and found it really helpful. This PR adds environment variable filtering to complement the existing sandbox controls.
What's included
Main feature (commit e6db3d5):
environmentsection in fence.json withallowedVarsanddeniedVarsglob patternsTooling fixes (commits 1f96100, 0cdd203):
Example usage
{ "environment": { "deniedVars": [ "*_SECRET*", "*_PASSWORD*", "*_TOKEN*", "*_APIKEY*", "*_API_KEY*" ] } }This prevents sensitive credentials from leaking into sandboxed processes while still allowing other environment variables through.
Note on commit structure
The tooling commits address version mismatches and linting issues that became apparent during development. If you prefer, I can cherry-pick the main feature commit (e6db3d5) into a separate PR and handle the tooling updates independently.
Testing
All existing tests pass, and the new environment filtering functionality includes extensive test coverage for various glob pattern scenarios.