Public release release-6d1a121b0a8a
Source commit: 6d1a121b0a8a636aac95998fe5d15c24c78eb7d0 Public tree identity: sha256:2bc22807f5b838286678b65d3f550b8ae4714ae673622041d4c2516a7c5b7926
This commit is contained in:
commit
21f097d9a8
210 changed files with 78649 additions and 0 deletions
99
scripts/agent-signing.js
Normal file
99
scripts/agent-signing.js
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
const crypto = require("crypto");
|
||||
|
||||
const { nodeIdentity, signedRequestPayloadDigest } = require("./node-signing");
|
||||
|
||||
function agentIdentity(seedPrefix, agent) {
|
||||
const identity = nodeIdentity(seedPrefix, agent);
|
||||
return {
|
||||
...identity,
|
||||
publicKeyFingerprint: `sha256:${crypto
|
||||
.createHash("sha256")
|
||||
.update(identity.publicKey)
|
||||
.digest("hex")}`,
|
||||
};
|
||||
}
|
||||
|
||||
function agentWorkflowSignatureMessage({
|
||||
tenant,
|
||||
project,
|
||||
agent,
|
||||
requestKind,
|
||||
process: processId,
|
||||
task = "",
|
||||
payloadDigest,
|
||||
nonce,
|
||||
issuedAtEpochSeconds,
|
||||
}) {
|
||||
const parts = [
|
||||
"clusterflux-agent-workflow-signature:v2",
|
||||
tenant,
|
||||
project,
|
||||
agent,
|
||||
requestKind,
|
||||
processId,
|
||||
task,
|
||||
payloadDigest,
|
||||
nonce,
|
||||
String(issuedAtEpochSeconds),
|
||||
];
|
||||
return Buffer.concat(
|
||||
parts.flatMap((part) => [
|
||||
Buffer.from(`${Buffer.byteLength(part)}:`),
|
||||
Buffer.from(part),
|
||||
Buffer.from("\n"),
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
function signedAgentWorkflowProof(identity, request, options = {}) {
|
||||
const nonce =
|
||||
options.nonce ||
|
||||
`${request.type}-${process.pid}-${Date.now()}-${crypto
|
||||
.randomBytes(8)
|
||||
.toString("hex")}`;
|
||||
const issuedAtEpochSeconds =
|
||||
options.issuedAtEpochSeconds || Math.floor(Date.now() / 1000);
|
||||
const processId =
|
||||
request.type === "launch_task" ? request.task_spec?.process : request.process;
|
||||
const task =
|
||||
request.type === "launch_task" ? request.task_spec?.task_instance : request.task || "";
|
||||
const signature = crypto.sign(
|
||||
null,
|
||||
agentWorkflowSignatureMessage({
|
||||
tenant: request.tenant,
|
||||
project: request.project,
|
||||
agent: request.actor_agent,
|
||||
requestKind: request.type,
|
||||
process: processId,
|
||||
task,
|
||||
payloadDigest: signedRequestPayloadDigest(request),
|
||||
nonce,
|
||||
issuedAtEpochSeconds,
|
||||
}),
|
||||
identity.privateKeyObject
|
||||
);
|
||||
return {
|
||||
nonce,
|
||||
issued_at_epoch_seconds: issuedAtEpochSeconds,
|
||||
signature: `ed25519:${signature.toString("base64")}`,
|
||||
};
|
||||
}
|
||||
|
||||
function signedAgentWorkflowRequest(identity, request, options = {}) {
|
||||
const unsignedRequest = {
|
||||
...request,
|
||||
agent_public_key_fingerprint:
|
||||
options.publicKeyFingerprint || identity.publicKeyFingerprint,
|
||||
};
|
||||
return {
|
||||
...unsignedRequest,
|
||||
agent_signature: signedAgentWorkflowProof(identity, unsignedRequest, options),
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
agentIdentity,
|
||||
agentWorkflowSignatureMessage,
|
||||
signedAgentWorkflowProof,
|
||||
signedAgentWorkflowRequest,
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue