Restart Consumers API
Request rollouts for workloads consuming a Secret
POST /api/namespaces/:namespace/secrets/:name/restart-consumers
No request body. After current live-Secret authorization, discovers Deployments, StatefulSets, and DaemonSets in the same namespace with exact Secret references:
env[].valueFrom.secretKeyRef.nameandenvFrom[].secretRef.nameon normal, init, and ephemeral containers, where present in the workload template;volumes[].secret.secretNameandvolumes[].projected.sources[].secret.name;imagePullSecrets[].name.
It patches spec.template.metadata.annotations["krypton.io/restarted-at"] with
a timestamp, using an RFC 6902 JSON Patch and at most four in-flight patches
per request across all kinds. Each patch first tests the inspected workload
UID and resourceVersion, so a same-name replacement or any intervening
edit (including reference removal) fails before any mutation instead of
restarting the wrong revision. Only acknowledged patches appear in requested.
The API does not wait for rollout completion, check readiness, or verify
credential uptake. Scanning limits and operational behavior
also apply.
Result contract
| HTTP | status | Meaning |
|---|---|---|
| 200 | requested | At least one acknowledged patch, no patch failures, all three inventories complete. |
| 200 | no_targets | All three inventories complete with zero matching workloads; no patch attempted. |
| 207 | partial | At least one acknowledged patch, plus patch and/or discovery failures. |
| 503 | failed | Zero acknowledged patches, with patch and/or discovery failures. |
An empty successful inventory for one kind does not compensate for a failed
inventory for another. In particular, failed discovery with zero known matches is
failed, not no_targets. Discovery settles before mutation. No workloads of
a failed/incomplete kind are patched; known matches from other kinds can proceed.
Each kind uses complete 100-object pages with at most 100 pages, 2,000 raw objects,
and 32 MiB of SDK-decoded JSON per inventory. All pages carry full per-user request
options. Budget or continuation failures do not permit patches from earlier pages
of that kind. See collection budgets.
All result and error statuses explicitly send Cache-Control: no-store.
Example 207 mixed result:
{
"status": "partial",
"matched": 2,
"requested": [{ "kind": "Deployment", "name": "api-server" }],
"failures": [{
"kind": "StatefulSet",
"name": "worker",
"code": "forbidden",
"message": "Access denied. Check Kubernetes permissions for the effective identity and, when enabled, ServiceAccount impersonation permissions.",
"httpStatus": 403
}],
"discoveryFailures": [],
"message": "Rollout requested for 1 of 2 matched workloads. 1 patch request failed.",
"note": "Only acknowledged pod-template patches are reported as requested. Rollout completion, readiness, and credential uptake are not verified."
}
The TypeScript RestartResult contract lives in app/lib/consumers.ts:
kindisDeployment,StatefulSet, orDaemonSet(case-sensitive).matchedis the number of known matches from successful inventories:requested.length + failures.length. It excludes unknown inventories.requestedcontains{ kind, name }for each acknowledged patch.failurescontains{ kind, name, code, message, httpStatus? }for each unacknowledged patch. A transport failure does not prove that no mutation occurred. A match whose listed identity is missing or malformed appears here withincomplete_listand is never patched by name alone. Conflict (409) and rejected-patch (422) failures mean the workload changed or was replaced after discovery; the patch was attempted once and never blind-retried.discoveryFailurescontains{ kind, code, message, httpStatus? }; no workload name is invented for a failed list. A malformed/inconsistent/over-budget list (including bad or repeated continuation tokens) usesincomplete_listand is not silently truncated. Valid continuation tokens are followed to completion.codeisunauthenticated,forbidden,not_found,conflict,invalid_request,rate_limited,unavailable,unconfirmed, orincomplete_list.httpStatusis a numeric upstream status when available, or 503 for a locally detected incomplete inventory. Messages are fixed, sanitized guidance, never raw error payloads.messageis a human-readable summary;noteexplains the acknowledgement limit. Automation should usestatusand the arrays, not parse either string.- A 503 attempt retains all these fields and also has
errorequal tomessage. Preflight errors have the ordinary{ error }envelope instead.
Review actual workload state and repair errors before retrying. After a conflict
or rejected patch, reload the workload (check for replacement, edits, or removed
references) and retry only if a rollout is still wanted. A retry scans all
kinds again and may request another rollout for workloads already acknowledged.
There is no transaction, background retry, or readiness watcher. Native
workload UIDs and resourceVersions stay internal to the patch; results and
audits carry only kind/name plus classified failures.
Access and audit
- Returns
403 { "error": "Restarting apps is disabled on this deployment" }unlessKRYPTON_RESTART_ENABLED=true(which also needs theappsRBAC rule). - Same authentication, namespace, live visibility, and current ACL gates as updating the Secret. Direct history names are hidden. Gate/preparation failures occur before workload mutation and return the ordinary error envelope. Unexpected preparation errors use the shared sanitized 500 response.
- In impersonation mode, every list and patch carries the full user/group identity. A workload 403 can be human RBAC or impersonation permission denial; in hybrid mode it can be ServiceAccount RBAC. List/patch failures are classified in the result, not treated as application-session expiry.
secret.restartaudits includestatus, knownmatchedcount, acknowledged workload identities, and sanitized patch/discovery failures.partialandfaileduse auditresult: error;requestedand explicitno_targetsuseallow. Secret values, template contents, and raw upstream errors are excluded.
Upgrade: replace consumption of the old deployments/statefulSets/
daemonSets arrays with this result. Preserve 207/503 bodies and check status;
a resolved HTTP request is not a completed rollout. The bundled client retains
typed failed-attempt reports for the detail UI, while preflight errors still raise
ApiError. See Consumer Restarts for the walkthrough.