Security
RBAC Model
Kymaros follows the principle of least privilege. The controller is granted only the permissions required to manage sandbox namespaces and interact with Velero. No cluster-admin privileges are used.
Controller ClusterRole
The complete set of permissions granted to the Kymaros controller service account:
| API Group | Resources | Verbs |
|---|---|---|
| (core) | namespaces | create, delete, get, list, watch |
| (core) | pods | get, list, watch |
| (core) | pods/exec | create |
| (core) | configmaps | get, list, watch |
| (core) | secrets | get, list, watch |
| (core) | services | get, list, watch |
| (core) | persistentvolumeclaims | get, list, watch |
| (core) | limitranges | create, delete |
| (core) | resourcequotas | create, delete |
| apps | deployments | get, list, update, watch |
| apps | statefulsets | get, list, update, watch |
| networking.k8s.io | networkpolicies | create, delete |
| restore.kymaros.io | * | create, delete, get, list, patch, update, watch (+ status subresource + finalizers) |
| velero.io | backups | get, list, watch |
| velero.io | schedules | get, list, watch |
| velero.io | restores | create, delete, get, list, watch |
Notable constraints:
- The controller can read Secrets (required to inspect backup credentials and cross-namespace config) but cannot create Secrets in any namespace — Secret creation during a restore is performed by Velero, not by the Kymaros controller.
- Velero
backupsandschedulesare read-only — the controller never modifies the backup lifecycle. pods/execis required for exec-type health checks defined inHealthCheckPolicy. If you do not use exec health checks, this permission is still present in theClusterRolebut is not exercised.
Audit Recommendation
Review the ClusterRole and ClusterRoleBinding after every Kymaros upgrade to confirm they match the expected permission set. If your organization enforces OPA/Kyverno policies on ClusterRole creation, pre-approve the Kymaros role manifest before installation.
Sandbox Security Controls
Each sandbox namespace created by Kymaros receives a mandatory set of security controls. These controls are applied by the controller at namespace creation time and cannot be removed by workloads running inside the sandbox.
NetworkPolicy (Default Deny All)
When sandbox.networkIsolation: strict is configured, the controller applies a NetworkPolicy that denies all ingress and egress traffic to and from the sandbox namespace. This prevents:
- Sandbox workloads from connecting to production databases or services
- Sandbox workloads from making outbound network calls (data exfiltration, C2 callbacks in compromised images)
- Production workloads from inadvertently connecting to sandbox services
The network isolation is enforced at the CNI level. It is effective against any workload that respects Kubernetes NetworkPolicy semantics.
ResourceQuota
The controller creates a ResourceQuota in each sandbox namespace to bound resource consumption. This prevents a runaway restore or a resource-intensive test from consuming cluster capacity at the expense of production workloads.
LimitRange
A LimitRange is applied to set default CPU and memory limits on pods that do not declare their own. This ensures that all sandbox pods are resource-bounded, even if the original workload specification omits resource limits.
Sandbox Labels
Every resource created by Kymaros in or for a sandbox carries a standard set of labels:
| Label | Purpose |
|---|---|
kymaros.io/managed-by | Identifies the resource as owned by Kymaros |
kymaros.io/test | Links the resource to a specific RestoreTest |
kymaros.io/test-namespace | The sandbox namespace name |
kymaros.io/group | Groups related sandbox resources for batch operations |
These labels are used by the controller to identify and clean up all sandbox resources, even if the sandbox namespace itself is not deleted (for example, during partial cleanup after a controller crash).
Sandbox Finalizer
The sandbox namespace carries the finalizer kymaros.io/sandbox-cleanup. This prevents the namespace from being deleted by a kubectl delete namespace call until the Kymaros controller has confirmed cleanup of all dependent resources. The finalizer is removed by the controller as the last step of sandbox teardown.
No Data Exfiltration from the Sandbox
Kymaros does not copy, transmit, or store application data from the sandbox. The validation process is purely observational:
- The controller reads pod status and events via the Kubernetes API
- Exec-type health checks run commands inside the sandbox pod and capture the exit code and stdout
- HTTP health checks probe endpoints inside the sandbox and capture the HTTP status code
None of this data is sent outside the cluster. RestoreReport resources written to the Kubernetes API contain only metadata (scores, timestamps, durations, check names, pass/fail status) — not application data.
Controller Hardening
The Kymaros controller pod runs with a restricted security posture:
- Non-root: The controller process runs as a non-root user. No
runAsRoot: trueorprivileged: trueis used. - Read-only root filesystem: The container filesystem is mounted read-only (
readOnlyRootFilesystem: true). No writes to the container filesystem are permitted at runtime. - Drop ALL capabilities: The container drops all Linux capabilities (
securityContext.capabilities.drop: [ALL]). No capabilities are added back. - No privilege escalation:
allowPrivilegeEscalation: falseis set.
These settings are enforced via the pod securityContext in the Helm chart. If your cluster enforces the Kubernetes Pod Security Standard at the restricted level, Kymaros pods are compatible without exception.
API Server RBAC
The Kymaros REST API (kymaros-api) exposes restore history and report data to the dashboard and CLI. Access to the API is controlled by Kubernetes RBAC:
- The API server uses the in-cluster service account to read
RestoreTestandRestoreReportresources. - The dashboard authenticates using the kubeconfig or service account token of the user's browser session (depending on deployment mode).
- No API keys or external credentials are stored by the API server.
For production deployments, expose the dashboard behind an ingress controller with TLS termination and authentication (for example, OAuth2 Proxy or an SSO provider). The Enterprise tier supports SSO directly.
Threat Model
What Kymaros Can Access
- All
RestoreTest,RestoreReport, andHealthCheckPolicyresources cluster-wide (all namespaces) - Velero
Backup,Schedule, andRestoreresources in theveleronamespace - All
SecretsandConfigMapsacross all namespaces (read-only) - Pod exec access in sandbox namespaces (for exec health checks)
- The ability to create and delete namespaces,
NetworkPolicy,ResourceQuota, andLimitRangeobjects
What Kymaros Cannot Access
- Kymaros does not have
cluster-admin. It cannot modifyClusterRole,ClusterRoleBinding,Node, orPersistentVolumeobjects. - Kymaros cannot create
Secretsoutside of sandbox namespaces. - Kymaros cannot modify Velero
BackuporScheduleobjects (read-only). - Kymaros cannot access the Velero backup storage backend directly — it uses Velero's API exclusively.
- Kymaros cannot escalate its own privileges (no
bind,escalate, orimpersonateverbs).
Accepted Risks
- Secret read access: The controller can read
Secretsacross all namespaces. This is required because restore validation may need to inspect credentials that are part of the restored application. Restrict access to thekymaros-systemnamespace if this is a concern in your environment, but note that this limits validation of cross-namespace dependencies. - Namespace creation: The controller can create namespaces with arbitrary names (subject to the configured prefix). Enforce a
NetworkPolicynamespace admission policy if namespace proliferation is a concern.