fix: enforce device pod profile identity

This commit is contained in:
Codex
2026-05-29 20:31:30 +08:00
parent 12c6331e63
commit fb46d6c267
2 changed files with 8 additions and 1 deletions
+6
View File
@@ -55,6 +55,7 @@ test("cloud api access control grants visible device pods and requires device-po
name: "71-FREQ",
profile: {
schemaVersion: 1,
devicePodId: "device-pod-local-spoof",
target: { id: "target-71-freq" },
projectWorkspace: { projectPath: "FirmWare/MDK-ARM/app.uvprojx", targetName: "app" },
route: {
@@ -66,6 +67,8 @@ test("cloud api access control grants visible device pods and requires device-po
}
}, adminCookie);
assert.equal(podCreate.status, 201);
assert.equal(podCreate.body.devicePod.devicePodId, "device-pod-71-freq");
assert.notEqual(podCreate.body.devicePod.profileHash, "sha256:a-local-profile-hash");
assert.equal(podCreate.body.devicePod.profile.route.gatewaySessionId, "redacted");
assert.equal(JSON.stringify(podCreate.body).includes("gws_missing"), false);
@@ -782,6 +785,7 @@ test("cloud api first-admin setup opens access when bootstrap secret is absent",
name: "71-FREQ",
profile: {
schemaVersion: 1,
devicePodId: "device-pod-seed-spoof",
target: { id: "target-71-freq" },
route: {
gatewaySessionId: "gws_first_admin_seed",
@@ -802,7 +806,9 @@ test("cloud api first-admin setup opens access when bootstrap secret is absent",
assert.deepEqual(setup.body.devicePodBootstrap, { requested: 1, initialized: 1 });
assert.equal(setup.body.devicePodsInitialized[0].devicePod.devicePodId, "device-pod-71-freq");
assert.equal(setup.body.devicePodsInitialized[0].grant.userId, setup.body.actor.id);
assert.match(setup.body.devicePodsInitialized[0].devicePod.profileHash, /^sha256:/u);
assert.equal(setup.body.devicePodsInitialized[0].devicePod.profile.route.gatewaySessionId, "redacted");
assert.equal(JSON.stringify(setup.body).includes("device-pod-seed-spoof"), false);
assert.equal(JSON.stringify(setup.body).includes("admin-pass"), false);
assert.equal(JSON.stringify(setup.body).includes("gws_first_admin_seed"), false);
assert.equal(JSON.stringify(setup.body).includes("F:\\Work\\Project"), false);
+2 -1
View File
@@ -1023,7 +1023,7 @@ class MemoryAccessStore {
async revokeSessionByTokenHash(tokenHash, now) { for (const session of this.sessions.values()) if (session.tokenHash === tokenHash) session.revokedAt = now; }
async upsertDevicePod(input) {
const existing = this.devicePods.get(input.id);
const profile = assertDevicePodProfileSafe(normalizeObject(input.profile), "profile");
const profile = devicePodProfileForAuthority(input.id, normalizeObject(input.profile));
const now = input.now ?? this.now();
const pod = { id: input.id, name: input.name ?? existing?.name ?? input.id, status: input.status ?? existing?.status ?? "active", profile, profileHash: profileHash(profile), createdAt: existing?.createdAt ?? now, updatedAt: now };
this.devicePods.set(pod.id, pod);
@@ -1174,6 +1174,7 @@ function assertDevicePodProfileSafe(profile, field = "profile") {
}
return profile;
}
function devicePodProfileForAuthority(devicePodId, profile) { return { ...assertDevicePodProfileSafe(profile, "profile"), devicePodId }; }
function collectDevicePodProfileSecretFindings(value, path, findings) {
if (findings.length >= 5) return;
if (Array.isArray(value)) {