Safety & trust¶
This document explains what kube-saver will never do, how it protects your workloads, and what you need to know before running it in a production environment.
Design principles¶
- Read-only by default, kube-saver never changes anything in your cluster unless you explicitly run the apply script from a PR plan. Even then, you review the script first.
- No required hosted backend, scans contact your Kubernetes API. Kubeconfig credential plugins may also contact identity providers. Reports are written locally and can contain internal cluster names.
- Degrades safely, if a runtime source is unavailable, kube-saver falls back to the next source instead of crashing.
- Review required, current-sample heuristics produce candidates, not guarantees of workload safety (see below).
What kube-saver will never do¶
- Auto-apply resource changes to your cluster
- Modify any Kubernetes object without your explicit action
- Require sending scan data to a hosted kube-saver service
- Require a cloud billing account or hosted kube-saver backend (cluster credentials are still required)
- Require metrics-server for request-based reports
- Generate a right-sizing recommendation from request-only estimates
Recommendation safety¶
The right-sizing engine applies these guardrails to the current metrics sample:
| Guardrail | What it prevents |
|---|---|
| Measured usage required | A missing sample for a collected sibling suppresses the workload plan |
| Current-sample headroom | CPU suggestions use 1.5× observed usage; memory uses 1.2× |
| Configured resource floors | CLI defaults: at least 100m CPU, 128Mi memory, and half of each current request |
| Single-container workloads | Pods with sidecars are skipped because pod metrics cannot be split safely |
| Protected namespaces and exclusions | Configured namespaces, labels, and annotations suppress recommendations |
The tool uses a current snapshot, not historical peak usage. Review recommendations against workload bursts and service objectives before applying the generated script.
Confidence labels come from utilization ratios, not statistical intervals; plans include low, medium, and high confidence candidates. Workload consolidation takes the largest suggestion across all collected sibling samples, including busy replicas that would not generate their own candidate. A missing sample, multi-container sibling, or excluded sibling suppresses the workload plan. Values round upward to whole millicores and MiB to preserve sample headroom. Malformed, incomplete, negative, non-finite, missing-timestamp, stale, or future-dated samples are treated as unavailable. Measured container names must match collected pod containers. If sibling requests differ for a resource, that resource's recommendation is suppressed because the active controller template cannot be inferred safely during a rollout. Confidence and rationale use the least wasteful collected sibling, including non-candidates.
CPU × 1.5 and memory × 1.2 are fixed sample multipliers. Configured absolute
minimums apply in every mode. In normal mode, prod_cpu_floor_ratio and
prod_memory_floor_ratio apply to every eligible workload; no production
namespace is inferred. aggressive_mode skips those relative floors only.
The engine does not automatically protect StatefulSets or workloads with PVCs.
Configure exclusions for sensitive workloads. Even a complete scan is a current
snapshot, not proof that future replicas or future peaks are covered.
pr-plan creates local files, not a GitHub PR. Executing the patch script contacts
the Kubernetes API and can trigger a workload rollout. The script requires
KUBE_SAVER_APPLY_CONTEXT to name an explicitly reviewed kubectl context,
passes it to every patch, and stops on the first failed command. Verify this
context identifies the cluster you scanned. For GitOps, translate
reviewed changes into your managed manifests.
If you want to suppress recommendations for specific workloads, use the exclusion config:
exclude_labels:
app.kubernetes.io/part-of: database
exclude_annotations:
kube-saver.io/ignore: "true"
RBAC, minimum required permissions¶
kube-saver needs only list and get on a small set of resources. Here is the minimal RBAC manifest:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kube-saver-reader
rules:
- apiGroups: [""]
resources: ["pods", "nodes", "namespaces"]
verbs: ["list", "get"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets", "statefulsets", "daemonsets"]
verbs: ["list", "get"]
- apiGroups: ["metrics.k8s.io"]
resources: ["pods", "nodes"]
verbs: ["list", "get"]
To use it:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kube-saver-reader-binding
subjects:
- kind: ServiceAccount
name: kube-saver
namespace: kube-saver
roleRef:
kind: ClusterRole
name: kube-saver-reader
apiGroup: rbac.authorization.k8s.io
For namespace-scoped access, use a Role / RoleBinding in each target namespace and set namespace_filter to those names. See RBAC permissions.
Note: The
metrics.k8s.iogroup is only needed if metrics-server is running. kube-saver works without it, it just falls back to estimates.
HTTP API¶
The built-in HTTP server (kube-saver serve) is:
- Loopback-only by default (
127.0.0.1) - Read-only, no mutation endpoints
- No authentication, because it is not designed to be exposed
If you need to expose it in a shared environment, put it behind a reverse proxy with auth and TLS. Do not bind it to 0.0.0.0 directly.
Data sources and accuracy¶
kube-saver displays which runtime source it is using in every view. The accuracy tradeoff is:
| Source | Accuracy | When you get it |
|---|---|---|
| metrics-server | Good, cluster-aggregated CPU/memory | metrics-server running |
| Estimates | Request-based, not measured usage | metrics-server unavailable |
Falling back to estimates is not a bug. The TUI shows which source is active, and estimated samples never produce right-sizing recommendations. eBPF live collection is not implemented in this release.
Secrets and sensitive data¶
kube-saver does not intentionally collect or export:
- Kubeconfig contents
- Tokens or credentials
- Pod environment variables
- Secret objects or their data
The doctor command reports the kubeconfig path, selected context, and server
version. API and credential-plugin error text can appear in diagnostics; inspect
and redact logs before sharing them. Reports and plans contain namespace, pod, and workload names; review them before sharing or committing them.