Skip to main content

CertOps

Certificate lifecycle orchestration (workspace-scoped). Control plane never stores private key material.

📄️Bulk-create CertOps renewal jobs

Queues a renew job for up to 100 managed certificates in one request. Each certificate goes through the same manual job-creation path as POST /jobs (manager role, workspace kill switch, approval gate, payload validation), and jobs are always recorded with source 'api'. The response is a partial-failure envelope: per-certificate successes and failures are reported item by item and never abort the batch, so the request returns 200 even when some or all items fail. Only whole-request shape problems (malformed body, more than 100 ids, non-UUID or duplicate ids) fail with 400. Private key or secret material in the request body is rejected.

📄️Approve a pending CertOps job

Grants the human approval a gated job needs before an agent can claim it. Session-only manager surface (internal worker credentials are rejected) with a non-requester rule: the user who requested the job cannot approve it. The approval is bound to a canonical SHA256 hash of the job payload at decision time; if the payload changes afterwards the claim path voids the approval and returns the job to pending_approval. Available while the workspace kill switch is paused.

📄️Retire a CertOps agent

Retires an agent so its credential stops authenticating (agent protocol routes return 410). Retiring an already-retired agent is idempotent. If the agent holds actively leased jobs the request is blocked with 409 unless force is true, in which case an attributable reason is required. A forced retire fences the agent's in-flight work immediately rather than leaving it to the lease reaper: jobs still at 'claimed' are cancelled with error_code CERTOPS_AGENT_FORCE_RETIRED, while jobs that had reached 'running' become orphaned_unknown_effect and are flagged needs_operator_reconciliation, because their real-world effect is unknown. Both id lists are returned in the response and recorded on the CERTOPS_AGENT_RETIRED audit event.

📄️Approve a CertOps trust anchor

Approves a CA certificate as a trust anchor that distribute-trust jobs may install into an agent's trust store (ADR-0012 decision 6). `pem` must contain exactly one CA certificate (Basic Constraints CA=true); bundles and leaf certificates are rejected. Re-submitting the same fingerprint updates the existing row in place and reactivates it if it was previously retired, rather than creating a duplicate record. Recorded as a CERTOPS_TRUST_ANCHOR_APPROVED audit event.

📄️List installations for a CertOps trust anchor

Returns every certops_trust_anchor_installations row for one trust anchor (agent, store, transition state, provenance, last error), so an operator can see where the anchor actually landed before revoking or distributing it further. Manager-only, same as the other trust-anchor routes. Read-only: unlike the mutating trust-anchor routes, this route does not require the workspace's CertOps state to be active, since an operator diagnosing a paused workspace still needs to see current installations.

📄️Bootstrap a CertOps diagnostic agent

Session-authenticated (requires certops.agents.diagnose, admin-only). Atomically consumes a single-use requestId, creates an agent with agent_kind 'diagnostic', and creates its protocol_smoke job, all in one transaction. The response's credential is returned exactly once and is not recoverable afterward. Retrying with the same requestId never replays the original agentId/credential/job; it fails with diagnostic_bootstrap_already_consumed. Requests are rate limited per workspace. Diagnostic agents that stay inactive for 24 hours are retired automatically; retirement revokes the credential in the same transaction that marks the agent retired, so a retired diagnostic agent's credential fails authentication immediately, not just authorization.