Install
$ agentstack add skill-efeumutaslan-sap-skills-sap-kyma-runtime ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
SAP BTP Kyma Runtime
Related Skills
sap-s4hana-extensibility— S/4HANA events and APIs consumed by Kyma extensionssap-devops-cicd— CI/CD pipelines for Kyma deploymentssap-security-authorization— XSUAA/IAS integration for Kyma workloadssap-cap-advanced— Deploying CAP applications on Kymasap-event-mesh— Event-driven Kyma Functions consuming SAP events
Quick Start
Choose your extension pattern:
| Scenario | Approach | Key Artifact | |----------|----------|-------------| | Lightweight webhook / event handler | Kyma Function (serverless) | Function CR | | Full microservice | Kubernetes Deployment | Deployment + Service + APIRule | | Scheduled job | Kubernetes CronJob | CronJob CR | | Event-driven extension | Function + Event subscription | Subscription CR | | Helm-based app | Helm chart | Chart.yaml + templates |
Minimal Kyma Function:
apiVersion: serverless.kyma-project.io/v1alpha2
kind: Function
metadata:
name: order-handler
namespace: default
spec:
runtime: nodejs20
source:
inline:
source: |
module.exports = {
main: async function (event, context) {
const order = event.data;
console.log('Order received:', order.OrderID);
return { statusCode: 200, body: { status: 'processed' } };
}
};
dependencies: |
{ "name": "order-handler", "version": "1.0.0", "dependencies": {} }
Core Concepts
Kyma Architecture on BTP
- Kyma modules: Modular capabilities (Serverless, Istio, API Gateway, Eventing) enabled per cluster
- BTP Service Operator: Provisions BTP services (XSUAA, HANA, Destination) as Kubernetes secrets
- Istio service mesh: Mutual TLS, traffic management, observability built-in
- Kyma Dashboard: Web UI for managing resources (alternative to kubectl)
Key Custom Resources
| CR | Purpose | Module | |----|---------|--------| | Function | Serverless function | Serverless | | APIRule | Expose service externally (Istio Gateway) | API Gateway | | Subscription | Subscribe to SAP/custom events | Eventing | | ServiceInstance | Provision BTP service | BTP Operator | | ServiceBinding | Bind BTP service to workload | BTP Operator |
Namespace Strategy
default— Quick prototyping onlyproduction/staging— Separate by environment- One namespace per bounded context for microservice architectures
- Label namespaces with
istio-injection=enabledfor mesh
Common Patterns
Pattern 1: Microservice with BTP Service Binding
# service-instance.yaml — provision XSUAA
apiVersion: services.cloud.sap.com/v1
kind: ServiceInstance
metadata:
name: xsuaa-instance
spec:
serviceOfferingName: xsuaa
servicePlanName: application
parameters:
xsappname: order-service
tenant-mode: dedicated
scopes:
- name: $XSAPPNAME.OrderRead
description: Read orders
role-templates:
- name: OrderViewer
scope-references:
- $XSAPPNAME.OrderRead
---
# service-binding.yaml
apiVersion: services.cloud.sap.com/v1
kind: ServiceBinding
metadata:
name: xsuaa-binding
spec:
serviceInstanceName: xsuaa-instance
secretName: xsuaa-credentials
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
spec:
replicas: 2
selector:
matchLabels:
app: order-service
template:
metadata:
labels:
app: order-service
spec:
containers:
- name: order-service
image: myregistry.io/order-service:1.0.0
ports:
- containerPort: 8080
envFrom:
- secretRef:
name: xsuaa-credentials
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: order-service
spec:
selector:
app: order-service
ports:
- port: 80
targetPort: 8080
Pattern 2: API Rule (External Exposure)
apiVersion: gateway.kyma-project.io/v1beta1
kind: APIRule
metadata:
name: order-api
spec:
host: order-api
service:
name: order-service
port: 80
gateway: kyma-system/kyma-gateway
rules:
- path: /orders.*
methods: ["GET", "POST"]
accessStrategies:
- handler: jwt
config:
jwks_urls:
- https://.authentication..hana.ondemand.com/token_keys
trusted_issuers:
- https://.authentication..hana.ondemand.com
- path: /health
methods: ["GET"]
accessStrategies:
- handler: noop
Pattern 3: Event-Driven Extension (S/4HANA Events)
apiVersion: eventing.kyma-project.io/v1alpha2
kind: Subscription
metadata:
name: order-created-sub
spec:
sink: http://order-handler.default.svc.cluster.local
source: sap.s4.beh/ER9
types:
- sap.s4.beh.businesspartner.v1.BusinessPartner.Created.v1
typeMatching: standard
Pattern 4: Destination Service Access
apiVersion: services.cloud.sap.com/v1
kind: ServiceInstance
metadata:
name: dest-instance
spec:
serviceOfferingName: destination
servicePlanName: lite
---
apiVersion: services.cloud.sap.com/v1
kind: ServiceBinding
metadata:
name: dest-binding
spec:
serviceInstanceName: dest-instance
secretName: dest-credentials
// Node.js — call S/4HANA via Destination Service
const { getDestination, executeHttpRequest } = require('@sap-cloud-sdk/connectivity');
async function getBusinessPartners() {
const dest = await getDestination({ destinationName: 'S4HANA_SYSTEM' });
const response = await executeHttpRequest(dest, {
method: 'GET',
url: '/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner?$top=10'
});
return response.data;
}
Pattern 5: Helm Chart Deployment
my-extension/
├── Chart.yaml
├── values.yaml
└── templates/
├── deployment.yaml
├── service.yaml
├── apirule.yaml
└── service-binding.yaml
# Deploy with Helm
helm upgrade --install my-extension ./my-extension \
--namespace production \
--set image.tag=1.2.0 \
--set replicas=3
Error Catalog
| Error | Message | Root Cause | Fix | |-------|---------|------------|-----| | Function CrashLoopBackOff | Runtime error in function code | Syntax error or missing dependency | Check logs: kubectl logs -n default -l serverless.kyma-project.io/function-name= | | APIRule ERROR | VirtualService creation failed | Duplicate host or invalid gateway | Ensure unique host; verify gateway exists: kubectl get gateways -n kyma-system | | ServiceBinding failed | Could not find service instance | Instance not ready or wrong name | Check kubectl get serviceinstances; wait for Ready status | | Subscription NATS error | No events received | Wrong event type string or source | Match exact type from SAP Event Catalog; check eventing module is enabled | | ImagePullBackOff | unauthorized: authentication required | Registry credentials missing | Create imagePullSecret and reference in Deployment spec | | OOMKilled | Container killed by OOM | Memory limit too low | Increase resources.limits.memory; profile actual usage first |
Performance Tips
- Right-size resources — Start with
100mCPU /128Mimemory, scale based on metrics - HPA for autoscaling — Use
HorizontalPodAutoscaleron CPU/memory or custom metrics - Function cold starts — Set
minReplicas: 1for latency-sensitive Functions - Connection pooling — Reuse HTTP clients and DB connections across invocations
- Istio sidecar — Adds ~20ms latency per hop; disable for internal batch jobs if acceptable
- Image size — Use distroless/alpine base images; smaller image = faster pull = faster scaling
- Pod disruption budgets — Set
PodDisruptionBudgetfor critical services during node upgrades
Gotchas
- Kyma module enablement: Serverless, Eventing, API Gateway are separate modules — enable them in BTP Cockpit or via
KymaCR before use - Function source size limit: Inline source max ~1MB; use Git source for larger codebases
- Secret rotation: BTP Service Operator does NOT auto-rotate secrets; delete and recreate ServiceBinding to refresh
- Network policies: By default, all pods can communicate; add
NetworkPolicyfor production isolation - Kyma trial limitations: 14-day expiry, limited resources, no custom domains
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: efeumutaslan
- Source: efeumutaslan/SAP-SKILLS
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.