kern-sandbox 0.2.20 → 0.2.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/index.js +28 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -164,8 +164,8 @@ Every relaxing option says so in its name or docs:
|
|
|
164
164
|
- **mounts refused**: the host's own sources (`/`, `/etc`, `/root`, `/boot`, `/proc`, `/sys`, `/dev`,
|
|
165
165
|
`$HOME`, the docker socket), any path with a **credential directory** in it (`.ssh`, `.aws`, `.gnupg`,
|
|
166
166
|
`.kube`, `.docker`, `.azure`, `.password-store`, `.netrc`, `.git-credentials`, `.pypirc`, `.npmrc`),
|
|
167
|
-
**kern's own state** (`$XDG_RUNTIME_DIR/kern`, the image cache, the config dir
|
|
168
|
-
plane), and escaping targets.
|
|
167
|
+
**kern's own state** (`$XDG_RUNTIME_DIR/kern`, the image cache, the config dir, the data dir that
|
|
168
|
+
holds every named volume: the sandbox's control plane), and escaping targets.
|
|
169
169
|
- **workspace I/O contained**: `writeFile`/`readFile` reject `..` escapes, open the final component
|
|
170
170
|
`O_NOFOLLOW` so a symlink the box plants cannot redirect host I/O, and refuse anything that is not a
|
|
171
171
|
REGULAR file (see the notes for the FIFO that made a read hang).
|
package/index.js
CHANGED
|
@@ -36,7 +36,7 @@ const crypto = require("crypto");
|
|
|
36
36
|
const zlib = require("zlib");
|
|
37
37
|
const { spawn, spawnSync } = require("child_process");
|
|
38
38
|
|
|
39
|
-
const VERSION = "0.2.
|
|
39
|
+
const VERSION = "0.2.22";
|
|
40
40
|
|
|
41
41
|
const DEFAULT_IMAGE = "python:3.12-slim";
|
|
42
42
|
const WORKSPACE = "/workspace"; // where the persistent workspace is mounted inside every box
|
|
@@ -456,16 +456,35 @@ const REFUSED_MOUNT_SOURCES = new Set([
|
|
|
456
456
|
* follow the environment and a service manager moves them. */
|
|
457
457
|
function kernStateDirs() {
|
|
458
458
|
const uid = process.getuid();
|
|
459
|
-
const runtime = process.env.XDG_RUNTIME_DIR || `/run/user/${uid}`;
|
|
460
459
|
const home = os.homedir();
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
460
|
+
// EACH DIRECTORY TWICE: where the environment says it is, AND where XDG says it is by default. The
|
|
461
|
+
// runtime dir was already spelled both ways; the other three were not, and a reviewer measured the
|
|
462
|
+
// consequence in one process - with `XDG_DATA_HOME=/tmp/xdh2`, `~/.local/share/kern` was ACCEPTED
|
|
463
|
+
// and still held `builds` and `volumes`. The variable answers "which kern will this SDK spawn",
|
|
464
|
+
// which is the right input for the guard, but data a previous run left on disk does not move with it.
|
|
465
|
+
//
|
|
466
|
+
// The DATA dir itself joined the list after the same reviewer took the refused two as the shape of
|
|
467
|
+
// the rule and looked for the rest: it holds `volumes/`, the CONTENT of every named volume on this
|
|
468
|
+
// host, and `builds/`, the records a later image is assembled from.
|
|
469
|
+
const known = [
|
|
470
|
+
[process.env.XDG_RUNTIME_DIR, `/run/user/${uid}`,
|
|
471
|
+
"kern's runtime state (the registry, instance dirs, netns handles and exit files of every box you are running)"],
|
|
472
|
+
[process.env.XDG_CACHE_HOME, path.join(home, ".cache"),
|
|
473
|
+
"kern's image cache (a box that writes it poisons the rootfs a later box runs)"],
|
|
474
|
+
[process.env.XDG_CONFIG_HOME, path.join(home, ".config"),
|
|
475
|
+
"kern's configuration (the profiles a later box may be given)"],
|
|
476
|
+
[process.env.XDG_DATA_HOME, path.join(home, ".local", "share"),
|
|
477
|
+
"kern's data (every named volume on this host, and the build records a later image is assembled from)"],
|
|
468
478
|
];
|
|
479
|
+
// A MAP, so the usual case where the variable IS the default collapses to one entry instead of
|
|
480
|
+
// listing the same directory twice with two different accounts of what it is.
|
|
481
|
+
const out = new Map();
|
|
482
|
+
for (const [configured, dflt, what] of known)
|
|
483
|
+
for (const base of [configured || dflt, dflt]) {
|
|
484
|
+
const dir = path.join(base, "kern");
|
|
485
|
+
if (!out.has(dir)) out.set(dir, what);
|
|
486
|
+
}
|
|
487
|
+
return [...out];
|
|
469
488
|
}
|
|
470
489
|
|
|
471
490
|
/** Credential directories, refused as a COMPONENT anywhere in the source. The set above is absolute
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kern-sandbox",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.22",
|
|
4
4
|
"description": "kern is a fast, rootless sandbox and virtual resource runtime for any workload, including untrusted and LLM-generated code; kern-sandbox is its Node/TypeScript binding. Run untrusted or agent-generated code (Python/JS/Bash) in a real, kernel-enforced box in single-digit milliseconds, with no cloud, no account and no VM.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sandbox",
|