forked from EduCraft/curriculum-project-hub
fix(hub): enable tenant Typst package resolution
This commit is contained in:
@@ -33,6 +33,8 @@ const SAFE_HOST_ENV_KEYS = [
|
||||
"all_proxy",
|
||||
"no_proxy",
|
||||
"NODE_USE_ENV_PROXY",
|
||||
"TYPST_PACKAGE_PATH",
|
||||
"TYPST_PACKAGE_CACHE_PATH",
|
||||
] as const;
|
||||
|
||||
const SANDBOX_HIDDEN_ENV_KEYS = [
|
||||
@@ -134,6 +136,7 @@ export async function createAgentSecurityPolicy(input: AgentSecurityInput): Prom
|
||||
|
||||
const sensitiveReadPaths = hostSensitiveReadPaths(hostEnv);
|
||||
const runtimeReadPaths = hostRuntimeReadPaths(hostEnv);
|
||||
const typstCacheWritePaths = hostTypstCacheWritePaths(hostEnv);
|
||||
const selectedSkills = input.skills ?? [];
|
||||
const skillPlugin = selectedSkills.length === 0
|
||||
? null
|
||||
@@ -174,7 +177,7 @@ export async function createAgentSecurityPolicy(input: AgentSecurityInput): Prom
|
||||
autoAllowBashIfSandboxed: true,
|
||||
allowUnsandboxedCommands: false,
|
||||
filesystem: {
|
||||
allowWrite: [workspaceDir],
|
||||
allowWrite: [...new Set([workspaceDir, ...typstCacheWritePaths])],
|
||||
// Reject every write path by default, then re-open only the canonical
|
||||
// workspace. This prevents bubblewrap's ordinary temp exceptions from
|
||||
// turning an unauthorized path into a successful ephemeral write.
|
||||
@@ -244,9 +247,30 @@ function hostRuntimeReadPaths(env: Readonly<Record<string, string | undefined>>)
|
||||
if (!isAbsolute(cphBin)) throw new Error("CPH_BIN must be absolute for the Agent subprocess");
|
||||
platformPaths.push(resolve(cphBin));
|
||||
}
|
||||
platformPaths.push(...configuredTypstPackagePaths(env, ["TYPST_PACKAGE_PATH", "TYPST_PACKAGE_CACHE_PATH"]));
|
||||
return [...new Set(platformPaths.map((path) => resolve(path)))];
|
||||
}
|
||||
|
||||
function hostTypstCacheWritePaths(env: Readonly<Record<string, string | undefined>>): string[] {
|
||||
return configuredTypstPackagePaths(env, ["TYPST_PACKAGE_CACHE_PATH"]);
|
||||
}
|
||||
|
||||
function configuredTypstPackagePaths(
|
||||
env: Readonly<Record<string, string | undefined>>,
|
||||
names: readonly ("TYPST_PACKAGE_PATH" | "TYPST_PACKAGE_CACHE_PATH")[],
|
||||
): string[] {
|
||||
const paths: string[] = [];
|
||||
for (const name of names) {
|
||||
const packagePath = env[name]?.trim();
|
||||
if (packagePath === undefined || packagePath === "") continue;
|
||||
if (!isAbsolute(packagePath)) throw new Error(`${name} must be absolute for the Agent subprocess`);
|
||||
const canonical = resolve(packagePath);
|
||||
if (canonical === "/") throw new Error(`${name} must not be the filesystem root`);
|
||||
paths.push(canonical);
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
|
||||
function hostSensitiveReadPaths(env: Readonly<Record<string, string | undefined>>): string[] {
|
||||
const home = homedir();
|
||||
const paths = [
|
||||
|
||||
Reference in New Issue
Block a user