This repository has been archived on 2026-03-13. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
greywall/docs/security-model.md
Mathieu Virbel da3a2ac3a4 rename Fence to Greywall as GreyHaven sandboxing component
Rebrand the project from Fence to Greywall, the sandboxing layer of the
GreyHaven platform. This updates:

- Go module path to gitea.app.monadical.io/monadical/greywall
- Binary name, CLI help text, and all usage examples
- Config paths (~/.config/greywall/greywall.json), env vars (GREYWALL_*)
- Log prefixes ([greywall:*]), temp file prefixes (greywall-*)
- All documentation, scripts, CI workflows, and example files
- README rewritten with GreyHaven branding and Fence attribution

Directory/file renames: cmd/fence → cmd/greywall, pkg/fence → pkg/greywall,
docs/why-fence.md → docs/why-greywall.md, example JSON files, and banner.
2026-02-10 16:00:24 -06:00

4.2 KiB

Security Model

Greywall is intended as defense-in-depth for running semi-trusted commands with reduced side effects (package installs, build scripts, CI jobs, unfamiliar repos).

It is not designed to be a strong isolation boundary against actively malicious code that is attempting to escape.

Threat model (what Greywall helps with)

Greywall is useful when you want to reduce risk from:

  • Supply-chain scripts that unexpectedly call out to the network
  • Tools that write broadly across your filesystem
  • Accidental leakage of secrets via "phone home" behavior
  • Unfamiliar repos that run surprising commands during install/build/test

What Greywall enforces

Network

  • Default deny: outbound network is blocked unless explicitly allowed.
  • Allowlisting by domain: you can specify allowedDomains (with wildcard support like *.example.com).
  • Localhost controls: inbound binding and localhost outbound are separately controlled.

Important: domain filtering does not inspect content. If you allow a domain, code can exfiltrate via that domain.

How allowlisting works

Greywall combines OS-level enforcement with proxy-based allowlisting:

  • The OS sandbox / network namespace is expected to block direct outbound connections.
  • Domain allowlisting happens via local HTTP/SOCKS proxies and proxy environment variables (HTTP_PROXY, HTTPS_PROXY, ALL_PROXY).

If a program does not use proxy env vars (or uses a custom protocol/stack), it may not benefit from domain allowlisting. In that case it typically fails with connection errors rather than being "selectively allowed."

Localhost is separate from "external domains":

  • allowLocalOutbound=false can intentionally block connections to local services like Redis on 127.0.0.1:6379 (see the dev-server example).

Filesystem

  • Writes are denied by default; you must opt in with allowWrite.
  • denyWrite can block specific files/patterns even if the parent directory is writable.
  • denyRead can block reads from sensitive paths.
  • Greywall includes an internal list of always-protected targets (e.g. shell configs, git hooks) to reduce common persistence vectors.

Environment sanitization

Greywall strips dangerous environment variables before passing them to sandboxed commands:

  • LD_* (Linux): LD_PRELOAD, LD_LIBRARY_PATH, etc.
  • DYLD_* (macOS): DYLD_INSERT_LIBRARIES, DYLD_LIBRARY_PATH, etc.

This prevents a library injection attack where a sandboxed process writes a malicious .so/.dylib and then uses LD_PRELOAD/DYLD_INSERT_LIBRARIES in a subsequent command to load it.

Visibility / auditing

  • -m/--monitor helps you discover what a command tries to access (blocked only).
  • -d/--debug shows more detail to understand why something was blocked.

Limitations (what Greywall does NOT try to solve)

  • Hostile code containment: assume determined attackers may escape via kernel/OS vulnerabilities.
  • Resource limits: CPU, memory, disk, fork bombs, etc. are out of scope.
  • Content-based controls: Greywall does not block data exfiltration to allowed destinations.
  • Proxy limitations / protocol edge cases: some programs may not respect proxy environment variables, so they won't get domain allowlisting unless you configure them to use a proxy (e.g. Node.js http/https without a proxy-aware client).

Practical examples of proxy limitations

The proxy approach works well for many tools (curl, wget, git, npm, pip), but not by default for some stacks:

  • Node.js native http/https (use a proxy-aware client, e.g. undici + ProxyAgent)
  • Raw socket connections (custom TCP/UDP protocols)

Greywall's OS-level sandbox is still expected to block direct outbound connections; bypassing the proxy should fail rather than silently succeeding.

Domain-based filtering only

Greywall does not inspect request content. If you allow a domain, a sandboxed process can still exfiltrate data to that domain.

Not a hostile-code containment boundary

Greywall is defense-in-depth for running semi-trusted code, not a strong isolation boundary against malware designed to escape sandboxes.

For implementation details (how proxies/sandboxes/bridges work), see ARCHITECTURE.md.