Supply exact private platform source to sealed checks without private evaluator egress
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
generator,
|
generator,
|
||||||
contractOnly ? false,
|
contractOnly ? false,
|
||||||
workspaceId ? null,
|
workspaceId ? null,
|
||||||
|
platformSourceJSON ? null,
|
||||||
system ? builtins.currentSystem,
|
system ? builtins.currentSystem,
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
@@ -71,9 +72,16 @@ let
|
|||||||
else
|
else
|
||||||
{ };
|
{ };
|
||||||
execution = (configuration.backend or "typescript") == "execution";
|
execution = (configuration.backend or "typescript") == "execution";
|
||||||
runtime = builtins.getFlake (
|
platformSource = if platformSourceJSON == null then null else builtins.fromJSON platformSourceJSON;
|
||||||
|
runtime =
|
||||||
|
if platformSource == null then
|
||||||
|
builtins.getFlake (
|
||||||
"git+${root.lock.quixos.repository}?rev=${root.lock.quixos.commit}&ref=refs/tags/quixos-reachability/${root.lock.quixos.commit}"
|
"git+${root.lock.quixos.repository}?rev=${root.lock.quixos.commit}&ref=refs/tags/quixos-reachability/${root.lock.quixos.commit}"
|
||||||
);
|
)
|
||||||
|
else
|
||||||
|
assert platformSource.repository == root.lock.quixos.repository;
|
||||||
|
assert platformSource.commit == root.lock.quixos.commit;
|
||||||
|
builtins.getFlake "path:${builtins.storePath platformSource.directory}";
|
||||||
runtimePackages = runtime.packages.${system};
|
runtimePackages = runtime.packages.${system};
|
||||||
resourceClosure =
|
resourceClosure =
|
||||||
includeBuild: node:
|
includeBuild: node:
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ export async function buildImmutableCandidate(
|
|||||||
contractOnly = false,
|
contractOnly = false,
|
||||||
observe?: (phase: "nixEvaluationMs" | "nixBuildMs", ms: number) => void,
|
observe?: (phase: "nixEvaluationMs" | "nixBuildMs", ms: number) => void,
|
||||||
workspaceId?: string,
|
workspaceId?: string,
|
||||||
|
platformSource?: { repository: string; commit: string; directory: string },
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
if (workspaceId !== undefined && (kind !== "workspace" || !/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,255}$/.test(workspaceId)))
|
if (workspaceId !== undefined && (kind !== "workspace" || !/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,255}$/.test(workspaceId)))
|
||||||
throw new Error("Instance binding requires a valid Workspace identity and a Workspace root");
|
throw new Error("Instance binding requires a valid Workspace identity and a Workspace root");
|
||||||
@@ -121,6 +122,13 @@ export async function buildImmutableCandidate(
|
|||||||
const url = new URL(source.repository);
|
const url = new URL(source.repository);
|
||||||
if (url.protocol !== "https:" || url.username || url.password || url.search || url.hash)
|
if (url.protocol !== "https:" || url.username || url.password || url.search || url.hash)
|
||||||
throw new Error("Candidate origin must be credential-free HTTPS");
|
throw new Error("Candidate origin must be credential-free HTTPS");
|
||||||
|
if (
|
||||||
|
platformSource &&
|
||||||
|
(Object.keys(platformSource).sort().join(",") !== "commit,directory,repository" ||
|
||||||
|
!/^[a-f0-9]{40}$/.test(platformSource.commit) ||
|
||||||
|
!/^\/nix\/store\/[a-z0-9]{32}-[^/\s]+$/.test(platformSource.directory))
|
||||||
|
)
|
||||||
|
throw Error("Invalid immutable platform source input");
|
||||||
const generator =
|
const generator =
|
||||||
process.env.QUIXOS_CHECK_GENERATOR ?? path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
|
process.env.QUIXOS_CHECK_GENERATOR ?? path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
|
||||||
if (!/^\/nix\/store\/[^/]+$/.test(generator)) throw new Error("Use the installed Quixos checker");
|
if (!/^\/nix\/store\/[^/]+$/.test(generator)) throw new Error("Use the installed Quixos checker");
|
||||||
@@ -204,6 +212,7 @@ export async function buildImmutableCandidate(
|
|||||||
"contractOnly",
|
"contractOnly",
|
||||||
contractOnly ? "true" : "false",
|
contractOnly ? "true" : "false",
|
||||||
...(workspaceId === undefined ? [] : ["--argstr", "workspaceId", workspaceId]),
|
...(workspaceId === undefined ? [] : ["--argstr", "workspaceId", workspaceId]),
|
||||||
|
...(platformSource ? ["--argstr", "platformSourceJSON", JSON.stringify(platformSource)] : []),
|
||||||
"--add-root",
|
"--add-root",
|
||||||
gcRoot,
|
gcRoot,
|
||||||
"--indirect",
|
"--indirect",
|
||||||
|
|||||||
@@ -6,5 +6,13 @@ const [repository, commit, log, workspaceId] = process.argv.slice(2);
|
|||||||
if (!repository || !commit || !log || !workspaceId || process.argv.length !== 6)
|
if (!repository || !commit || !log || !workspaceId || process.argv.length !== 6)
|
||||||
throw Error("source-check-driver REPOSITORY COMMIT LOG WORKSPACE_ID");
|
throw Error("source-check-driver REPOSITORY COMMIT LOG WORKSPACE_ID");
|
||||||
process.stdout.write(
|
process.stdout.write(
|
||||||
(await buildImmutableCandidate({ repository, commit }, "workspace", log, false, undefined, workspaceId)) + "\n",
|
(await buildImmutableCandidate(
|
||||||
|
{ repository, commit },
|
||||||
|
"workspace",
|
||||||
|
log,
|
||||||
|
false,
|
||||||
|
undefined,
|
||||||
|
workspaceId,
|
||||||
|
process.env.QUIXOS_CHECK_PLATFORM_SOURCE ? JSON.parse(process.env.QUIXOS_CHECK_PLATFORM_SOURCE) : undefined,
|
||||||
|
)) + "\n",
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,20 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
import { loadQuixosLock } from "./loader.js";
|
import { loadQuixosLock } from "./loader.js";
|
||||||
|
import { parseQuixosLockDocument } from "./parser.js";
|
||||||
|
import { readFile, stat } from "node:fs/promises";
|
||||||
|
|
||||||
|
// A trusted fetcher can inspect the root's declared platform pin without
|
||||||
|
// following authored import paths or evaluating Nix. The input is a fetched
|
||||||
|
// Git blob, not a filesystem tree provided by an author.
|
||||||
|
if (process.argv[2] === "--platform-only") {
|
||||||
|
const filename = process.argv[3];
|
||||||
|
if (process.argv.length !== 4 || !filename || (await stat(filename)).size > 1024 * 1024)
|
||||||
|
throw Error("INVALID_PLATFORM_SOURCE_LOCK");
|
||||||
|
const result = parseQuixosLockDocument(await readFile(filename, "utf8"));
|
||||||
|
if (!result.ok || result.document.kind !== "root") throw Error("INVALID_PLATFORM_SOURCE_LOCK");
|
||||||
|
console.log(JSON.stringify({ repository: result.document.quixos.repository, commit: result.document.quixos.commit }));
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
const fileName = process.argv[2];
|
const fileName = process.argv[2];
|
||||||
if (!fileName || process.argv.length !== 3) {
|
if (!fileName || process.argv.length !== 3) {
|
||||||
|
|||||||
Reference in New Issue
Block a user