jailed-agents no-cwd

This commit is contained in:
2026-02-27 12:24:25 +01:00
parent fc658b4112
commit 46f2bedb1f
2 changed files with 152 additions and 88 deletions

36
flake.lock generated
View File

@@ -9,11 +9,11 @@
"systems": "systems_2" "systems": "systems_2"
}, },
"locked": { "locked": {
"lastModified": 1769353768, "lastModified": 1771437256,
"narHash": "sha256-zI+7cbMI4wMIR57jMjDSEsVb3grapTnURDxxJPYFIW0=", "narHash": "sha256-bLqwib+rtyBRRVBWhMuBXPCL/OThfokA+j6+uH7jDGU=",
"owner": "numtide", "owner": "numtide",
"repo": "blueprint", "repo": "blueprint",
"rev": "c7da5c70ad1c9b60b6f5d4f674fbe205d48d8f6c", "rev": "06ee7190dc2620ea98af9eb225aa9627b68b0e33",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -42,11 +42,11 @@
}, },
"jail-nix": { "jail-nix": {
"locked": { "locked": {
"lastModified": 1765903853, "lastModified": 1770418571,
"narHash": "sha256-buoPpx7moJzAXbLuHAImn6x9fGRdk3x0T57goPv1vnc=", "narHash": "sha256-EzQUbe1gwW/xpJoMuMeblWcjAEF+F92cz/enz0Mz/qo=",
"owner": "~alexdavid", "owner": "~alexdavid",
"repo": "jail.nix", "repo": "jail.nix",
"rev": "bf9f49c8118e7a77b68a675dbe26e93e91412066", "rev": "c141cf8cc68617625b4a28a7d8ce0a35904815d5",
"type": "sourcehut" "type": "sourcehut"
}, },
"original": { "original": {
@@ -62,11 +62,11 @@
"treefmt-nix": "treefmt-nix" "treefmt-nix": "treefmt-nix"
}, },
"locked": { "locked": {
"lastModified": 1769813338, "lastModified": 1772165712,
"narHash": "sha256-IlRKon8+bfoi/uOa8CUPAAWW0Pv6AHBSF1jVSD4QO8U=", "narHash": "sha256-ThpPDZeGjLKXb3UW1rIFOmrNVBB0T3LxO8cu9c5B/ig=",
"owner": "numtide", "owner": "numtide",
"repo": "llm-agents.nix", "repo": "llm-agents.nix",
"rev": "58939415e56d01c30d429cf0c49a9d8e2a6a07c3", "rev": "e3356720c7b3d4c20e06396997c5d76fa7241f0e",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -77,11 +77,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1769740369, "lastModified": 1771423170,
"narHash": "sha256-xKPyJoMoXfXpDM5DFDZDsi9PHArf2k5BJjvReYXoFpM=", "narHash": "sha256-K7Dg9TQ0mOcAtWTO/FX/FaprtWQ8BmEXTpLIaNRhEwU=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "6308c3b21396534d8aaeac46179c14c439a89b8a", "rev": "bcc4a9d9533c033d806a46b37dc444f9b0da49dd",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -93,11 +93,11 @@
}, },
"nixpkgs_2": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1769461804, "lastModified": 1771848320,
"narHash": "sha256-msG8SU5WsBUfVVa/9RPLaymvi5bI8edTavbIq3vRlhI=", "narHash": "sha256-0MAd+0mun3K/Ns8JATeHT1sX28faLII5hVLq0L3BdZU=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "bfc1b8a4574108ceef22f02bafcf6611380c100d", "rev": "2fc6539b481e1d2569f25f8799236694180c0993",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -153,11 +153,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1769691507, "lastModified": 1770228511,
"narHash": "sha256-8aAYwyVzSSwIhP2glDhw/G0i5+wOrren3v6WmxkVonM=", "narHash": "sha256-wQ6NJSuFqAEmIg2VMnLdCnUc0b7vslUohqqGGD+Fyxk=",
"owner": "numtide", "owner": "numtide",
"repo": "treefmt-nix", "repo": "treefmt-nix",
"rev": "28b19c5844cc6e2257801d43f2772a4b4c050a1b", "rev": "337a4fe074be1042a35086f15481d763b8ddc0e7",
"type": "github" "type": "github"
}, },
"original": { "original": {

204
flake.nix
View File

@@ -23,33 +23,41 @@
pkgs = nixpkgs.legacyPackages.${system}; pkgs = nixpkgs.legacyPackages.${system};
jail = jail-nix.lib.init pkgs; jail = jail-nix.lib.init pkgs;
defaultPackages = with pkgs; defaultPackages = with pkgs; [
[ bashInteractive
bashInteractive curl
curl wget
wget jq
jq git
git which
which ripgrep
ripgrep gnugrep
gnugrep gawkInteractive
gawkInteractive ps
ps findutils
findutils gzip
gzip unzip
unzip gnutar
gnutar diffutils
diffutils ];
];
makeJailedConfig = { name, jail, pkgs, extraPkgs ? [ ], extraCombinators ? [ ] }: makeJailedConfig = {
name,
jail,
pkgs,
extraPkgs ? [ ],
extraCombinators ? [ ],
mountCwd ? true,
}:
with jail.combinators; with jail.combinators;
( (
[ [
network network
time-zone time-zone
no-new-session no-new-session
mount-cwd ]
++ (if mountCwd then [ mount-cwd ] else [ ])
++ [
(readwrite (noescape "~/.config/${name}")) (readwrite (noescape "~/.config/${name}"))
(readwrite (noescape "~/.local/share/${name}")) (readwrite (noescape "~/.local/share/${name}"))
(readwrite (noescape "~/.local/state/${name}")) (readwrite (noescape "~/.local/state/${name}"))
@@ -59,11 +67,18 @@
++ extraCombinators ++ extraCombinators
); );
makeJailedAgent = { name, pkg, extraPkgs ? [ ], extraCombinators ? [ ] }: makeJailedAgent = {
name,
pkg,
extraPkgs ? [ ],
extraCombinators ? [ ],
mountCwd ? true,
}:
jail name pkg (makeJailedConfig { jail name pkg (makeJailedConfig {
inherit name jail pkgs extraPkgs extraCombinators; inherit name jail pkgs extraPkgs extraCombinators mountCwd;
}); });
# CWD-mounted variants
opencode-jailed = makeJailedAgent { opencode-jailed = makeJailedAgent {
name = "opencode"; name = "opencode";
pkg = llm-agents.packages.${system}.opencode; pkg = llm-agents.packages.${system}.opencode;
@@ -74,45 +89,67 @@
pkg = llm-agents.packages.${system}.claude-code; pkg = llm-agents.packages.${system}.claude-code;
}; };
# No-CWD variants
opencode-jailed-nocwd = makeJailedAgent {
name = "opencode-nocwd";
pkg = llm-agents.packages.${system}.opencode;
mountCwd = false;
};
claude-jailed-nocwd = makeJailedAgent {
name = "claude-code-nocwd";
pkg = llm-agents.packages.${system}.claude-code;
mountCwd = false;
};
lib = { lib = {
# Call as: inputs.jailed-agents.lib.makeJailed system { agentTool = "opencode"; extraPkgs = [...]; } # Call as: inputs.jailed-agents.lib.makeJailed system { agentTool = "opencode"; extraPkgs = [...]; mountCwd = false; }
makeJailed = makeJailed =
system': system':
{ {
agentTool, agentTool,
extraPkgs ? [ ], extraPkgs ? [ ],
extraCombinators ? [ ], extraCombinators ? [ ],
mountCwd ? true,
}: }:
let let
pkgs' = nixpkgs.legacyPackages.${system'}; pkgs' = nixpkgs.legacyPackages.${system'};
jail' = jail-nix.lib.init pkgs'; jail' = jail-nix.lib.init pkgs';
pkg' = llm-agents.packages.${system'}.opencode; pkg' = llm-agents.packages.${system'}.opencode;
defaultPackages' = with pkgs'; defaultPackages' = with pkgs'; [
[ bashInteractive
bashInteractive curl
curl wget
wget jq
jq git
git which
which ripgrep
ripgrep gnugrep
gnugrep gawkInteractive
gawkInteractive ps
ps findutils
findutils gzip
gzip unzip
unzip gnutar
gnutar diffutils
diffutils ];
]; makeJailedConfig' = {
makeJailedConfig' = { name, jail, pkgs, extraPkgs ? [ ], extraCombinators ? [ ] }: name,
with jail.combinators; jail,
pkgs,
extraPkgs ? [ ],
extraCombinators ? [ ],
mountCwd ? true,
}:
with jail'.combinators;
( (
[ [
network network
time-zone time-zone
no-new-session no-new-session
mount-cwd ]
++ (if mountCwd then [ mount-cwd ] else [ ])
++ [
(readwrite (noescape "~/.config/${name}")) (readwrite (noescape "~/.config/${name}"))
(readwrite (noescape "~/.local/share/${name}")) (readwrite (noescape "~/.local/share/${name}"))
(readwrite (noescape "~/.local/state/${name}")) (readwrite (noescape "~/.local/state/${name}"))
@@ -126,7 +163,7 @@
name = agentTool; name = agentTool;
jail = jail'; jail = jail';
pkgs = pkgs'; pkgs = pkgs';
inherit extraPkgs extraCombinators; inherit extraPkgs extraCombinators mountCwd;
}); });
}; };
@@ -141,7 +178,12 @@
in in
{ {
packages = { packages = {
inherit opencode-jailed claude-jailed; inherit
opencode-jailed
claude-jailed
opencode-jailed-nocwd
claude-jailed-nocwd
;
}; };
checks = { checks = {
@@ -159,6 +201,20 @@
touch $out touch $out
''; '';
opencode-jailed-nocwd-build = pkgs.runCommand "test-opencode-jailed-nocwd" {
buildInputs = [ opencode-jailed-nocwd ];
} ''
test -f ${opencode-jailed-nocwd}/bin/opencode-nocwd
touch $out
'';
claude-jailed-nocwd-build = pkgs.runCommand "test-claude-jailed-nocwd" {
buildInputs = [ claude-jailed-nocwd ];
} ''
test -f ${claude-jailed-nocwd}/bin/claude-code-nocwd
touch $out
'';
lib-makeJailed-basic = pkgs.runCommand "test-lib-makeJailed-basic" { lib-makeJailed-basic = pkgs.runCommand "test-lib-makeJailed-basic" {
buildInputs = [ test-agent-basic ]; buildInputs = [ test-agent-basic ];
} '' } ''
@@ -190,44 +246,53 @@
}; };
lib = { lib = {
# Call as: inputs.jailed-agents.lib.makeJailed system { agentTool = "opencode"; extraPkgs = [...]; } # Call as: inputs.jailed-agents.lib.makeJailed system { agentTool = "opencode"; extraPkgs = [...]; mountCwd = false; }
makeJailed = makeJailed =
system': system':
{ {
agentTool, agentTool,
extraPkgs ? [ ], extraPkgs ? [ ],
extraCombinators ? [ ], extraCombinators ? [ ],
mountCwd ? true,
}: }:
let let
pkgs' = nixpkgs.legacyPackages.${system'}; pkgs' = nixpkgs.legacyPackages.${system'};
jail' = jail-nix.lib.init pkgs'; jail' = jail-nix.lib.init pkgs';
pkg' = llm-agents.packages.${system'}.opencode; pkg' = llm-agents.packages.${system'}.opencode;
defaultPackages' = with pkgs'; defaultPackages' = with pkgs'; [
[ bashInteractive
bashInteractive curl
curl wget
wget jq
jq git
git which
which ripgrep
ripgrep gnugrep
gnugrep gawkInteractive
gawkInteractive ps
ps findutils
findutils gzip
gzip unzip
unzip gnutar
gnutar diffutils
diffutils ];
]; makeJailedConfig' = {
makeJailedConfig' = { name, jail, pkgs, extraPkgs ? [ ], extraCombinators ? [ ] }: name,
with jail.combinators; jail,
pkgs,
extraPkgs ? [ ],
extraCombinators ? [ ],
mountCwd ? true,
}:
with jail'.combinators;
( (
[ [
network network
time-zone time-zone
no-new-session no-new-session
mount-cwd ]
++ (if mountCwd then [ mount-cwd ] else [ ])
++ [
(readwrite (noescape "~/.config/${name}")) (readwrite (noescape "~/.config/${name}"))
(readwrite (noescape "~/.local/share/${name}")) (readwrite (noescape "~/.local/share/${name}"))
(readwrite (noescape "~/.local/state/${name}")) (readwrite (noescape "~/.local/state/${name}"))
@@ -241,10 +306,9 @@
name = agentTool; name = agentTool;
jail = jail'; jail = jail';
pkgs = pkgs'; pkgs = pkgs';
inherit extraPkgs extraCombinators; inherit extraPkgs extraCombinators mountCwd;
}); });
}; };
} }
); );
} }