Kyma (Kubernetes) General
SAP BTP, Kyma runtime is a managed Kubernetes cluster (traditionally Gardener-provisioned) with SAP’s Kyma modules layered on top as CRDs/controllers running in the kyma-system namespace: the API Gateway module (Istio ingress + APIRule CRD), the Istio module, the Serverless module (Functions), the SAP BTP Operator module (btp-manager, bridging ServiceInstance/ServiceBinding CRs to the SAP Service Manager API), the Application Connector Manager (Connectivity Proxy + Application Gateway, tunnelling to on-prem SAP systems via SAP Cloud Connector), the Eventing module (NATS JetStream), and the Kyma Dashboard (Busola).
Unlike a classic on-prem SAP landscape, a pentester normally has no direct network path to the Kubernetes objects underneath a Kyma runtime - reaching them requires a foothold: a self-serviced kubeconfig, a running Function/workload, a leaked ServiceAccount token, or an exposed API/dashboard. This section assumes that foothold exists and catalogs what is customer-operated and reproducible on an engagement. It deliberately excludes generic Kubernetes/Istio technique write-ups.
A Kubernetes RBAC misconfiguration or an over-broad APIRule in Kyma is not contained to “just a cluster” the way it might appear from the BTP Cockpit’s abstraction layer. Because kyma-system co-hosts both the Application Connector’s on-prem credentials and the SAP BTP Operator’s Service Manager credentials, a single get secrets -n kyma-system RBAC grant gates access to an on-premise SAP ERP/S4 pivot and subaccount-wide SAP BTP platform API control simultaneously. BTP-cockpit role assignments do not constrain Kyma kubeconfig access - the two authorization layers are independent and must each be reviewed.
Confirm what the current identity/ServiceAccount can reach before targeting any specific module:
kubectl auth can-i --list
kubectl get apirule -A -o yaml
kubectl get secrets -n kyma-system
Start privilege review by asking “who can get secrets -n kyma-system?” - that single question gates both the on-prem pivot (Application Connector) and BTP-wide API control (BTP Operator).
The account that creates a Kyma cluster receives cluster-admin by default and can assign roles to others. Kyma ships predefined ClusterRoles (common-resource-viewer, a namespace-scoped admin role) on top of standard Kubernetes RBAC, which is “completely decoupled and independent” from BTP-cockpit role collections - a user’s BTP-side scoping does not constrain what they can do once they hold a Kyma kubeconfig. Any subaccount member can typically self-service a kubeconfig from the BTP Cockpit subaccount Overview page (KubeconfigURL link); Kyma authenticates via OIDC, usually requiring the kubectl oidc-login plugin, so a bare downloaded kubeconfig is not immediately usable without an interactive OIDC login.
kubectl get clusterrolebindings -o json | jq '.items[] | select(.roleRef.name=="cluster-admin")'
Kyma has no single aggregation point analogous to Cloud Foundry’s VCAP_SERVICES - service-binding Secrets follow the servicebinding.io convention and can be mounted as env vars or files with no single well-known variable name to grep for (e.g. AI Core defaults to /etc/secrets/sapcp/aicore/<instance-name>). Dump every Secret reachable by a compromised ServiceAccount and search the filesystem inside any compromised pod:
kubectl get secrets -A --field-selector type=servicebinding.io/... -o yaml
find / -path '*/secrets/sapcp/*' 2>/dev/null
Functions are cheap to create and frequently over-permissioned by developers reusing the default namespace ServiceAccount. Anyone who can edit/create a Function CR can add arbitrary secretMounts/secretKeyRef env vars pointing at any Secret readable by the Function’s ServiceAccount in that namespace, then read them back over the Function’s own HTTP trigger - a live, in-cluster secret dumper needing no extra tooling. Specifically enumerate secretMounts and env vars of every Function in scope:
kubectl get functions -A -o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}: {.spec.secretMounts}{"\n"}{end}'
A Function pod with RCE is a normal mesh-workload foothold - see Generic pointers for the post-exploitation playbook (Peirates, kubectl auth can-i, IMDS).
Busola is a pure client-side app hitting the Kubernetes API with the viewer’s own credentials - it has no independent authorization model, so any exposure risk is really “is the underlying Kubernetes API/OIDC login exposed or weak.” Per Busola’s own docs, communication with the backend Pod is plain HTTP even under Istio - mTLS terminates at the sidecar, not the app - so a second container landed in the same pod (e.g. via a compromised sidecar/init-container supply chain) can read Busola traffic in the clear.
Not written up in depth here because they are not materially different inside Kyma than in any other managed Kubernetes/Istio environment:
- RBAC/identity post-exploitation -
kubectl auth can-i --list, wildcard-verb Roles,escalate/bind/impersonateprivilege-escalation verbs; automated tooling: Peirates. - Full enumeration/exploitation methodology - HackTricks Cloud: Kubernetes Pentesting; network/vuln scanning - kube-hunter.
- Node/kubelet/container escape - exposed kubelet API on :10250 with
--anonymous-auth=true;hostPath/hostPID/hostNetwork/CAP_SYS_ADMIN; cloud metadata (IMDS) reachability from a pod - see Hacking The Cloud: EC2 metadata SSRF. - Istio mesh (upstream, applies unchanged inside Kyma) - sidecar bypass / PERMISSIVE mTLS; CVE-2021-31920 path-normalization AuthorizationPolicy bypass; Envoy admin interface on loopback :15000; current bulletins ISTIO-SECURITY-2024-001/004 and ISTIO-SECURITY-2026-001 (CVE-2026-26308 RBAC header-matcher bypass, CVE-2026-31837 JWKS resolver auth bypass, CVE-2026-31838 unauthenticated debug endpoints - postdates most public Kyma writeups, worth testing).
- Networking - namespaces are not a network boundary without NetworkPolicies; Gardener-backed clusters can use Calico for default-deny, but presence is customer-specific.
- Treat
get/listonsecretsinkyma-systemas the single highest-value RBAC grant in the cluster - restrict it to a minimal admin set; audit who holds it before every engagement. - Never rely on the cluster-creator’s default
cluster-admingrant persisting as the intended model - review actualClusterRoleBindings, not assumed defaults. - Restrict who can create/edit
FunctionCRs and auditsecretMounts/env vars on every Function; do not let Functions default to the namespace’s shared ServiceAccount. - Per-surface mitigations: see APIRule Misconfiguration, Application Connector Pivot, BTP Operator escape.
- Do not treat a trial Kyma cluster as a safe pentest range - SAP BTP trial accounts explicitly prohibit production/commercial use.
- Kubernetes audit logs for
get/listonsecretsinkyma-system, especially from ServiceAccounts outside the platform-operator set. ClusterRoleBinding/RoleBindingchanges grantingcluster-adminor namespaceadminroles - alert on new grants outside change-managed onboarding.- NATS dispatcher logs at INFO level - a tracked Kyma issue confirms event headers (potentially containing business data/tokens) were logged there; grep for sensitive header content if log-aggregation access is available.
- Function
secretMounts/env-var changes referencing Secrets outside the Function’s own service binding. - Per-surface detection lives on each surface page.
- SAP Discovery Center - Kyma runtime
- Role-Based Access Control (RBAC) in Kyma | SAP Help Portal
- SAP Tutorials: Enable SAP BTP, Kyma Runtime
- busola (Kyma Dashboard) GitHub
- The new way to consume Service Bindings on Kyma Runtime (SAP blog)
- kyma-project/kyma issue #4983 - NATS dispatcher logging headers
- Peirates GitHub
- HackTricks Cloud: Kubernetes Pentesting
- Aqua Security kube-hunter KB
- Istio Security Bulletin 2026-001
- SAP Help Portal: Trial Accounts and Free Tier
- Surface pages: APIRule Misconfiguration · Application Connector Pivot · BTP Operator → Service Manager Escape
