Spaces:
Running
Running
Add measured source attestation route
#1
by betterwithage - opened
- Dockerfile +1 -0
- dist/immune-server.js +25 -0
- dist/szl-source-attestation.mjs +139 -0
- tests/test-source-attestation.mjs +75 -0
Dockerfile
CHANGED
|
@@ -23,6 +23,7 @@ WORKDIR /app
|
|
| 23 |
|
| 24 |
# Self-contained server bundle, the vite-built SPA, and the REAL receipt/evidence chain.
|
| 25 |
COPY dist/immune-server.js ./immune-server.js
|
|
|
|
| 26 |
COPY dist/public ./public
|
| 27 |
COPY dist/data ./data
|
| 28 |
|
|
|
|
| 23 |
|
| 24 |
# Self-contained server bundle, the vite-built SPA, and the REAL receipt/evidence chain.
|
| 25 |
COPY dist/immune-server.js ./immune-server.js
|
| 26 |
+
COPY dist/szl-source-attestation.mjs ./szl-source-attestation.mjs
|
| 27 |
COPY dist/public ./public
|
| 28 |
COPY dist/data ./data
|
| 29 |
|
dist/immune-server.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
import { createRequire as __immuneCreateRequire } from 'node:module'; globalThis.require = globalThis.require || __immuneCreateRequire(import.meta.url);
|
|
|
|
| 2 |
var __create = Object.create;
|
| 3 |
var __defProp = Object.defineProperty;
|
| 4 |
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -34263,10 +34264,34 @@ var __serverDir = path3.dirname(fileURLToPath(import.meta.url));
|
|
| 34263 |
var app = (0, import_express3.default)();
|
| 34264 |
app.disable("x-powered-by");
|
| 34265 |
app.set("trust proxy", 1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34266 |
app.use(import_express3.default.json({ limit: "2mb" }));
|
| 34267 |
app.get("/healthz", (_req, res) => {
|
| 34268 |
res.json({ ok: true, service: "immune-standalone" });
|
| 34269 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34270 |
app.use("/api/immune", immune_default);
|
| 34271 |
app.use("/api", (_req, res) => {
|
| 34272 |
res.status(404).json({ error: "not found" });
|
|
|
|
| 1 |
import { createRequire as __immuneCreateRequire } from 'node:module'; globalThis.require = globalThis.require || __immuneCreateRequire(import.meta.url);
|
| 2 |
+
import { buildSourceAttestation } from "./szl-source-attestation.mjs";
|
| 3 |
var __create = Object.create;
|
| 4 |
var __defProp = Object.defineProperty;
|
| 5 |
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
|
| 34264 |
var app = (0, import_express3.default)();
|
| 34265 |
app.disable("x-powered-by");
|
| 34266 |
app.set("trust proxy", 1);
|
| 34267 |
+
app.use((_req, res, next) => {
|
| 34268 |
+
res.set("X-Content-Type-Options", "nosniff");
|
| 34269 |
+
res.set("Referrer-Policy", "no-referrer");
|
| 34270 |
+
res.set(
|
| 34271 |
+
"Permissions-Policy",
|
| 34272 |
+
"camera=(), microphone=(), geolocation=(), payment=(), usb=()"
|
| 34273 |
+
);
|
| 34274 |
+
next();
|
| 34275 |
+
});
|
| 34276 |
app.use(import_express3.default.json({ limit: "2mb" }));
|
| 34277 |
app.get("/healthz", (_req, res) => {
|
| 34278 |
res.json({ ok: true, service: "immune-standalone" });
|
| 34279 |
});
|
| 34280 |
+
app.get("/.well-known/szl-source.json", async (req, res) => {
|
| 34281 |
+
const force = req.query.refresh === "1";
|
| 34282 |
+
const document = await buildSourceAttestation({ force });
|
| 34283 |
+
res.set("Cache-Control", "no-store");
|
| 34284 |
+
res.set(
|
| 34285 |
+
"Content-Security-Policy",
|
| 34286 |
+
"default-src 'none'; frame-ancestors 'none'; base-uri 'none'"
|
| 34287 |
+
);
|
| 34288 |
+
res.set("Cross-Origin-Resource-Policy", "same-origin");
|
| 34289 |
+
res.set("X-SZL-Transport-State", "REACHABLE");
|
| 34290 |
+
res.set("X-SZL-Evidence-State", document.evidence_state);
|
| 34291 |
+
res.set("X-SZL-Verification-State", "STRUCTURAL_ONLY");
|
| 34292 |
+
res.set("X-SZL-Authority-State", "READ_ONLY");
|
| 34293 |
+
res.json(document);
|
| 34294 |
+
});
|
| 34295 |
app.use("/api/immune", immune_default);
|
| 34296 |
app.use("/api", (_req, res) => {
|
| 34297 |
res.status(404).json({ error: "not found" });
|
dist/szl-source-attestation.mjs
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const SHA40 = /^[0-9a-f]{40}$/;
|
| 2 |
+
const SPACE_ID = "SZLHOLDINGS/immune";
|
| 3 |
+
const SOURCE_REFERENCE = {
|
| 4 |
+
repository: "szl-holdings/immune",
|
| 5 |
+
commit: "649e7bb87063f3a83dfa978e77c1359e4728ddd8",
|
| 6 |
+
path: "",
|
| 7 |
+
relation: "direct-mirror-declaration",
|
| 8 |
+
commit_state: "MEASURED_GITHUB_MAIN_REFERENCE",
|
| 9 |
+
build_source_state: "NOT_PROVEN"
|
| 10 |
+
};
|
| 11 |
+
const OVERLAY_BASE_REVISION = "f26b626ef36f09ca878d58ab70835c61ae4df24f";
|
| 12 |
+
|
| 13 |
+
let cached = null;
|
| 14 |
+
|
| 15 |
+
function nowIso() {
|
| 16 |
+
return new Date().toISOString();
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
function validSha(value) {
|
| 20 |
+
const candidate = String(value || "").trim().toLowerCase();
|
| 21 |
+
return SHA40.test(candidate) ? candidate : null;
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
export function clearSourceAttestationCache() {
|
| 25 |
+
cached = null;
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
export async function measureHfHead({
|
| 29 |
+
force = false,
|
| 30 |
+
fetchImpl = globalThis.fetch,
|
| 31 |
+
env = process.env,
|
| 32 |
+
now = Date.now
|
| 33 |
+
} = {}) {
|
| 34 |
+
const at = now();
|
| 35 |
+
if (!force && cached && at - cached.storedAt < 60_000) {
|
| 36 |
+
return { ...cached.measurement };
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
const envRevision = validSha(env.SPACE_REPOSITORY_COMMIT);
|
| 40 |
+
if (envRevision) {
|
| 41 |
+
const measurement = {
|
| 42 |
+
hf_revision: envRevision,
|
| 43 |
+
last_modified: null,
|
| 44 |
+
observed_at: nowIso(),
|
| 45 |
+
state: "MEASURED",
|
| 46 |
+
method: "SPACE_REPOSITORY_COMMIT",
|
| 47 |
+
resolver: "runtime environment",
|
| 48 |
+
semantics: "Exact commit exposed by the running Hugging Face Space."
|
| 49 |
+
};
|
| 50 |
+
cached = { storedAt: now(), measurement: { ...measurement } };
|
| 51 |
+
return measurement;
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
const endpoint =
|
| 55 |
+
`https://huggingface.co/api/spaces/${SPACE_ID}?expand[]=sha&expand[]=lastModified`;
|
| 56 |
+
const controller = new AbortController();
|
| 57 |
+
const timer = setTimeout(() => controller.abort(), 4_000);
|
| 58 |
+
let measurement;
|
| 59 |
+
try {
|
| 60 |
+
const response = await fetchImpl(endpoint, {
|
| 61 |
+
headers: {
|
| 62 |
+
Accept: "application/json",
|
| 63 |
+
"User-Agent": "szl-immune-source-attestation/1.0"
|
| 64 |
+
},
|
| 65 |
+
signal: controller.signal
|
| 66 |
+
});
|
| 67 |
+
if (!response.ok) throw new Error(`HTTP_${response.status}`);
|
| 68 |
+
const payload = await response.json();
|
| 69 |
+
const revision = validSha(payload.sha);
|
| 70 |
+
measurement = {
|
| 71 |
+
hf_revision: revision,
|
| 72 |
+
last_modified:
|
| 73 |
+
typeof payload.lastModified === "string" ? payload.lastModified : null,
|
| 74 |
+
observed_at: nowIso(),
|
| 75 |
+
state: revision ? "MEASURED" : "UNAVAILABLE",
|
| 76 |
+
method: revision ? "HUGGINGFACE_API" : "UNAVAILABLE",
|
| 77 |
+
resolver: endpoint,
|
| 78 |
+
semantics:
|
| 79 |
+
"Measured Hugging Face repository head; not proof of a rolling process revision."
|
| 80 |
+
};
|
| 81 |
+
} catch (error) {
|
| 82 |
+
measurement = {
|
| 83 |
+
hf_revision: null,
|
| 84 |
+
last_modified: null,
|
| 85 |
+
observed_at: nowIso(),
|
| 86 |
+
state: "UNAVAILABLE",
|
| 87 |
+
method: "UNAVAILABLE",
|
| 88 |
+
resolver: endpoint,
|
| 89 |
+
error: error instanceof Error ? error.name : "Error",
|
| 90 |
+
semantics: "No revision guessed when measurement is unavailable."
|
| 91 |
+
};
|
| 92 |
+
} finally {
|
| 93 |
+
clearTimeout(timer);
|
| 94 |
+
}
|
| 95 |
+
cached = { storedAt: now(), measurement: { ...measurement } };
|
| 96 |
+
return measurement;
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
export async function buildSourceAttestation(options = {}) {
|
| 100 |
+
const measurement = await measureHfHead(options);
|
| 101 |
+
return {
|
| 102 |
+
schema: "szl.deployment-source/v1",
|
| 103 |
+
source: { ...SOURCE_REFERENCE },
|
| 104 |
+
deployment: {
|
| 105 |
+
hf_space: SPACE_ID,
|
| 106 |
+
hf_revision: measurement.hf_revision
|
| 107 |
+
},
|
| 108 |
+
built_at: measurement.last_modified,
|
| 109 |
+
observed_at: measurement.observed_at,
|
| 110 |
+
transport_state: "REACHABLE",
|
| 111 |
+
evidence_state: measurement.hf_revision ? "COMPUTED" : "UNAVAILABLE",
|
| 112 |
+
verification_state: "STRUCTURAL_ONLY",
|
| 113 |
+
authority_state: "READ_ONLY",
|
| 114 |
+
alignment_state: "SOURCE_REFERENCE_ONLY",
|
| 115 |
+
attestation_state: "UNSIGNED_STRUCTURAL",
|
| 116 |
+
claims: {
|
| 117 |
+
github_parity: "NOT_CLAIMED",
|
| 118 |
+
reproducible_build: "NOT_CLAIMED",
|
| 119 |
+
running_process_revision:
|
| 120 |
+
measurement.method === "SPACE_REPOSITORY_COMMIT"
|
| 121 |
+
? "MEASURED_FROM_RUNTIME_ENVIRONMENT"
|
| 122 |
+
: "NOT_CLAIMED"
|
| 123 |
+
},
|
| 124 |
+
extensions: {
|
| 125 |
+
schema: "szl.deployment-source-evidence/v1",
|
| 126 |
+
deployment_revision_evidence: measurement,
|
| 127 |
+
overlay: {
|
| 128 |
+
base_revision: OVERLAY_BASE_REVISION,
|
| 129 |
+
base_revision_semantics:
|
| 130 |
+
"Hugging Face head inspected before this attestation overlay."
|
| 131 |
+
}
|
| 132 |
+
},
|
| 133 |
+
limits: [
|
| 134 |
+
"The GitHub commit is a measured source reference, not asserted build provenance.",
|
| 135 |
+
"Repository-head evidence does not establish deployed-artifact equivalence.",
|
| 136 |
+
"This unsigned structural document does not establish SLSA provenance or reproducible builds."
|
| 137 |
+
]
|
| 138 |
+
};
|
| 139 |
+
}
|
tests/test-source-attestation.mjs
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import test from "node:test";
|
| 2 |
+
import assert from "node:assert/strict";
|
| 3 |
+
import {
|
| 4 |
+
buildSourceAttestation,
|
| 5 |
+
clearSourceAttestationCache,
|
| 6 |
+
measureHfHead
|
| 7 |
+
} from "../dist/szl-source-attestation.mjs";
|
| 8 |
+
|
| 9 |
+
test("runtime revision is measured without parity overclaim", async () => {
|
| 10 |
+
clearSourceAttestationCache();
|
| 11 |
+
const revision = "a".repeat(40);
|
| 12 |
+
const document = await buildSourceAttestation({
|
| 13 |
+
force: true,
|
| 14 |
+
env: { SPACE_REPOSITORY_COMMIT: revision }
|
| 15 |
+
});
|
| 16 |
+
assert.equal(document.deployment.hf_revision, revision);
|
| 17 |
+
assert.equal(document.verification_state, "STRUCTURAL_ONLY");
|
| 18 |
+
assert.equal(document.authority_state, "READ_ONLY");
|
| 19 |
+
assert.equal(document.claims.github_parity, "NOT_CLAIMED");
|
| 20 |
+
assert.equal(document.claims.reproducible_build, "NOT_CLAIMED");
|
| 21 |
+
assert.equal(
|
| 22 |
+
document.claims.running_process_revision,
|
| 23 |
+
"MEASURED_FROM_RUNTIME_ENVIRONMENT"
|
| 24 |
+
);
|
| 25 |
+
});
|
| 26 |
+
|
| 27 |
+
test("Hub API fallback reports repository-head semantics", async () => {
|
| 28 |
+
clearSourceAttestationCache();
|
| 29 |
+
const revision = "b".repeat(40);
|
| 30 |
+
const fetchImpl = async () => ({
|
| 31 |
+
ok: true,
|
| 32 |
+
json: async () => ({
|
| 33 |
+
sha: revision,
|
| 34 |
+
lastModified: "2026-07-11T22:00:00.000Z"
|
| 35 |
+
})
|
| 36 |
+
});
|
| 37 |
+
const measurement = await measureHfHead({
|
| 38 |
+
force: true,
|
| 39 |
+
env: {},
|
| 40 |
+
fetchImpl
|
| 41 |
+
});
|
| 42 |
+
assert.equal(measurement.hf_revision, revision);
|
| 43 |
+
assert.equal(measurement.method, "HUGGINGFACE_API");
|
| 44 |
+
assert.match(measurement.semantics, /repository head/);
|
| 45 |
+
});
|
| 46 |
+
|
| 47 |
+
test("measurement failure never invents a revision", async () => {
|
| 48 |
+
clearSourceAttestationCache();
|
| 49 |
+
const measurement = await measureHfHead({
|
| 50 |
+
force: true,
|
| 51 |
+
env: {},
|
| 52 |
+
fetchImpl: async () => {
|
| 53 |
+
throw new Error("offline");
|
| 54 |
+
}
|
| 55 |
+
});
|
| 56 |
+
assert.equal(measurement.hf_revision, null);
|
| 57 |
+
assert.equal(measurement.state, "UNAVAILABLE");
|
| 58 |
+
});
|
| 59 |
+
|
| 60 |
+
test("well-known route precedes API and SPA fallbacks", async () => {
|
| 61 |
+
const fs = await import("node:fs/promises");
|
| 62 |
+
const server = await fs.readFile(
|
| 63 |
+
new URL("../dist/immune-server.js", import.meta.url),
|
| 64 |
+
"utf8"
|
| 65 |
+
);
|
| 66 |
+
assert.ok(
|
| 67 |
+
server.indexOf('app.get("/.well-known/szl-source.json"') <
|
| 68 |
+
server.indexOf('app.use("/api/immune"')
|
| 69 |
+
);
|
| 70 |
+
assert.ok(
|
| 71 |
+
server.indexOf('app.get("/.well-known/szl-source.json"') <
|
| 72 |
+
server.indexOf('app.get("/{*splat}"')
|
| 73 |
+
);
|
| 74 |
+
assert.match(server, /Cache-Control", "no-store"/);
|
| 75 |
+
});
|