Skip to main content

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 GroupResourcesVerbs
(core)namespacescreate, delete, get, list, watch
(core)podsget, list, watch
(core)pods/execcreate
(core)configmapsget, list, watch
(core)secretsget, list, watch
(core)servicesget, list, watch
(core)persistentvolumeclaimsget, list, watch
(core)limitrangescreate, delete
(core)resourcequotascreate, delete
appsdeploymentsget, list, update, watch
appsstatefulsetsget, list, update, watch
networking.k8s.ionetworkpoliciescreate, delete
restore.kymaros.io*create, delete, get, list, patch, update, watch (+ status subresource + finalizers)
velero.iobackupsget, list, watch
velero.ioschedulesget, list, watch
velero.iorestorescreate, 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 backups and schedules are read-only — the controller never modifies the backup lifecycle.
  • pods/exec is required for exec-type health checks defined in HealthCheckPolicy. If you do not use exec health checks, this permission is still present in the ClusterRole but 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:

LabelPurpose
kymaros.io/managed-byIdentifies the resource as owned by Kymaros
kymaros.io/testLinks the resource to a specific RestoreTest
kymaros.io/test-namespaceThe sandbox namespace name
kymaros.io/groupGroups 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: true or privileged: true is 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: false is 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 RestoreTest and RestoreReport resources.
  • 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, and HealthCheckPolicy resources cluster-wide (all namespaces)
  • Velero Backup, Schedule, and Restore resources in the velero namespace
  • All Secrets and ConfigMaps across all namespaces (read-only)
  • Pod exec access in sandbox namespaces (for exec health checks)
  • The ability to create and delete namespaces, NetworkPolicy, ResourceQuota, and LimitRange objects

What Kymaros Cannot Access

  • Kymaros does not have cluster-admin. It cannot modify ClusterRole, ClusterRoleBinding, Node, or PersistentVolume objects.
  • Kymaros cannot create Secrets outside of sandbox namespaces.
  • Kymaros cannot modify Velero Backup or Schedule objects (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, or impersonate verbs).

Accepted Risks

  • Secret read access: The controller can read Secrets across all namespaces. This is required because restore validation may need to inspect credentials that are part of the restored application. Restrict access to the kymaros-system namespace 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 NetworkPolicy namespace admission policy if namespace proliferation is a concern.