FileJail
Defined in: file/jail.ts:27
Confines file access to a configured root. Every requested path is resolved against the
root and checked (after symlink resolution) to still be inside it. Defends against
.. traversal and a symlink planted inside the jail pointing outside it.
Known limitation (TOCTOU): this is a check-then-use pattern, not a kernel-enforced
boundary — there’s a window between a resolve* call’s realpath check and the caller’s
actual readFile/writeFile on that same path where a concurrent filesystem change (e.g.
something swaps a symlink into place) could in principle slip through. A fully closed
version would operate on a file descriptor (open → fstat/read) instead of a path, so
there’s no gap between check and use; this package doesn’t do that yet. Matches the threat
model this jail is scoped to (the model is the adversary, via tool-call arguments — not a
concurrent local filesystem race) but is worth knowing if that threat model ever changes.
A subprocess-level, kernel-enforced sandbox (e.g. Landlock, sandbox-exec) doesn’t have
this gap; this jail does.
Platform support: tested on Linux and macOS only. Windows is untested and not
currently supported — path.isAbsolute/path.relative/path.sep behave differently
there (drive letters, UNC paths, case-insensitive-but-case-preserving filesystems), and
none of that has been verified.
Properties
Section titled “Properties”
readonlyroot:string
Defined in: file/jail.ts:29
The jail root, resolved to an absolute path (not yet symlink-resolved).
Methods
Section titled “Methods”resolveExisting()
Section titled “resolveExisting()”resolveExisting(
requestedPath):Promise<string>
Defined in: file/jail.ts:35
Resolve requestedPath (relative to the root) to an absolute, symlink-resolved path,
for a file that must already exist. Throws AdlError("INVALID_INPUT", …) if the path is
absolute, escapes the root, or doesn’t exist.
Parameters
Section titled “Parameters”requestedPath
Section titled “requestedPath”string
Returns
Section titled “Returns”Promise<string>
resolveForWrite()
Section titled “resolveForWrite()”resolveForWrite(
requestedPath):Promise<string>
Defined in: file/jail.ts:42
Resolve requestedPath to an absolute, symlink-resolved path for a file that may not
exist yet — the file itself isn’t symlink-resolved (it may not exist), but its parent
directory is, and must already exist. Throws AdlError("INVALID_INPUT", …) if the path
is absolute, escapes the root, or its parent directory doesn’t exist.
Parameters
Section titled “Parameters”requestedPath
Section titled “requestedPath”string
Returns
Section titled “Returns”Promise<string>