better/compute
API

commandBatches

Destructive-command batches (v1.0 quorum). A batch fixes a set of (subject, kind) leaves, optionally bound to exact payloads, under one Merkle root when it is created (modules create them through `commands.createBatch`). When the deployment publishes approver keys (`pki.approvers`), the batch's commands wait until enough approvers, holding keys off the control plane, have signed its root for the trust domain. The gateway then sends each command with the approval and its leaf's proof, and the daemon verifies both. Without approver keys a batch is recorded for audit and its commands go out at once. See [Security](/docs/operations/security).

Destructive-command batches (v1.0 quorum). A batch fixes a set of (subject, kind) leaves, optionally bound to exact payloads, under one Merkle root when it is created (modules create them through commands.createBatch). When the deployment publishes approver keys (pki.approvers), the batch's commands wait until enough approvers, holding keys off the control plane, have signed its root for the trust domain. The gateway then sends each command with the approval and its leaf's proof, and the daemon verifies both. Without approver keys a batch is recorded for audit and its commands go out at once. See Security.

All 7 methods are served by this release.

MethodKindAuthorizationPhaseStatus
createmutationcompute:batches:create @ compute-tenantv1.0registered
getreadcompute:batches:read @ compute-tenantv1.0registered
listreadcompute:batches:read @ compute-tenantv1.0registered
scopereadcompute:batches:read @ compute-tenantv1.0registered
membersreadcompute:batches:read @ compute-tenantv1.0registered
approvemutationcompute:batches:approve @ compute-tenantv1.0registered
cancelmutationcompute:batches:approve @ compute-tenantv1.0registered

create

POST /api/compute/commandBatches/create

Creates a batch from its (subject, kind) leaves, each optionally bound to a payload's SHA-256, a reason and a lifetime; returns it pending, with the approvals its size needs.

  • The tree is fixed now: its root, size and every leaf's proof are stored, so what approvers review is what the daemons check. Subjects are computed as the executing agent does (see pki batchSubject): the node id, bmc:<site agent>/<address> for BMC kinds, node:<target> for site.httpProxy. A leaf without payloadSha256 admits any payload of its kind, and scope flags it to approvers.
  • Idempotency. The batch id derives from the tenant, the caller and idempotencyKey. The same request again (the same leaves in any order, reason and lifetime) returns the stored batch without a new event; a different request under the key is CONFLICT.
  • The lifetime is notAfterSeconds (default 24 hours): after it the batch admits no commands and can no longer be approved. At most 50,000 leaves.

Publishes command.batch.created with the scope size and the approvals required.

  • Kind: mutation
  • Authorization: compute:batches:create @ compute-tenant
  • Module: quorum
  • Phase: v1.0 (registered)

Input

FieldTypeRequiredConstraints
tenantIdstringyes
reasonstringyes
scopelist of objectyes
scope[].subjectstringyes
scope[].kindstringyes
scope[].payloadSha256string
scope[].payloadobject
scope[].payload.typeUrlstringyes
scope[].payload.valuestringyes
notAfterSecondsinteger
idempotencyKeystringyes

get

POST /api/compute/commandBatches/get

Returns one batch of the tenant: its reason, state, scope root and size, the approvals it needs and has, and how many of its commands are in each state.

The state is expired as soon as notAfter passes, even before the minute sweep writes it. A batch of another tenant is NOT_FOUND.

createdBy is the identity that created the batch. When an agent proposed it on that identity's behalf (MCP propose_command_batch), createdByAgent and delegationId say so, and the reason is the agent's text, not the person's.

  • Kind: read
  • Authorization: compute:batches:read @ compute-tenant
  • Module: quorum
  • Phase: v1.0 (registered)

Input

FieldTypeRequiredConstraints
tenantIdstringyes
batchIdstringyes

list

POST /api/compute/commandBatches/list

Returns the tenant's batches, newest first, filtered by state.

limit is 1 to 200 (default 50); next, when present, is the cursor for the following page.

  • Kind: read
  • Authorization: compute:batches:read @ compute-tenant
  • Module: quorum
  • Phase: v1.0 (registered)

Input

FieldTypeRequiredConstraints
tenantIdstringyes
stateone of pending, approved, expired, cancelled
limitinteger
cursorstring

scope

POST /api/compute/commandBatches/scope

Returns a batch's leaves in leaf order, for approvers to review before signing: each leaf's index, subject, kind and payloadSha256, plus the leaf's payload ({ typeUrl, value } base64) when its creator stored it. Decode it by the kind's payload type, after checking it against payloadSha256.

An empty payloadSha256 marks a leaf that admits any payload of its kind, which approvers should look at closely. Pages hold 1 to 5,000 leaves (1,000 by default); next is the leaf index to pass as cursor.

  • Kind: read
  • Authorization: compute:batches:read @ compute-tenant
  • Module: quorum
  • Phase: v1.0 (registered)

Input

FieldTypeRequiredConstraints
tenantIdstringyes
batchIdstringyes
cursorinteger
limitinteger

members

POST /api/compute/commandBatches/members

Returns the commands enqueued into a batch so far, in command-id order: each one's node, (subject, kind), state and reason, and awaitingApproval while it is held for the batch's approval.

state keeps one command state. Pages hold 1 to 500 commands (100 by default); next is the command id to pass as cursor. A batch of another tenant is NOT_FOUND.

  • Kind: read
  • Authorization: compute:batches:read @ compute-tenant
  • Module: quorum
  • Phase: v1.0 (registered)

Input

FieldTypeRequiredConstraints
tenantIdstringyes
batchIdstringyes
stateone of pending, dispatched, acked, running, succeeded, failed, rejected, expired, cancelled
limitinteger
cursorstring

approve

POST /api/compute/commandBatches/approve

Adds one approver's signature over the batch's root; once the signatures meet the threshold for its size, the batch becomes approved and its held commands are released at once.

  • signature is { kid, sig }: the approver key id and a base64url P-256 signature over the batch (id, root, size, end, trust domain), made off the control plane. A signature by a key outside the published set, or over anything else, is ACCESS_DENIED. The same approver twice counts once.
  • Decided as compute:batches:approve, on top of the signature, never instead of it.
  • INVALID_STATE for a batch that is not pending, or one that needs no approvals (no approver keys, or a size the tiers exempt). INVALID_CONFIG when the deployment has no trust domain (no pki.join).

Publishes command.batch.approved with the approver key ids when the batch completes.

  • Kind: mutation
  • Authorization: compute:batches:approve @ compute-tenant
  • Module: quorum
  • Phase: v1.0 (registered)

Input

FieldTypeRequiredConstraints
tenantIdstringyes
batchIdstringyes
signatureobjectyes
signature.kidstringyes
signature.sigstringyes

cancel

POST /api/compute/commandBatches/cancel

Ends a pending batch: it becomes cancelled and its held commands are cancelled with it.

A batch that is not pending is INVALID_STATE. Decided as compute:batches:approve.

  • Kind: mutation
  • Authorization: compute:batches:approve @ compute-tenant
  • Module: quorum
  • Phase: v1.0 (registered)

Input

FieldTypeRequiredConstraints
tenantIdstringyes
batchIdstringyes

Was this page helpful?

Better Compute is created by Sean Filimon

Last updated

On this page