Public release release-98d969b26488
Source commit: 98d969b26488b4cda8b2381fa870276a00ca98ea Public tree identity: sha256:d02dd1e8d3547a489bb300741bed544bdc60bb8fe0bd541fd43ce9bfa7129a3e
This commit is contained in:
commit
8ded2b6a42
210 changed files with 76954 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