forked from
lass.pds.lassul.us/superconfig
This repository has no description
5.8 kB
164 lines
1# crit (https://crit.md): agents run `crit` to open their diff/plan for review
2# in the browser and block until it is finished. Each review session is its
3# own daemon on its own port, reachable over retiolum as
4# http://<host>.r:<port>, and publicly as https://<id>.review.lassul.us
5# through neoprism (configs/crit-proxy.nix) and the router nginx below.
6#
7# SECURITY: crit has no authentication, and comments left in a review are fed
8# to the agent as instructions. Whoever can reach a daemon can steer an agent
9# running here, so the ports are only open on retiolum. On the public side the
10# random 10-char hostname (~51 bits, fresh per review, only on a wildcard cert
11# so it never shows up in CT logs) is the only protection.
12{
13 self,
14 config,
15 pkgs,
16 ...
17}:
18let
19 firstPort = 7700;
20 lastPort = 7719;
21 # router nginx, neoprism proxies *.review.lassul.us here
22 routerPort = 7720;
23 domain = "review.lassul.us";
24 # one file per port, "<id> <port>", written by the wrapper
25 routesDir = "/var/lib/crit-routes";
26 mapDir = "/run/crit-routes";
27 crit-unwrapped = self.inputs.llm-agents.packages.${pkgs.system}.crit;
28
29 # crit binds 127.0.0.1 on a random port by default. Bind all interfaces on a
30 # free port from the firewalled range instead and advertise the public URL.
31 # Only the invocation that starts a daemon binds the port; reconnecting to a
32 # running session uses the port and URL recorded in ~/.crit/sessions.
33 crit = pkgs.symlinkJoin {
34 name = "crit";
35 paths = [
36 (pkgs.writeShellScriptBin "crit" ''
37 if [ -z "''${CRIT_PORT:-}" ]; then
38 for p in $(${pkgs.coreutils}/bin/seq ${toString firstPort} ${toString lastPort}); do
39 if [ -z "$(${pkgs.iproute2}/bin/ss -Htln "sport = :$p")" ]; then
40 export CRIT_PORT=$p
41 # Fresh unguessable hostname per daemon. Replacing the port's
42 # route kills the link of whichever review used the port before.
43 id=$(LC_ALL=C ${pkgs.coreutils}/bin/tr -dc a-z0-9 </dev/urandom | ${pkgs.coreutils}/bin/head -c 10)
44 tmp=${routesDir}/.$p.$$
45 if printf '%s %s\n' "$id" "$p" >"$tmp" && ${pkgs.coreutils}/bin/mv -f "$tmp" ${routesDir}/"$p"; then
46 export CRIT_PUBLIC_URL="''${CRIT_PUBLIC_URL:-https://$id.${domain}}"
47 else
48 ${pkgs.coreutils}/bin/rm -f "$tmp"
49 echo "crit: cannot write ${routesDir} (not in group crit?), no public URL" >&2
50 fi
51 break
52 fi
53 done
54 fi
55 if [ -n "''${CRIT_PORT:-}" ]; then
56 echo "crit: retiolum: http://${config.networking.hostName}.r:$CRIT_PORT" >&2
57 export CRIT_PUBLIC_URL="''${CRIT_PUBLIC_URL:-http://${config.networking.hostName}.r:$CRIT_PORT}"
58 else
59 echo "crit: ports ${toString firstPort}-${toString lastPort} all busy, using a random port (not reachable over retiolum)" >&2
60 fi
61 export CRIT_HOST="''${CRIT_HOST:-0.0.0.0}"
62 export CRIT_ALLOW_UNAUTHENTICATED_NETWORK=1
63 exec ${crit-unwrapped}/bin/crit "$@"
64 '')
65 crit-unwrapped
66 ];
67 };
68
69 # Only well-formed routes make it into the nginx config: the routes dir is
70 # writable by the agent.
71 crit-routes-map = pkgs.writeShellApplication {
72 name = "crit-routes-map";
73 runtimeInputs = [ pkgs.coreutils ];
74 text = ''
75 routes=$1
76 out=$2
77 tmp=$(mktemp "$out.XXXXXX")
78 for f in "$routes"/*; do
79 [ -f "$f" ] || continue
80 id=''' port='''
81 read -r id port _ <"$f" || [ -n "$id" ] || continue
82 if [[ $id =~ ^[a-z0-9]{10}$ && $port =~ ^[0-9]{4}$ ]] &&
83 ((port >= ${toString firstPort} && port <= ${toString lastPort})); then
84 printf '%s.${domain} %s;\n' "$id" "$port"
85 fi
86 done >"$tmp"
87 chmod 644 "$tmp"
88 mv -f "$tmp" "$out"
89 '';
90 };
91in
92{
93 environment.systemPackages = [ crit ];
94
95 users.groups.crit.members = [
96 config.users.users.mainUser.name
97 "hermes"
98 ];
99 # no sticky bit: any crit user must be able to replace another's route
100 systemd.tmpfiles.rules = [ "d ${routesDir} 2770 root crit -" ];
101
102 systemd.paths.crit-routes = {
103 wantedBy = [ "paths.target" ];
104 pathConfig.PathChanged = routesDir;
105 };
106 systemd.services.crit-routes = {
107 description = "Generate the nginx map of crit review hostnames";
108 wantedBy = [ "multi-user.target" ];
109 before = [ "nginx.service" ];
110 serviceConfig.Type = "oneshot";
111 script = ''
112 mkdir -p ${mapDir}
113 ${pkgs.lib.getExe crit-routes-map} ${routesDir} ${mapDir}/routes.map
114 systemctl try-reload-or-restart nginx.service
115 '';
116 };
117
118 # Routes <id>.review.lassul.us to the daemon's port. A daemon that has gone
119 # away gives 502, unknown ids 404.
120 services.nginx = {
121 enable = true;
122 # the glob tolerates a missing file before crit-routes ran
123 appendHttpConfig = ''
124 map $host $crit_port {
125 default "";
126 include ${mapDir}/*.map;
127 }
128 '';
129 virtualHosts.crit-routes = {
130 listen = [
131 {
132 addr = "0.0.0.0";
133 port = routerPort;
134 }
135 {
136 addr = "[::]";
137 port = routerPort;
138 }
139 ];
140 extraConfig = ''
141 if ($crit_port = "") {
142 return 404;
143 }
144 '';
145 # the UI follows the review over SSE
146 locations."/" = {
147 recommendedProxySettings = true;
148 proxyPass = "http://127.0.0.1:$crit_port";
149 extraConfig = ''
150 proxy_buffering off;
151 proxy_read_timeout 1h;
152 '';
153 };
154 };
155 };
156
157 networking.firewall.interfaces.retiolum.allowedTCPPorts = [ routerPort ];
158 networking.firewall.interfaces.retiolum.allowedTCPPortRanges = [
159 {
160 from = firstPort;
161 to = lastPort;
162 }
163 ];
164}