Skip to content

implement transparent sandboxing#1783

Draft
LorenzBischof wants to merge 3 commits intocachix:mainfrom
LorenzBischof:push-uvwrmtustnww
Draft

implement transparent sandboxing#1783
LorenzBischof wants to merge 3 commits intocachix:mainfrom
LorenzBischof:push-uvwrmtustnww

Conversation

@LorenzBischof
Copy link
Contributor

The idea is to transparently sandbox all processes, packages, tasks and scripts to the current directory, without the user having to develop inside a container.

This is currently just an idea. I still have to figure out if it is feasible.

@LorenzBischof LorenzBischof marked this pull request as draft March 19, 2025 22:51
@LorenzBischof LorenzBischof force-pushed the push-uvwrmtustnww branch 3 times, most recently from 67f281d to 3e66c51 Compare March 20, 2025 21:40
@domenkozar
Copy link
Member

If this works on macOS, I'll be damned :)

@LorenzBischof
Copy link
Contributor Author

LorenzBischof commented Mar 21, 2025

No, this currently only works on Linux and on supported kernels. The sandboxing is "best-effort" and disabled if not supported. Landlock support is pretty good and getting better. Mac has sandbox_init which was deprecated a long time ago, but still used by chrome.

My goal was to start simple and add upon the implementation once we see it work. For example syscall filtering with Seccomp would be really nice. We could also add other implementations like Bubblewrap (user namespaces), but I prefer these lightweight implementations.

I haven't fully thought this through, but I think the filesystem sandboxing could also be used to make the environment more pure, by only allowing access to the shell Nix closure, which would ensure no other packages are accidentally used within the scripts.

@LorenzBischof LorenzBischof force-pushed the push-uvwrmtustnww branch 3 times, most recently from 1211fbf to 6927ad3 Compare March 23, 2025 14:47
@domenkozar
Copy link
Member

Maybe a more feasible apprach would be to run sandboxing at devenv shell and so everything inside is sandboxed?

That would be tricky for loading things like editor config, etc.

@LorenzBischof
Copy link
Contributor Author

That could also work, but my goal was to enable transparent sandboxing. One main advantage of devenv is that development is not within a container, meaning everything else on the host system stays available.

@gabyx
Copy link
Contributor

gabyx commented May 3, 2025

I like that really! Containers come with heavy problems in CI which turns quickly into nested containers which make things hard etc. So a less container approach is really nice

@domenkozar
Copy link
Member

@LorenzBischof do you have some findings to share on this PR?

@LorenzBischof
Copy link
Contributor Author

This definitely needs more work and was just an experiment. I wont have any time to develop or think about this until next year.

@LorenzBischof

This comment was marked as outdated.

@zaytsev
Copy link

zaytsev commented Feb 5, 2026

perhaps something similar to the PoC could be achieved by simply integrating landlock restrict_self into devenv binary?

use landlock::{
    Access, AccessFs, Ruleset, RulesetAttr, RulesetCreatedAttr, ABI,
};

    // let allowed_dirs = get_sandbox_config_dirs()
    let allowed_dirs = vec![
        "/tmp",
        "/home/user/safe_dir",
    ];

    // Create a Landlock ruleset
    let abi = ABI::V2; // Use the latest ABI your kernel supports
    
    let status = Ruleset::default()
        .handle_access(AccessFs::from_all(abi))?
        .create()?
        .add_rules(
            allowed_dirs.iter().map(|dir| {
                landlock::path_beneath_rules(
                    dir,
                    AccessFs::from_read(abi) | AccessFs::from_write(abi),
                )
            })
        )?
        .restrict_self()?;

Pros:

  • no dependencies on extra 3rd party packages for sandboxing
    Cons:
  • doesn't work on OSX
  • no bubblewrap's mount point flexibility (tmpfs, overlays)
  • doesn't work with direnv

It seems direnv integration might be tricky (LLM-generated summary below):

Supervisor process using Linux seccomp-unotify for dynamic policy enforcement.

Key Points

  • Supervisor intercepts syscalls, makes allow/deny decisions based on current policy
  • direnv hooks send restrictions on load (e.g., "block writes to ~"), remove on unload
  • No sub-shells: Works in current shell session
  • Inherited: All child processes automatically sandboxed

Requirements

  • Linux 5.0+ (seccomp-unotify support)
  • Supervisor daemon (C/Rust)
  • Modified shell startup to launch via supervisor

Trade-offs

Pros: Truly dynamic, fine-grained control, seamless UX
Cons: Linux-only, implementation complexity, syscall interception overhead

Why not Landlock?

Restrictions can only increase, never decrease - incompatible with dynamic add/remove requirement.

@LorenzBischof
Copy link
Contributor Author

Inspired by https://github.com/landlock-lsm/island?target=https://github.com I created another POC https://github.com/LorenzBischof/peninsula?target=https://github.com which should support direnv.

@LorenzBischof LorenzBischof force-pushed the push-uvwrmtustnww branch 6 times, most recently from fa2232b to 79a6336 Compare February 8, 2026 22:01
@domenkozar domenkozar mentioned this pull request Feb 9, 2026
@LorenzBischof LorenzBischof changed the title implement basic filesystem sandbox implement transparent sandboxing Feb 22, 2026
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.

4 participants