Kyma APIRule Misconfiguration
APIRule is the Kyma API Gateway CRD that exposes a workload through Istio ingress. It compiles down to real Istio VirtualService/AuthorizationPolicy objects, so a misconfigured rule is a live authorization bypass, not just YAML — this is the richest and most frequently-wrong Kyma attack surface. This page assumes a foothold with at least get/list on apirule resources (and ideally the ability to reach the exposed endpoints); see the Kyma overview for establishing that foothold.
An APIRule intended to expose one public path can, through a wildcard, a missing access strategy, or rule-ordering confusion, expose admin/debug/actuator paths of the backing workload with no authentication. Because the rule authors an Istio AuthorizationPolicy directly, a principal who can create/patch APIRule objects can also influence mesh-wide authorization for other workloads without holding RBAC on authorizationpolicies at all.
Enumerate every rule and its access strategy first:
kubectl get apirule -A -o yaml
The access strategy for a rule is exactly one of noAuth, jwt, or extAuth. Flag any rule with noAuth: true on path: /* as the Kyma equivalent of an open S3 bucket:
kubectl get apirule -A -o yaml | grep -B10 "noAuth: true"
Rule paths support exact match, {*} (single segment), and {} (multi-segment); a rule intended to expose /api/public/* under jwt but written as / can unintentionally cover admin/debug/actuator sub-paths. Diff declared paths against the backend’s actual route table.
“Earlier entries override later ones.” A broad noAuth rule for a decoy/health path declared before a narrower jwt-protected rule for the same prefix can win depending on path matching — always confirm live behavior with curl, never trust the YAML alone.
Every APIRule you create directly authors an Istio AuthorizationPolicy of type ALLOW scoped to that rule (documented as a self-inflicted DoS side-effect when it unintentionally blocks legitimate in-mesh pod-to-pod traffic). This demonstrates that a principal who can create/patch APIRule objects — even without direct RBAC on authorizationpolicies.security.istio.io — can indirectly manipulate mesh-wide authorization for any workload sharing a selector.
SAP states v2alpha1 “is not intended for use in a productive environment but only for testing the API and migration process”; finding it live in a production-labeled namespace is itself a finding.
Oathkeeper reacts to APIRule and generates access-rule resources. Ory’s own security advisory (v26.2.0) notes Oathkeeper now normalizes request paths before rule matching “to prevent path traversal attacks,” implying pre-fix versions were bypassable. Identify the target’s Oathkeeper/API Gateway version and test classic bypass payloads against every jwt-protected APIRule endpoint:
curl https://<host>/foo/../admin
curl https://<host>/foo%2F..%2Fadmin
curl https://<host>//admin
curl "https://<host>/foo/..;/admin"
APIRule v2’s OAuth2 Proxy external-authorizer delegation (Authorization Code and Client Credentials tutorials both documented by SAP) inherits the same bug class as any reverse-proxy-based auth: misconfigured redirect URIs, over-permissive header forwarding, stale/self-signed proxy — presented in Kyma-specific YAML reviewers may not recognize as “just another auth proxy.”
- Audit every
APIRulefornoAuth: true, overly broad path wildcards (/), and rule ordering; test live behavior withcurl, not just the YAML. - Avoid
v2alpha1in production namespaces. - Patch/track the Oathkeeper version in use and confirm path-normalization fixes (≥ v26.2.0) are actually deployed.
- Restrict who can create/patch
APIRuleobjects, given the indirectAuthorizationPolicy-authoring side-effect. - Treat
extAuthdelegations as reverse-proxy auth: pin redirect URIs, minimize forwarded headers, verify proxy TLS.
APIRulecreate/update events, specifically any introducingnoAuth: trueor a/-class path.- New/changed Istio
AuthorizationPolicyobjects not traceable to an intentionalAPIRulechange. - Ingress access logs showing requests to admin/debug/actuator paths that succeed without a JWT.
