feat(device-core): add restricted identity references

This commit is contained in:
Codex
2026-08-10 18:31:30 +03:00
parent fceaca9546
commit 422ddb020f
20 changed files with 1413 additions and 7 deletions
@@ -116,6 +116,84 @@ test("management API forwards claim as evidence references without identity inpu
}
});
test("management API accepts only a canonical credential reference", async () => {
let executed;
const runtime = await startServer({
managementApiEnabled: true,
managementToken,
repository: {
health: async () => "ready",
executeManagementCommand: async (input) => {
executed = input;
return {
replayed: false,
result: {
credentialBinding: {
credentialBindingRef:
"credential-binding:44444444-4444-4444-8444-444444444444",
},
},
};
},
},
});
try {
const response = await fetch(
`${runtime.baseUrl}/internal/v1/management/device-credential-bindings:upsert`,
{
method: "POST",
headers: managementHeaders(),
body: JSON.stringify({
projectRef: "project:11111111-1111-4111-8111-111111111111",
deviceRef: "device:22222222-2222-4222-8222-222222222222",
purpose: "tracker.command",
credentialRef: {
owner: "ndc_l2_credentials",
reference: "ndc-credref:pilot-command-0001",
},
}),
},
);
assert.equal(response.status, 200);
assert.equal(
executed.commandKind,
"device_credential_binding.upsert",
);
assert.deepEqual(executed.command.credentialRef, {
owner: "ndc_l2_credentials",
reference: "ndc-credref:pilot-command-0001",
});
const rejected = await fetch(
`${runtime.baseUrl}/internal/v1/management/device-credential-bindings:upsert`,
{
method: "POST",
headers: {
...managementHeaders(),
"Idempotency-Key": "phase24-credential-invalid-0001",
},
body: JSON.stringify({
projectRef: "project:11111111-1111-4111-8111-111111111111",
deviceRef: "device:22222222-2222-4222-8222-222222222222",
purpose: "tracker.command",
credentialRef: {
owner: "device_core",
reference: "ndc-credref:pilot-command-0001",
},
}),
},
);
assert.equal(rejected.status, 400);
assert.equal(
(await rejected.json()).error,
"ndc_credential_reference_owner_invalid",
);
} finally {
await runtime.close();
}
});
async function startServer(options) {
const server = createControlCoreApp(options);
await new Promise((resolve, reject) => {